Skip to content

Commit 534afd6

Browse files
committed
[FLINK-23704][task] Apply review suggestsion for generating LatencyMarkers in FLIP-27 sources
1 parent 2ed9278 commit 534afd6

File tree

2 files changed

+94
-348
lines changed

2 files changed

+94
-348
lines changed

flink-streaming-java/src/main/java/org/apache/flink/streaming/api/operators/SourceOperator.java

+24-98
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.apache.flink.core.io.InputStatus;
3434
import org.apache.flink.core.io.SimpleVersionedSerializer;
3535
import org.apache.flink.metrics.MetricGroup;
36-
import org.apache.flink.runtime.jobgraph.OperatorID;
3736
import org.apache.flink.runtime.operators.coordination.OperatorEvent;
3837
import org.apache.flink.runtime.operators.coordination.OperatorEventGateway;
3938
import org.apache.flink.runtime.operators.coordination.OperatorEventHandler;
@@ -47,7 +46,6 @@
4746
import org.apache.flink.streaming.api.operators.source.TimestampsAndWatermarks;
4847
import org.apache.flink.streaming.api.operators.util.SimpleVersionedListState;
4948
import org.apache.flink.streaming.runtime.io.PushingAsyncDataInput;
50-
import org.apache.flink.streaming.runtime.streamrecord.LatencyMarker;
5149
import org.apache.flink.streaming.runtime.tasks.ProcessingTimeService;
5250
import org.apache.flink.util.CollectionUtil;
5351
import org.apache.flink.util.FlinkRuntimeException;
@@ -58,10 +56,8 @@
5856
import java.io.IOException;
5957
import java.util.List;
6058
import java.util.concurrent.CompletableFuture;
61-
import java.util.concurrent.ScheduledFuture;
6259

6360
import static org.apache.flink.util.Preconditions.checkNotNull;
64-
import static org.apache.flink.util.Preconditions.checkState;
6561

6662
/**
6763
* Base source operator only used for integrating the source reader which is proposed by FLIP-27. It
@@ -136,7 +132,7 @@ public class SourceOperator<OUT, SplitT extends SourceSplit> extends AbstractStr
136132
/** Indicating whether the source operator has been closed. */
137133
private boolean closed;
138134

139-
private LatencyMarkerEmitter<OUT> latencyMarerEmitter;
135+
private @Nullable LatencyMarkerEmitter<OUT> latencyMarerEmitter;
140136

141137
public SourceOperator(
142138
FunctionWithException<SourceReaderContext, SourceReader<OUT, SplitT>, Exception>
@@ -237,19 +233,6 @@ public void open() throws Exception {
237233
watermarkStrategy, getMetricGroup());
238234
}
239235

