@@ -172,7 +172,7 @@ public final class StreamingDataflowWorker {
172172 "windmill_bounded_queue_executor_use_fair_monitor" ;
173173
174174 private final WindmillStateCache stateCache ;
175- private final StreamingWorkerStatusPages statusPages ;
175+ private StreamingWorkerStatusPages statusPages ;
176176 private final ComputationConfig .Fetcher configFetcher ;
177177 private final ComputationStateCache computationStateCache ;
178178 private final BoundedQueueExecutor workUnitExecutor ;
@@ -189,7 +189,10 @@ public final class StreamingDataflowWorker {
189189 private Consumer <PrintWriter > getDataStatusProvider ;
190190 private Supplier <Long > currentActiveCommitBytesProvider ;
191191 private @ Nullable ChannelzServlet channelzServlet ;
192+ private @ Nullable ChannelCache channelCache ;
193+ private Supplier <Instant > clock ;
192194 private final GrpcDispatcherClient dispatcherClient ;
195+ private final ExecutorService harnessSwitchExecutor ;
193196
194197 private StreamingDataflowWorker (
195198 WindmillServerStub windmillServer ,
@@ -222,6 +225,10 @@ private StreamingDataflowWorker(
222225 Executors .newCachedThreadPool ());
223226 this .options = options ;
224227 this .workUnitExecutor = workUnitExecutor ;
228+ this .harnessSwitchExecutor =
229+ Executors .newSingleThreadExecutor (
230+ new ThreadFactoryBuilder ().setNameFormat ("HarnessSwtichExecutor" ).build ());
231+ this .clock = clock ;
225232 this .memoryMonitor = BackgroundMemoryMonitor .create (memoryMonitor );
226233 this .numCommitThreads =
227234 options .isEnableStreamingEngine ()
@@ -247,9 +254,8 @@ private StreamingDataflowWorker(
247254 stageInfoMap );
248255 ThrottlingGetDataMetricTracker getDataMetricTracker =
249256 new ThrottlingGetDataMetricTracker (memoryMonitor );
250- // Status page members. Different implementations on whether the harness is streaming engine
257+ // Different implementations on whether the harness is streaming engine
251258 // direct path, streaming engine cloud path, or streaming appliance.
252- ChannelCache channelCache = null ;
253259 if (options .isEnableStreamingEngine ()) {
254260 if (options .getIsWindmillServiceDirectPathEnabled ()) {
255261 FanOutStreamingEngineWorkerHarness fanOutStreamingEngineWorkerHarness =
@@ -260,15 +266,8 @@ private StreamingDataflowWorker(
260266 streamingWorkScheduler ,
261267 getDataMetricTracker ,
262268 memoryMonitor ,
263- channelCache ,
264269 this .dispatcherClient );
265270 this .streamingWorkerHarness .set (fanOutStreamingEngineWorkerHarness );
266- this .getDataStatusProvider = getDataMetricTracker ::printHtml ;
267- this .currentActiveCommitBytesProvider =
268- fanOutStreamingEngineWorkerHarness ::currentActiveCommitBytes ;
269- this .channelzServlet =
270- createChannelzServlet (
271- options , fanOutStreamingEngineWorkerHarness ::currentWindmillEndpoints );
272271 } else {
273272 StreamingWorkerHarness singleSourceWorkerHarness =
274273 createSingleSourceWorkerHarness (
@@ -300,7 +299,6 @@ private StreamingDataflowWorker(
300299
301300 getDataStatusProvider = getDataClient ::printHtml ;
302301 currentActiveCommitBytesProvider = workCommitter ::currentActiveCommitBytes ;
303-
304302 this .streamingWorkerHarness .set (
305303 SingleSourceWorkerHarness .builder ()
306304 .setStreamingWorkScheduler (streamingWorkScheduler )
@@ -312,27 +310,27 @@ private StreamingDataflowWorker(
312310 .setGetWorkSender (getWorkSender )
313311 .build ());
314312 }
315-
316313 configFetcher
317314 .getGlobalConfigHandle ()
318315 .registerConfigObserver (
319316 streamingGlobalConfig -> {
320- // verify that global config only applies to streaming engine
317+ // TODO: confirm that global config only applies to streaming engine
321318 ConnectivityType connectivityType =
322319 streamingGlobalConfig .userWorkerJobSettings ().getConnectivityType ();
323320 if (connectivityType != ConnectivityType .CONNECTIVITY_TYPE_DEFAULT ) {
324321 LOG .debug ("Switching to connectivityType: {}." , connectivityType );
325- switchStreamingWorkerHarness (
326- connectivityType ,
327- clientId ,
328- options ,
329- windmillStreamFactory ,
330- streamingWorkScheduler ,
331- getDataMetricTracker ,
332- memoryMonitor ,
333- channelCache ,
334- this .dispatcherClient ,
335- windmillServer );
322+ harnessSwitchExecutor .execute (
323+ () ->
324+ switchStreamingWorkerHarness (
325+ connectivityType ,
326+ clientId ,
327+ options ,
328+ windmillStreamFactory ,
329+ streamingWorkScheduler ,
330+ getDataMetricTracker ,
331+ memoryMonitor ,
332+ this .dispatcherClient ,
333+ windmillServer ));
336334 }
337335 });
338336 this .workerStatusReporter = streamingWorkerStatusReporter ;
@@ -377,47 +375,56 @@ private FanOutStreamingEngineWorkerHarness createFanOutStreamingEngineWorkerHarn
377375 StreamingWorkScheduler streamingWorkScheduler ,
378376 ThrottlingGetDataMetricTracker getDataMetricTracker ,
379377 MemoryMonitor memoryMonitor ,
380- ChannelCache channelCache ,
381378 GrpcDispatcherClient dispatcherClient ) {
382-
383379 WeightedSemaphore <Commit > maxCommitByteSemaphore = Commits .maxCommitByteSemaphore ();
384- channelCache = channelCache == null ? createChannelCache (options , configFetcher ) : channelCache ;
385-
386- return FanOutStreamingEngineWorkerHarness .create (
387- createJobHeader (options , clientId ),
388- GetWorkBudget .builder ()
389- .setItems (chooseMaxBundlesOutstanding (options ))
390- .setBytes (MAX_GET_WORK_FETCH_BYTES )
391- .build (),
392- windmillStreamFactory ,
393- (workItem , serializedWorkItemSize , watermarks , processingContext , getWorkStreamLatencies ) ->
394- computationStateCache
395- .get (processingContext .computationId ())
396- .ifPresent (
397- computationState -> {
398- memoryMonitor .waitForResources ("GetWork" );
399- streamingWorkScheduler .scheduleWork (
400- computationState ,
401- workItem ,
402- serializedWorkItemSize ,
403- watermarks ,
404- processingContext ,
405- getWorkStreamLatencies );
406- }),
407- ChannelCachingRemoteStubFactory .create (options .getGcpCredential (), channelCache ),
408- GetWorkBudgetDistributors .distributeEvenly (),
409- Preconditions .checkNotNull (dispatcherClient ),
410- commitWorkStream ->
411- StreamingEngineWorkCommitter .builder ()
412- // Share the commitByteSemaphore across all created workCommitters.
413- .setCommitByteSemaphore (maxCommitByteSemaphore )
414- .setBackendWorkerToken (commitWorkStream .backendWorkerToken ())
415- .setOnCommitComplete (this ::onCompleteCommit )
416- .setNumCommitSenders (Math .max (options .getWindmillServiceCommitThreads (), 1 ))
417- .setCommitWorkStreamFactory (
418- () -> CloseableStream .create (commitWorkStream , () -> {}))
380+ this .channelCache = createChannelCache (options , configFetcher );
381+ this .getDataStatusProvider = getDataMetricTracker ::printHtml ;
382+ FanOutStreamingEngineWorkerHarness fanOutStreamingEngineWorkerHarness =
383+ FanOutStreamingEngineWorkerHarness .create (
384+ createJobHeader (options , clientId ),
385+ GetWorkBudget .builder ()
386+ .setItems (chooseMaxBundlesOutstanding (options ))
387+ .setBytes (MAX_GET_WORK_FETCH_BYTES )
419388 .build (),
420- getDataMetricTracker );
389+ windmillStreamFactory ,
390+ (workItem ,
391+ serializedWorkItemSize ,
392+ watermarks ,
393+ processingContext ,
394+ getWorkStreamLatencies ) ->
395+ computationStateCache
396+ .get (processingContext .computationId ())
397+ .ifPresent (
398+ computationState -> {
399+ memoryMonitor .waitForResources ("GetWork" );
400+ streamingWorkScheduler .scheduleWork (
401+ computationState ,
402+ workItem ,
403+ serializedWorkItemSize ,
404+ watermarks ,
405+ processingContext ,
406+ getWorkStreamLatencies );
407+ }),
408+ ChannelCachingRemoteStubFactory .create (options .getGcpCredential (), channelCache ),
409+ GetWorkBudgetDistributors .distributeEvenly (),
410+ Preconditions .checkNotNull (dispatcherClient ),
411+ commitWorkStream ->
412+ StreamingEngineWorkCommitter .builder ()
413+ // Share the commitByteSemaphore across all created workCommitters.
414+ .setCommitByteSemaphore (maxCommitByteSemaphore )
415+ .setBackendWorkerToken (commitWorkStream .backendWorkerToken ())
416+ .setOnCommitComplete (this ::onCompleteCommit )
417+ .setNumCommitSenders (Math .max (options .getWindmillServiceCommitThreads (), 1 ))
418+ .setCommitWorkStreamFactory (
419+ () -> CloseableStream .create (commitWorkStream , () -> {}))
420+ .build (),
421+ getDataMetricTracker );
422+ this .currentActiveCommitBytesProvider =
423+ fanOutStreamingEngineWorkerHarness ::currentActiveCommitBytes ;
424+ this .channelzServlet =
425+ createChannelzServlet (
426+ options , fanOutStreamingEngineWorkerHarness ::currentWindmillEndpoints );
427+ return fanOutStreamingEngineWorkerHarness ;
421428 }
422429
423430 private StreamingWorkerHarness createSingleSourceWorkerHarness (
@@ -461,6 +468,7 @@ private StreamingWorkerHarness createSingleSourceWorkerHarness(
461468 this .currentActiveCommitBytesProvider = workCommitter ::currentActiveCommitBytes ;
462469 this .channelzServlet =
463470 createChannelzServlet (options , windmillServer ::getWindmillServiceEndpoints );
471+ this .channelCache = null ;
464472
465473 return SingleSourceWorkerHarness .builder ()
466474 .setStreamingWorkScheduler (streamingWorkScheduler )
@@ -481,11 +489,14 @@ private void switchStreamingWorkerHarness(
481489 StreamingWorkScheduler streamingWorkScheduler ,
482490 ThrottlingGetDataMetricTracker getDataMetricTracker ,
483491 MemoryMonitor memoryMonitor ,
484- ChannelCache channelCache ,
485492 GrpcDispatcherClient dispatcherClient ,
486493 WindmillServerStub windmillServer ) {
494+ // Stop the current status pages before switching the harness.
495+ this .statusPages .stop ();
496+ LOG .debug ("Stopped StreamingWorkerStatusPages before switching connectivity type." );
487497 if (connectivityType == ConnectivityType .CONNECTIVITY_TYPE_DIRECTPATH ) {
488498 if (!(this .streamingWorkerHarness .get () instanceof FanOutStreamingEngineWorkerHarness )) {
499+ LOG .info ("Switching connectivity type from CLOUDPATH to DIRECTPATH" );
489500 LOG .debug ("Shutting down to SingleSourceWorkerHarness" );
490501 this .streamingWorkerHarness .get ().shutdown ();
491502 FanOutStreamingEngineWorkerHarness fanoutStreamingWorkerHarness =
@@ -496,20 +507,15 @@ private void switchStreamingWorkerHarness(
496507 streamingWorkScheduler ,
497508 getDataMetricTracker ,
498509 memoryMonitor ,
499- channelCache ,
500510 dispatcherClient );
501511 this .streamingWorkerHarness .set (fanoutStreamingWorkerHarness );
502- this .getDataStatusProvider = getDataMetricTracker ::printHtml ;
503- this .currentActiveCommitBytesProvider =
504- fanoutStreamingWorkerHarness ::currentActiveCommitBytes ;
505- this .channelzServlet =
506- createChannelzServlet (options , fanoutStreamingWorkerHarness ::currentWindmillEndpoints );
507512 streamingWorkerHarness .get ().start ();
508513 LOG .debug ("Started FanOutStreamingEngineWorkerHarness" );
509514 return ;
510515 }
511- } else {
516+ } else if ( connectivityType == ConnectivityType . CONNECTIVITY_TYPE_CLOUDPATH ) {
512517 if (!(streamingWorkerHarness .get () instanceof SingleSourceWorkerHarness )) {
518+ LOG .info ("Switching connectivity type from DIRECTPATH to CLOUDPATH" );
513519 LOG .debug ("Shutting down to FanOutStreamingEngineWorkerHarness" );
514520 streamingWorkerHarness .get ().shutdown ();
515521 streamingWorkerHarness .set (
@@ -525,6 +531,22 @@ private void switchStreamingWorkerHarness(
525531 return ;
526532 }
527533 }
534+ this .statusPages =
535+ createStatusPageBuilder (options , windmillStreamFactory , memoryMonitor )
536+ .setClock (this .clock )
537+ .setClientId (clientId )
538+ .setIsRunning (running )
539+ .setStateCache (stateCache )
540+ .setComputationStateCache (this .computationStateCache )
541+ .setWorkUnitExecutor (workUnitExecutor )
542+ .setGlobalConfigHandle (configFetcher .getGlobalConfigHandle ())
543+ .setChannelzServlet (this .channelzServlet )
544+ .setGetDataStatusProvider (this .getDataStatusProvider )
545+ .setCurrentActiveCommitBytes (this .currentActiveCommitBytesProvider )
546+ .setChannelCache (this .channelCache )
547+ .build ();
548+ this .statusPages .start (options );
549+ LOG .info ("Started new StreamingWorkerStatusPages instance." );
528550 }
529551
530552 private static StreamingWorkerStatusPages .Builder createStatusPageBuilder (
@@ -1043,6 +1065,7 @@ void stop() {
10431065 streamingWorkerHarness .get ().shutdown ();
10441066 memoryMonitor .shutdown ();
10451067 workUnitExecutor .shutdown ();
1068+ harnessSwitchExecutor .shutdown ();
10461069 computationStateCache .closeAndInvalidateAll ();
10471070 workerStatusReporter .stop ();
10481071 } catch (Exception e ) {
0 commit comments