15
15
*/
16
16
package com .netflix .concurrency .limits .limiter ;
17
17
18
+ import com .netflix .concurrency .limits .Limiter ;
18
19
import com .netflix .concurrency .limits .MetricIds ;
19
20
import com .netflix .concurrency .limits .MetricRegistry ;
20
21
21
22
import java .util .Optional ;
23
+ import java .util .concurrent .Semaphore ;
22
24
23
25
public class SimpleLimiter <ContextT > extends AbstractLimiter <ContextT > {
24
26
public static class Builder extends AbstractLimiter .Builder <Builder > {
@@ -35,22 +37,75 @@ protected Builder self() {
35
37
public static Builder newBuilder () {
36
38
return new Builder ();
37
39
}
38
-
39
40
private final MetricRegistry .SampleListener inflightDistribution ;
41
+ private final AdjustableSemaphore semaphore ;
40
42
41
43
public SimpleLimiter (AbstractLimiter .Builder <?> builder ) {
42
44
super (builder );
43
45
44
46
this .inflightDistribution = builder .registry .distribution (MetricIds .INFLIGHT_NAME );
47
+ this .semaphore = new AdjustableSemaphore (getLimit ());
45
48
}
46
49
47
50
@ Override
48
- public Optional <Listener > acquire (ContextT context ) {
49
- int currentInFlight = getInflight ();
50
- inflightDistribution .addSample (currentInFlight );
51
- if (currentInFlight >= getLimit ()) {
51
+ public Optional <Limiter .Listener > acquire (ContextT context ) {
52
+ if (!semaphore .tryAcquire ()) {
52
53
return createRejectedListener ();
53
54
}
54
- return Optional .of (createListener ());
55
+ Listener listener = new Listener (createListener ());
56
+ inflightDistribution .addSample (getInflight ());
57
+ return Optional .of (listener );
58
+ }
59
+
60
+ @ Override
61
+ protected void onNewLimit (int newLimit ) {
62
+ int oldLimit = this .getLimit ();
63
+ super .onNewLimit (newLimit );
64
+
65
+ if (newLimit > oldLimit ) {
66
+ semaphore .release (newLimit - oldLimit );
67
+ } else {
68
+ semaphore .reducePermits (oldLimit - newLimit );
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Simple Semaphore subclass that allows access to its reducePermits method.
74
+ */
75
+ private static final class AdjustableSemaphore extends Semaphore {
76
+ AdjustableSemaphore (int permits ) {
77
+ super (permits );
78
+ }
79
+
80
+ @ Override
81
+ public void reducePermits (int reduction ) {
82
+ super .reducePermits (reduction );
83
+ }
84
+ }
85
+
86
+ private class Listener implements Limiter .Listener {
87
+ private final Limiter .Listener delegate ;
88
+
89
+ Listener (Limiter .Listener delegate ) {
90
+ this .delegate = delegate ;
91
+ }
92
+
93
+ @ Override
94
+ public void onSuccess () {
95
+ delegate .onSuccess ();
96
+ semaphore .release ();
97
+ }
98
+
99
+ @ Override
100
+ public void onIgnore () {
101
+ delegate .onIgnore ();
102
+ semaphore .release ();
103
+ }
104
+
105
+ @ Override
106
+ public void onDropped () {
107
+ delegate .onDropped ();
108
+ semaphore .release ();
109
+ }
55
110
}
56
111
}
0 commit comments