240-
latencyMarerEmitter =
241-
new LatencyMarkerEmitter<>(
242-
getProcessingTimeService(),
243-
getExecutionConfig().isLatencyTrackingConfigured()
244-
? getExecutionConfig().getLatencyTrackingInterval()
245-
: getContainingTask()
246-
.getEnvironment()
247-
.getTaskManagerInfo()
248-
.getConfiguration()
249-
.getLong(MetricOptions.LATENCY_INTERVAL),
250-
getOperatorID(),
251-
getRuntimeContext().getIndexOfThisSubtask());
252-
253236
// restore the state if necessary.
254237
final List<SplitT> splits = CollectionUtil.iterableToList(readerState.get());
255238
if (!splits.isEmpty()) {
@@ -263,7 +246,6 @@ public void open() throws Exception {
263246
sourceReader.start();
264247

265248
eventTimeLogic.startPeriodicWatermarkEmits();
266-
latencyMarerEmitter.startLatencyMarkerEmit();
267249
}
268250

269251
@Override
@@ -272,7 +254,7 @@ public void close() throws Exception {
272254
eventTimeLogic.stopPeriodicWatermarkEmits();
273255
}
274256
if (latencyMarerEmitter != null) {
275-
latencyMarerEmitter.stopLatencyMarkerEmit();
257+
latencyMarerEmitter.close();
276258
}
277259
if (sourceReader != null) {
278260
sourceReader.close();
@@ -289,7 +271,7 @@ public void dispose() throws Exception {
289271
sourceReader.close();
290272
}
291273
if (latencyMarerEmitter != null) {
292-
latencyMarerEmitter.stopLatencyMarkerEmit();
274+
latencyMarerEmitter.close();
293275
}
294276
}
295277

@@ -306,11 +288,31 @@ public InputStatus emitNext(DataOutput<OUT> output) throws Exception {
306288

307289
// this creates a batch or streaming output based on the runtime mode
308290
currentMainOutput = eventTimeLogic.createMainOutput(output);
309-
latencyMarerEmitter.emitMainOutput(output);
291+
initializeLatencyMarkerEmitter(output);
310292
lastInvokedOutput = output;
311293
return sourceReader.pollNext(currentMainOutput);
312294
}
313295

296+
private void initializeLatencyMarkerEmitter(DataOutput<OUT> output) {
297+
long latencyTrackingInterval =
298+
getExecutionConfig().isLatencyTrackingConfigured()
299+
? getExecutionConfig().getLatencyTrackingInterval()
300+
: getContainingTask()
301+
.getEnvironment()
302+
.getTaskManagerInfo()
303+
.getConfiguration()
304+
.getLong(MetricOptions.LATENCY_INTERVAL);
305+
if (latencyTrackingInterval > 0) {
306+
latencyMarerEmitter =
307+
new org.apache.flink.streaming.api.operators.LatencyMarkerEmitter<>(
308+
getProcessingTimeService(),
309+
output::emitLatencyMarker,
310+
latencyTrackingInterval,
311+
getOperatorID(),
312+
getRuntimeContext().getIndexOfThisSubtask());
313+
}
314+
}
315+
314316
@Override
315317
public void snapshotState(StateSnapshotContext context) throws Exception {
316318
long checkpointId = context.getCheckpointId();
@@ -377,80 +379,4 @@ public SourceReader<OUT, SplitT> getSourceReader() {
377379
ListState<SplitT> getReaderState() {
378380
return readerState;
379381
}
380-
381-
private static class LatencyMarkerEmitter<OUT> {
382-
383-
private final ProcessingTimeService timeService;
384-
385-
private final long latencyTrackingInterval;
386-
387-
private final OperatorID operatorId;
388-
389-
private final int subtaskIndex;
390-
391-
@Nullable private DataOutput<OUT> currentMainOutput;
392-
393-
@Nullable
394-
private ScheduledFuture<?> latencyMarkerTimer;
395-
396-
public LatencyMarkerEmitter(
397-
final ProcessingTimeService timeService,
398-
long latencyTrackingInterval,
399-
final OperatorID operatorId,
400-
final int subtaskIndex) {
401-
this.timeService = timeService;
402-
this.latencyTrackingInterval = latencyTrackingInterval;
403-
this.operatorId = operatorId;
404-
this.subtaskIndex = subtaskIndex;
405-
}
406-
407-
// ------------------------------------------------------------------------
408-
409-
public void emitMainOutput(PushingAsyncDataInput.DataOutput<OUT> output) {
410-
// At the moment, we assume only one output is ever created!
411-
// This assumption is strict, currently, because many of the classes in this
412-
// implementation
413-
// do not support re-assigning the underlying output
414-
checkState(currentMainOutput == null, "Main output has already been set.");
415-
currentMainOutput = output;
416-
}
417-
418-
public void startLatencyMarkerEmit() {
419-
checkState(
420-
latencyMarkerTimer == null, "Latency marker emitter has already been started");
421-
if (latencyTrackingInterval == 0) {
422-
// a value of zero means not activated
423-
return;
424-
}
425-
latencyMarkerTimer =
426-
timeService.scheduleWithFixedDelay(
427-
this::triggerLatencyMarkerEmit, 0L, latencyTrackingInterval);
428-
}
429-
430-
public void stopLatencyMarkerEmit() {
431-
if (latencyMarkerTimer != null) {
432-
latencyMarkerTimer.cancel(false);
433-
latencyMarkerTimer = null;
434-
}
435-
}
436-
437-
void triggerLatencyMarkerEmit(@SuppressWarnings("unused") long wallClockTimestamp) {
438-
if (currentMainOutput != null) {
439-
try {
440-
// ProcessingTimeService callbacks are executed under the
441-
// checkpointing lock
442-
currentMainOutput.emitLatencyMarker(
443-
new LatencyMarker(
444-
timeService.getCurrentProcessingTime(),
445-
operatorId,
446-
subtaskIndex));
447-
} catch (Throwable t) {
448-
// we catch the Throwable here so that we don't trigger the
449-
// processing
450-
// timer services async exception handler
451-
LOG.warn("Error while emitting latency marker.", t);
452-
}
453-
}
454-
}
455-
}
456382
}

0 commit comments

Comments
 (0)