Skip to content

Commit 6a86204

Browse files
committed
Restart StreamingWorkerStatusPages whenever harness type is swithched
1 parent dc9287a commit 6a86204

3 files changed

Lines changed: 96 additions & 74 deletions

File tree

runners/google-cloud-dataflow-java/src/main/java/org/apache/beam/runners/dataflow/options/DataflowStreamingPipelineOptions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ public Integer create(PipelineOptions options) {
310310
class EnableWindmillServiceDirectPathFactory implements DefaultValueFactory<Boolean> {
311311
@Override
312312
public Boolean create(PipelineOptions options) {
313+
if (ExperimentalOptions.hasExperiment(options, "enable_windmill_service_direct_path=false")) {
314+
return false;
315+
}
313316
return ExperimentalOptions.hasExperiment(options, "enable_windmill_service_direct_path");
314317
}
315318
}

runners/google-cloud-dataflow-java/worker/src/main/java/org/apache/beam/runners/dataflow/worker/StreamingDataflowWorker.java

Lines changed: 93 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {

runners/google-cloud-dataflow-java/worker/src/main/java/org/apache/beam/runners/dataflow/worker/streaming/harness/StreamingWorkerStatusPages.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,6 @@ public static StreamingWorkerStatusPages.Builder builder() {
124124
new ThreadFactoryBuilder().setNameFormat(DUMP_STATUS_PAGES_EXECUTOR).build()));
125125
}
126126

127-
public void updateChannelCache(@Nullable ChannelCache channelCache) {
128-
this.channelCache = channelCache;
129-
}
130-
131127
public void start(DataflowWorkerHarnessOptions options) {
132128
statusPages.addServlet(stateCache.statusServlet());
133129
statusPages.addServlet(newSpecServlet());

0 commit comments

Comments
 (0)