22
22
* @param <K> the type of the blocking stub for the GRPC service
23
23
*/
24
24
@ Slf4j
25
- public class GrpcConnector <T extends AbstractStub <T >, K extends AbstractBlockingStub <K >> {
26
-
27
- /**
28
- * The asynchronous service stub for making non-blocking GRPC calls.
29
- */
30
- private final T serviceStub ;
25
+ public class ChannelConnector <T extends AbstractStub <T >, K extends AbstractBlockingStub <K >> {
31
26
32
27
/**
33
28
* The blocking service stub for making blocking GRPC calls.
@@ -37,80 +32,51 @@ public class GrpcConnector<T extends AbstractStub<T>, K extends AbstractBlocking
37
32
/**
38
33
* The GRPC managed channel for managing the underlying GRPC connection.
39
34
*/
35
+ @ Getter
40
36
private final ManagedChannel channel ;
41
37
42
38
/**
43
39
* The deadline in milliseconds for GRPC operations.
44
40
*/
45
41
private final long deadline ;
46
42
47
- /**
48
- * The deadline in milliseconds for event streaming operations.
49
- */
50
- private final long streamDeadlineMs ;
51
-
52
43
/**
53
44
* A consumer that handles connection events such as connection loss or reconnection.
54
45
*/
55
46
private final Consumer <FlagdProviderEvent > onConnectionEvent ;
56
47
57
48
/**
58
- * A consumer that handles GRPC service stubs for event stream handling.
59
- */
60
- private final Consumer <T > streamObserver ;
61
-
62
- private final FlagdOptions options ;
63
-
64
- /**
65
- * Indicates whether the connector is currently connected to the GRPC service.
66
- */
67
- @ Getter
68
- private boolean connected = false ;
69
-
70
- /**
71
- * Constructs a new {@code GrpcConnector} instance with the specified options and parameters.
49
+ * Constructs a new {@code ChannelConnector} instance with the specified options and parameters.
72
50
*
73
51
* @param options the configuration options for the GRPC connection
74
- * @param stub a function to create the asynchronous service stub from a {@link ManagedChannel}
75
52
* @param blockingStub a function to create the blocking service stub from a {@link ManagedChannel}
76
53
* @param onConnectionEvent a consumer to handle connection events
77
- * @param eventStreamObserver a consumer to handle the event stream
78
54
* @param channel the managed channel for the GRPC connection
79
55
*/
80
- public GrpcConnector (
56
+ public ChannelConnector (
81
57
final FlagdOptions options ,
82
- final Function <ManagedChannel , T > stub ,
83
58
final Function <ManagedChannel , K > blockingStub ,
84
59
final Consumer <FlagdProviderEvent > onConnectionEvent ,
85
- final Consumer <T > eventStreamObserver ,
86
60
ManagedChannel channel ) {
87
61
88
62
this .channel = channel ;
89
- this .serviceStub = stub .apply (channel ).withWaitForReady ();
90
63
this .blockingStubFunction = blockingStub ;
91
64
this .deadline = options .getDeadline ();
92
- this .streamDeadlineMs = options .getStreamDeadlineMs ();
93
65
this .onConnectionEvent = onConnectionEvent ;
94
- this .streamObserver = eventStreamObserver ;
95
- this .options = options ;
96
66
}
97
67
98
68
/**
99
- * Constructs a {@code GrpcConnector } instance for testing purposes.
69
+ * Constructs a {@code ChannelConnector } instance for testing purposes.
100
70
*
101
71
* @param options the configuration options for the GRPC connection
102
- * @param stub a function to create the asynchronous service stub from a {@link ManagedChannel}
103
72
* @param blockingStub a function to create the blocking service stub from a {@link ManagedChannel}
104
73
* @param onConnectionEvent a consumer to handle connection events
105
- * @param eventStreamObserver a consumer to handle the event stream
106
74
*/
107
- public GrpcConnector (
75
+ public ChannelConnector (
108
76
final FlagdOptions options ,
109
- final Function <ManagedChannel , T > stub ,
110
77
final Function <ManagedChannel , K > blockingStub ,
111
- final Consumer <FlagdProviderEvent > onConnectionEvent ,
112
- final Consumer <T > eventStreamObserver ) {
113
- this (options , stub , blockingStub , onConnectionEvent , eventStreamObserver , ChannelBuilder .nettyChannel (options ));
78
+ final Consumer <FlagdProviderEvent > onConnectionEvent ) {
79
+ this (options , blockingStub , onConnectionEvent , ChannelBuilder .nettyChannel (options ));
114
80
}
115
81
116
82
/**
@@ -120,16 +86,20 @@ public GrpcConnector(
120
86
*/
121
87
public void initialize () throws Exception {
122
88
log .info ("Initializing GRPC connection..." );
123
- ChannelMonitor . monitorChannelState (ConnectivityState .READY , channel , this :: onReady , this :: onConnectionLost );
89
+ monitorChannelState (ConnectivityState .READY );
124
90
}
125
91
126
92
/**
127
93
* Returns the blocking service stub for making blocking GRPC calls.
128
94
*
129
95
* @return the blocking service stub
130
96
*/
131
- public K getResolver () {
132
- return blockingStubFunction .apply (channel ).withWaitForReady ();
97
+ public K getBlockingStub () {
98
+ K stub = blockingStubFunction .apply (channel ).withWaitForReady ();
99
+ if (this .deadline > 0 ) {
100
+ stub = stub .withDeadlineAfter (this .deadline , TimeUnit .MILLISECONDS );
101
+ }
102
+ return stub ;
133
103
}
134
104
135
105
/**
@@ -147,39 +117,25 @@ public void shutdown() throws InterruptedException {
147
117
}
148
118
149
119
/**
150
- * Handles the event when the GRPC channel becomes ready, marking the connection as established.
151
- * Cancels any pending reconnection task and restarts the event stream.
152
- */
153
- private synchronized void onReady () {
154
- connected = true ;
155
- restartStream ();
156
- }
157
-
158
- /**
159
- * Handles the event when the GRPC channel loses its connection, marking the connection as lost.
160
- * Schedules a reconnection task after a grace period and emits a stale connection event.
120
+ * Monitors the state of a gRPC channel and triggers the specified callbacks based on state changes.
121
+ *
122
+ * @param expectedState the initial state to monitor.
161
123
*/
162
- private synchronized void onConnectionLost () {
163
- connected = false ;
164
-
165
- this .onConnectionEvent .accept (new FlagdProviderEvent (
166
- ProviderEvent .PROVIDER_ERROR , Collections .emptyList (), new ImmutableStructure ()));
124
+ private void monitorChannelState (ConnectivityState expectedState ) {
125
+ channel .notifyWhenStateChanged (expectedState , this ::onStateChange );
167
126
}
168
127
169
- /**
170
- * Restarts the event stream using the asynchronous service stub, applying a deadline if configured.
171
- * Emits a connection event if the restart is successful.
172
- */
173
- private synchronized void restartStream () {
174
- if (connected ) {
175
- log .debug ("(Re)initializing event stream." );
176
- T localServiceStub = this .serviceStub ;
177
- if (streamDeadlineMs > 0 ) {
178
- localServiceStub = localServiceStub .withDeadlineAfter (this .streamDeadlineMs , TimeUnit .MILLISECONDS );
179
- }
180
- streamObserver .accept (localServiceStub );
181
- return ;
128
+ private void onStateChange () {
129
+ ConnectivityState currentState = channel .getState (true );
130
+ log .debug ("Channel state changed to: {}" , currentState );
131
+ if (currentState == ConnectivityState .TRANSIENT_FAILURE || currentState == ConnectivityState .SHUTDOWN ) {
132
+ this .onConnectionEvent .accept (new FlagdProviderEvent (
133
+ ProviderEvent .PROVIDER_ERROR , Collections .emptyList (), new ImmutableStructure ()));
134
+ }
135
+ if (currentState != ConnectivityState .SHUTDOWN ) {
136
+ log .debug ("continuing to monitor the grpc channel" );
137
+ // Re-register the state monitor to watch for the next state transition.
138
+ monitorChannelState (currentState );
182
139
}
183
- log .debug ("Stream restart skipped. Not connected." );
184
140
}
185
141
}
0 commit comments