1
1
package dev .openfeature .contrib .providers .flagd .resolver .grpc ;
2
2
3
+ import java .util .Collections ;
4
+ import java .util .List ;
3
5
import java .util .Random ;
4
6
import java .util .concurrent .TimeUnit ;
5
7
import java .util .concurrent .atomic .AtomicBoolean ;
6
- import java .util .function .Consumer ;
7
-
8
+ import java .util .function .BiConsumer ;
8
9
import dev .openfeature .contrib .providers .flagd .FlagdOptions ;
9
10
import dev .openfeature .contrib .providers .flagd .resolver .common .ChannelBuilder ;
10
11
import dev .openfeature .contrib .providers .flagd .resolver .common .Util ;
@@ -37,7 +38,7 @@ public class GrpcConnector {
37
38
private final long deadline ;
38
39
39
40
private final Cache cache ;
40
- private final Consumer <ProviderState > stateConsumer ;
41
+ private final BiConsumer <ProviderState , List < String > > stateConsumer ;
41
42
42
43
private int eventStreamAttempt = 1 ;
43
44
private int eventStreamRetryBackoff ;
@@ -52,7 +53,8 @@ public class GrpcConnector {
52
53
* @param cache cache to use.
53
54
* @param stateConsumer lambda to call for setting the state.
54
55
*/
55
- public GrpcConnector (final FlagdOptions options , final Cache cache , Consumer <ProviderState > stateConsumer ) {
56
+ public GrpcConnector (final FlagdOptions options , final Cache cache ,
57
+ BiConsumer <ProviderState , List <String >> stateConsumer ) {
56
58
this .channel = ChannelBuilder .nettyChannel (options );
57
59
this .serviceStub = ServiceGrpc .newStub (channel );
58
60
this .serviceBlockingStub = ServiceGrpc .newBlockingStub (channel );
@@ -80,7 +82,8 @@ public void initialize() throws Exception {
80
82
/**
81
83
* Shuts down all gRPC resources.
82
84
*
83
- * @throws Exception is something goes wrong while terminating the communication.
85
+ * @throws Exception is something goes wrong while terminating the
86
+ * communication.
84
87
*/
85
88
public void shutdown () throws Exception {
86
89
// first shutdown the event listener
@@ -100,7 +103,7 @@ public void shutdown() throws Exception {
100
103
this .channel .awaitTermination (this .deadline , TimeUnit .MILLISECONDS );
101
104
log .warn (String .format ("Unable to shut down channel by %d deadline" , this .deadline ));
102
105
}
103
- this .stateConsumer .accept (ProviderState .NOT_READY );
106
+ this .stateConsumer .accept (ProviderState .NOT_READY , Collections . emptyList () );
104
107
}
105
108
}
106
109
@@ -114,21 +117,24 @@ public ServiceGrpc.ServiceBlockingStub getResolver() {
114
117
}
115
118
116
119
/**
117
- * Event stream observer logic. This contains blocking mechanisms, hence must be run in a dedicated thread.
120
+ * Event stream observer logic. This contains blocking mechanisms, hence must be
121
+ * run in a dedicated thread.
118
122
*/
119
123
private void observeEventStream () {
120
124
while (this .eventStreamAttempt <= this .maxEventStreamRetries ) {
121
- final StreamObserver <EventStreamResponse > responseObserver =
122
- new EventStreamObserver ( sync , this . cache , this ::grpcStateConsumer );
125
+ final StreamObserver <EventStreamResponse > responseObserver = new EventStreamObserver ( sync , this . cache ,
126
+ this ::grpcStateConsumer );
123
127
this .serviceStub .eventStream (EventStreamRequest .getDefaultInstance (), responseObserver );
124
128
125
129
try {
126
130
synchronized (sync ) {
127
131
sync .wait ();
128
132
}
129
133
} catch (InterruptedException e ) {
130
- // Interruptions are considered end calls for this observer, hence log and return
131
- // Note - this is the most common interruption when shutdown, hence the log level debug
134
+ // Interruptions are considered end calls for this observer, hence log and
135
+ // return
136
+ // Note - this is the most common interruption when shutdown, hence the log
137
+ // level debug
132
138
log .debug ("interruption while waiting for condition" , e );
133
139
Thread .currentThread ().interrupt ();
134
140
}
@@ -140,17 +146,18 @@ private void observeEventStream() {
140
146
try {
141
147
Thread .sleep (this .eventStreamRetryBackoff );
142
148
} catch (InterruptedException e ) {
143
- // Interruptions are considered end calls for this observer, hence log and return
149
+ // Interruptions are considered end calls for this observer, hence log and
150
+ // return
144
151
log .warn ("interrupted while restarting gRPC Event Stream" );
145
152
Thread .currentThread ().interrupt ();
146
153
}
147
154
}
148
155
149
156
log .error ("failed to connect to event stream, exhausted retries" );
150
- this .grpcStateConsumer (ProviderState .ERROR );
157
+ this .grpcStateConsumer (ProviderState .ERROR , null );
151
158
}
152
159
153
- private void grpcStateConsumer (final ProviderState state ) {
160
+ private void grpcStateConsumer (final ProviderState state , final List < String > changedFlags ) {
154
161
// check for readiness
155
162
if (ProviderState .READY .equals (state )) {
156
163
this .eventStreamAttempt = 1 ;
@@ -162,6 +169,6 @@ private void grpcStateConsumer(final ProviderState state) {
162
169
}
163
170
164
171
// chain to initiator
165
- this .stateConsumer .accept (state );
172
+ this .stateConsumer .accept (state , changedFlags );
166
173
}
167
174
}
0 commit comments