]> git.basschouten.com Git - openhab-addons.git/blob
f27d790268b1be70ef49e2aea97d0ab02bae73bb
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.oceanic.internal;
14
15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.locks.ReentrantLock;
17
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 /**
22  * The {@link Throttler} is helper class that regulates the frequency at which messages/packets are sent to
23  * the serial port.
24  *
25  * @author Karel Goderis - Initial Contribution
26  */
27 public class Throttler {
28
29     private static Logger logger = LoggerFactory.getLogger(Throttler.class);
30
31     public static final long INTERVAL = 1000;
32
33     private static ConcurrentHashMap<String, ReentrantLock> locks = new ConcurrentHashMap<>();
34     private static ConcurrentHashMap<String, Long> timestamps = new ConcurrentHashMap<>();
35
36     public static void lock(String key) {
37         if (!locks.containsKey(key)) {
38             locks.put(key, new ReentrantLock());
39         }
40
41         locks.get(key).lock();
42
43         if (timestamps.get(key) != null) {
44             long lastStamp = timestamps.get(key);
45             long timeToWait = Math.max(INTERVAL - (System.currentTimeMillis() - lastStamp), 0);
46             if (timeToWait > 0) {
47                 try {
48                     Thread.sleep(timeToWait);
49                 } catch (InterruptedException e) {
50                     logger.error("An exception occurred while putting the thread to sleep : '{}'", e.getMessage());
51                 }
52             }
53         }
54     }
55
56     public static void unlock(String key) {
57         if (locks.containsKey(key)) {
58             timestamps.put(key, System.currentTimeMillis());
59             locks.get(key).unlock();
60         }
61     }
62
63     public static void lock() {
64         for (ReentrantLock aLock : locks.values()) {
65             aLock.lock();
66         }
67
68         long lastStamp = 0;
69
70         for (Long aStamp : timestamps.values()) {
71             if (aStamp > lastStamp) {
72                 lastStamp = aStamp;
73             }
74         }
75
76         long timeToWait = Math.max(INTERVAL - (System.currentTimeMillis() - lastStamp), 0);
77         if (timeToWait > 0) {
78             try {
79                 Thread.sleep(timeToWait);
80             } catch (InterruptedException e) {
81                 logger.error("An exception occurred while putting the thread to sleep : '{}'", e.getMessage());
82             }
83         }
84     }
85
86     public static void unlock() {
87         for (String key : locks.keySet()) {
88             if (locks.get(key).isHeldByCurrentThread()) {
89                 timestamps.put(key, System.currentTimeMillis());
90                 locks.get(key).unlock();
91             }
92         }
93     }
94 }