1+ /**
2+ * Copyright 2016 Netflix, Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
116package io .reactivesocket .lease ;
217
318import io .reactivesocket .Frame ;
1530 * Distribute evenly a static number of tickets to all connected clients.
1631 */
1732public class FairLeaseGovernor implements LeaseGovernor {
18- private static ScheduledExecutorService EXECUTOR = Executors .newScheduledThreadPool (1 );
19-
2033 private final int tickets ;
2134 private final long period ;
2235 private final TimeUnit unit ;
36+ private final ScheduledExecutorService executor ;
37+
2338 private final Map <Responder , Integer > responders ;
2439 private ScheduledFuture <?> runningTask ;
2540
@@ -41,19 +56,29 @@ private synchronized void distribute(int ttlMs) {
4156 }
4257 }
4358
44- public FairLeaseGovernor (int tickets , long period , TimeUnit unit ) {
59+ public FairLeaseGovernor (int tickets , long period , TimeUnit unit , ScheduledExecutorService executor ) {
4560 this .tickets = tickets ;
4661 this .period = period ;
4762 this .unit = unit ;
63+ this .executor = executor ;
4864 responders = new HashMap <>();
4965 }
5066
67+ public FairLeaseGovernor (int tickets , long period , TimeUnit unit ) {
68+ this (tickets , period , unit , Executors .newScheduledThreadPool (2 , runnable -> {
69+ Thread thread = new Thread (runnable );
70+ thread .setDaemon (true );
71+ thread .setName ("FairLeaseGovernor" );
72+ return thread ;
73+ }));
74+ }
75+
5176 @ Override
5277 public synchronized void register (Responder responder ) {
5378 responders .put (responder , 0 );
5479 if (runningTask == null ) {
5580 final int ttl = (int )TimeUnit .NANOSECONDS .convert (period , unit );
56- runningTask = EXECUTOR .scheduleAtFixedRate (() -> distribute (ttl ), 0 , period , unit );
81+ runningTask = executor .scheduleAtFixedRate (() -> distribute (ttl ), 0 , period , unit );
5782 }
5883 }
5984
@@ -68,8 +93,13 @@ public synchronized void unregister(Responder responder) {
6893
6994 @ Override
7095 public synchronized boolean accept (Responder responder , Frame frame ) {
71- boolean valid ;
72- final Integer remainingTickets = responders .get (responder );
73- return remainingTickets == null || remainingTickets > 0 ;
96+ Integer remainingTickets = responders .get (responder );
97+ if (remainingTickets != null ) {
98+ remainingTickets --;
99+ } else {
100+ remainingTickets = -1 ;
101+ }
102+ responders .put (responder , remainingTickets );
103+ return remainingTickets >= 0 ;
74104 }
75105}
0 commit comments