Remove checkstyle syntax warnings from dr-node
[dmaap/datarouter.git] / datarouter-node / src / main / java / org / onap / dmaap / datarouter / node / RateLimitedOperation.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * * ===========================================================================
7  * * Licensed under the Apache License, Version 2.0 (the "License");
8  * * you may not use this file except in compliance with the License.
9  * * You may obtain a copy of the License at
10  * *
11  *  *      http://www.apache.org/licenses/LICENSE-2.0
12  * *
13  *  * Unless required by applicable law or agreed to in writing, software
14  * * distributed under the License is distributed on an "AS IS" BASIS,
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * * See the License for the specific language governing permissions and
17  * * limitations under the License.
18  * * ============LICENSE_END====================================================
19  * *
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24
25 package org.onap.dmaap.datarouter.node;
26
27 import java.util.Timer;
28 import java.util.TimerTask;
29
30 /**
31  * Execute an operation no more frequently than a specified interval.
32  */
33
34 public abstract class RateLimitedOperation implements Runnable {
35
36     private boolean marked;    // a timer task exists
37     private boolean executing;    // the operation is currently in progress
38     private boolean remark;    // a request was made while the operation was in progress
39     private Timer timer;
40     private long last;    // when the last operation started
41     private long mininterval;
42
43     /**
44      * Create a rate limited operation.
45      *
46      * @param mininterval The minimum number of milliseconds after the last execution starts before a new execution can
47      *      begin
48      * @param timer The timer used to perform deferred executions
49      */
50     public RateLimitedOperation(long mininterval, Timer timer) {
51         this.timer = timer;
52         this.mininterval = mininterval;
53     }
54
55     /**
56      * Request that the operation be performed by this thread or at a later time by the timer.
57      */
58     public void request() {
59         if (premark()) {
60             return;
61         }
62         do {
63             run();
64         }
65         while (demark());
66     }
67
68     private synchronized boolean premark() {
69         if (executing) {
70             // currently executing - wait until it finishes
71             remark = true;
72             return (true);
73         }
74         if (marked) {
75             // timer currently running - will run when it expires
76             return (true);
77         }
78         long now = System.currentTimeMillis();
79         if (last + mininterval > now) {
80             // too soon - schedule a timer
81             marked = true;
82             timer.schedule(new Deferred(), last + mininterval - now);
83             return (true);
84         }
85         last = now;
86         executing = true;
87         // start execution
88         return (false);
89     }
90
91     private synchronized boolean demark() {
92         executing = false;
93         if (remark) {
94             remark = false;
95             return (!premark());
96         }
97         return (false);
98     }
99
100     private class Deferred extends TimerTask {
101
102         public void run() {
103             execute();
104         }
105
106         private void execute() {
107             unmark();
108             request();
109         }
110
111         private synchronized void unmark() {
112             marked = false;
113         }
114     }
115 }