use of org.apache.beam.runners.core.StateNamespace in project beam by apache.
the class DoFnOperatorTest method testWatermarkUpdateAfterWatermarkHoldRelease.
@Test
public void testWatermarkUpdateAfterWatermarkHoldRelease() throws Exception {
Coder<WindowedValue<KV<String, String>>> coder = WindowedValue.getValueOnlyCoder(KvCoder.of(StringUtf8Coder.of(), StringUtf8Coder.of()));
TupleTag<KV<String, String>> outputTag = new TupleTag<>("main-output");
List<Long> emittedWatermarkHolds = new ArrayList<>();
KeySelector<WindowedValue<KV<String, String>>, ByteBuffer> keySelector = e -> FlinkKeyUtils.encodeKey(e.getValue().getKey(), StringUtf8Coder.of());
DoFnOperator<KV<String, String>, KV<String, String>> doFnOperator = new DoFnOperator<KV<String, String>, KV<String, String>>(new IdentityDoFn<>(), "stepName", coder, Collections.emptyMap(), outputTag, Collections.emptyList(), new DoFnOperator.MultiOutputOutputManagerFactory<>(outputTag, coder, new SerializablePipelineOptions(FlinkPipelineOptions.defaults())), WindowingStrategy.globalDefault(), new HashMap<>(), /* side-input mapping */
Collections.emptyList(), /* side inputs */
FlinkPipelineOptions.defaults(), StringUtf8Coder.of(), keySelector, DoFnSchemaInformation.create(), Collections.emptyMap()) {
@Override
protected DoFnRunner<KV<String, String>, KV<String, String>> createWrappingDoFnRunner(DoFnRunner<KV<String, String>, KV<String, String>> wrappedRunner, StepContext stepContext) {
StateNamespace namespace = StateNamespaces.window(GlobalWindow.Coder.INSTANCE, GlobalWindow.INSTANCE);
StateTag<WatermarkHoldState> holdTag = StateTags.watermarkStateInternal("hold", TimestampCombiner.LATEST);
WatermarkHoldState holdState = stepContext.stateInternals().state(namespace, holdTag);
TimerInternals timerInternals = stepContext.timerInternals();
return new DoFnRunner<KV<String, String>, KV<String, String>>() {
@Override
public void startBundle() {
wrappedRunner.startBundle();
}
@Override
public void processElement(WindowedValue<KV<String, String>> elem) {
wrappedRunner.processElement(elem);
holdState.add(elem.getTimestamp());
timerInternals.setTimer(namespace, "timer", "family", elem.getTimestamp().plus(Duration.millis(1)), elem.getTimestamp().plus(Duration.millis(1)), TimeDomain.EVENT_TIME);
timerInternals.setTimer(namespace, "cleanup", "", GlobalWindow.INSTANCE.maxTimestamp(), GlobalWindow.INSTANCE.maxTimestamp(), TimeDomain.EVENT_TIME);
}
@Override
public <KeyT> void onTimer(String timerId, String timerFamilyId, KeyT key, BoundedWindow window, Instant timestamp, Instant outputTimestamp, TimeDomain timeDomain) {
if ("cleanup".equals(timerId)) {
holdState.clear();
} else {
holdState.add(outputTimestamp);
}
}
@Override
public void finishBundle() {
wrappedRunner.finishBundle();
}
@Override
public <KeyT> void onWindowExpiration(BoundedWindow window, Instant timestamp, KeyT key) {
wrappedRunner.onWindowExpiration(window, timestamp, key);
}
@Override
public DoFn<KV<String, String>, KV<String, String>> getFn() {
return doFn;
}
};
}
@Override
void emitWatermarkIfHoldChanged(long currentWatermarkHold) {
emittedWatermarkHolds.add(keyedStateInternals.minWatermarkHoldMs());
}
};
OneInputStreamOperatorTestHarness<WindowedValue<KV<String, String>>, WindowedValue<KV<String, String>>> testHarness = new KeyedOneInputStreamOperatorTestHarness<>(doFnOperator, keySelector, new CoderTypeInformation<>(FlinkKeyUtils.ByteBufferCoder.of(), FlinkPipelineOptions.defaults()));
testHarness.setup();
Instant now = Instant.now();
testHarness.open();
// process first element, set hold to `now', setup timer for `now + 1'
testHarness.processElement(new StreamRecord<>(WindowedValue.timestampedValueInGlobalWindow(KV.of("Key", "Hello"), now)));
assertThat(emittedWatermarkHolds, is(equalTo(Collections.singletonList(now.getMillis()))));
// fire timer, change hold to `now + 2'
testHarness.processWatermark(now.getMillis() + 2);
assertThat(emittedWatermarkHolds, is(equalTo(Arrays.asList(now.getMillis(), now.getMillis() + 1))));
// process second element, verify we emitted changed hold
testHarness.processElement(new StreamRecord<>(WindowedValue.timestampedValueInGlobalWindow(KV.of("Key", "Hello"), now.plus(Duration.millis(2)))));
assertThat(emittedWatermarkHolds, is(equalTo(Arrays.asList(now.getMillis(), now.getMillis() + 1, now.getMillis() + 2))));
testHarness.processWatermark(GlobalWindow.INSTANCE.maxTimestamp().plus(Duration.millis(1)).getMillis());
testHarness.processWatermark(BoundedWindow.TIMESTAMP_MAX_VALUE.getMillis());
testHarness.close();
}
use of org.apache.beam.runners.core.StateNamespace in project beam by apache.
the class StatefulParDoP method fireTimer.
private static void fireTimer(Object key, TimerInternals.TimerData timer, DoFnRunner<KV<?, ?>, ?> doFnRunner) {
StateNamespace namespace = timer.getNamespace();
BoundedWindow window = ((StateNamespaces.WindowNamespace) namespace).getWindow();
doFnRunner.onTimer(timer.getTimerId(), timer.getTimerFamilyId(), key, window, timer.getTimestamp(), timer.getOutputTimestamp(), timer.getDomain());
}
use of org.apache.beam.runners.core.StateNamespace in project beam by apache.
the class CopyOnAccessInMemoryStateInternalsTest method testCommitWithoutUnderlying.
@Test
public void testCommitWithoutUnderlying() {
CopyOnAccessInMemoryStateInternals<String> internals = CopyOnAccessInMemoryStateInternals.withUnderlying(key, null);
StateNamespace namespace = new StateNamespaceForTest("foo");
StateTag<BagState<String>> bagTag = StateTags.bag("foo", StringUtf8Coder.of());
BagState<String> stringBag = internals.state(namespace, bagTag);
assertThat(stringBag.read(), emptyIterable());
stringBag.add("bar");
stringBag.add("baz");
assertThat(stringBag.read(), containsInAnyOrder("baz", "bar"));
internals.commit();
BagState<String> reReadStringBag = internals.state(namespace, bagTag);
assertThat(reReadStringBag.read(), containsInAnyOrder("baz", "bar"));
assertThat(internals.isEmpty(), is(false));
}
use of org.apache.beam.runners.core.StateNamespace in project beam by apache.
the class CopyOnAccessInMemoryStateInternalsTest method testCommitWithOverwrittenUnderlying.
@Test
public void testCommitWithOverwrittenUnderlying() {
CopyOnAccessInMemoryStateInternals<String> underlying = CopyOnAccessInMemoryStateInternals.withUnderlying(key, null);
CopyOnAccessInMemoryStateInternals<String> internals = CopyOnAccessInMemoryStateInternals.withUnderlying(key, underlying);
StateNamespace namespace = new StateNamespaceForTest("foo");
StateTag<BagState<String>> bagTag = StateTags.bag("foo", StringUtf8Coder.of());
BagState<String> stringBag = underlying.state(namespace, bagTag);
assertThat(stringBag.read(), emptyIterable());
stringBag.add("bar");
stringBag.add("baz");
BagState<String> internalsState = internals.state(namespace, bagTag);
internalsState.add("eggs");
internalsState.add("ham");
internalsState.add("0x00ff00");
internalsState.add("&");
internals.commit();
BagState<String> reReadInternalState = internals.state(namespace, bagTag);
assertThat(reReadInternalState.read(), containsInAnyOrder("bar", "baz", "0x00ff00", "eggs", "&", "ham"));
BagState<String> reReadUnderlyingState = underlying.state(namespace, bagTag);
assertThat(reReadUnderlyingState.read(), containsInAnyOrder("bar", "baz"));
}
use of org.apache.beam.runners.core.StateNamespace in project beam by apache.
the class CopyOnAccessInMemoryStateInternalsTest method testGetWithAbsentInUnderlying.
@Test
public void testGetWithAbsentInUnderlying() {
CopyOnAccessInMemoryStateInternals<String> underlying = CopyOnAccessInMemoryStateInternals.withUnderlying(key, null);
CopyOnAccessInMemoryStateInternals<String> internals = CopyOnAccessInMemoryStateInternals.withUnderlying(key, underlying);
StateNamespace namespace = new StateNamespaceForTest("foo");
StateTag<BagState<String>> bagTag = StateTags.bag("foo", StringUtf8Coder.of());
BagState<String> stringBag = internals.state(namespace, bagTag);
assertThat(stringBag.read(), emptyIterable());
stringBag.add("bar");
stringBag.add("baz");
assertThat(stringBag.read(), containsInAnyOrder("baz", "bar"));
BagState<String> reReadVoidBag = internals.state(namespace, bagTag);
assertThat(reReadVoidBag.read(), containsInAnyOrder("baz", "bar"));
BagState<String> underlyingState = underlying.state(namespace, bagTag);
assertThat(underlyingState.read(), emptyIterable());
}
Aggregations