Search in sources :

Example 1 with OnTimer

use of org.apache.beam.sdk.transforms.DoFn.OnTimer in project beam by apache.

the class ParDoTest method testOutOfBoundsEventTimeTimer.

@Test
@Category({ ValidatesRunner.class, UsesTimersInParDo.class })
public void testOutOfBoundsEventTimeTimer() throws Exception {
    final String timerId = "foo";
    DoFn<KV<String, Integer>, Integer> fn = new DoFn<KV<String, Integer>, Integer>() {

        @TimerId(timerId)
        private final TimerSpec spec = TimerSpecs.timer(TimeDomain.EVENT_TIME);

        @ProcessElement
        public void processElement(ProcessContext context, BoundedWindow window, @TimerId(timerId) Timer timer) {
            timer.set(window.maxTimestamp().plus(1L));
        }

        @OnTimer(timerId)
        public void onTimer(OnTimerContext context) {
        }
    };
    PCollection<Integer> output = pipeline.apply(Create.of(KV.of("hello", 37))).apply(ParDo.of(fn));
    thrown.expect(RuntimeException.class);
    // Note that runners can reasonably vary their message - this matcher should be flexible
    // and can be evolved.
    thrown.expectMessage("event time timer");
    thrown.expectMessage("expiration");
    pipeline.run();
}
Also used : OnTimer(org.apache.beam.sdk.transforms.DoFn.OnTimer) Timer(org.apache.beam.sdk.state.Timer) BoundedWindow(org.apache.beam.sdk.transforms.windowing.BoundedWindow) StringUtils.byteArrayToJsonString(org.apache.beam.sdk.util.StringUtils.byteArrayToJsonString) Matchers.containsString(org.hamcrest.Matchers.containsString) KV(org.apache.beam.sdk.values.KV) TimerSpec(org.apache.beam.sdk.state.TimerSpec) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Example 2 with OnTimer

use of org.apache.beam.sdk.transforms.DoFn.OnTimer in project beam by apache.

the class ParDoTest method testEventTimeTimerMultipleKeys.

/**
   * Tests that event time timers for multiple keys both fire. This particularly exercises
   * implementations that may GC in ways not simply governed by the watermark.
   */
@Test
@Category({ ValidatesRunner.class, UsesTimersInParDo.class })
public void testEventTimeTimerMultipleKeys() throws Exception {
    final String timerId = "foo";
    final String stateId = "sizzle";
    final int offset = 5000;
    final int timerOutput = 4093;
    DoFn<KV<String, Integer>, KV<String, Integer>> fn = new DoFn<KV<String, Integer>, KV<String, Integer>>() {

        @TimerId(timerId)
        private final TimerSpec spec = TimerSpecs.timer(TimeDomain.EVENT_TIME);

        @StateId(stateId)
        private final StateSpec<ValueState<String>> stateSpec = StateSpecs.value(StringUtf8Coder.of());

        @ProcessElement
        public void processElement(ProcessContext context, @TimerId(timerId) Timer timer, @StateId(stateId) ValueState<String> state, BoundedWindow window) {
            timer.set(window.maxTimestamp());
            state.write(context.element().getKey());
            context.output(KV.of(context.element().getKey(), context.element().getValue() + offset));
        }

        @OnTimer(timerId)
        public void onTimer(OnTimerContext context, @StateId(stateId) ValueState<String> state) {
            context.output(KV.of(state.read(), timerOutput));
        }
    };
    // Enough keys that we exercise interesting code paths
    int numKeys = 50;
    List<KV<String, Integer>> input = new ArrayList<>();
    List<KV<String, Integer>> expectedOutput = new ArrayList<>();
    for (Integer key = 0; key < numKeys; ++key) {
        // Each key should have just one final output at GC time
        expectedOutput.add(KV.of(key.toString(), timerOutput));
        for (int i = 0; i < 15; ++i) {
            // Each input should be output with the offset added
            input.add(KV.of(key.toString(), i));
            expectedOutput.add(KV.of(key.toString(), i + offset));
        }
    }
    Collections.shuffle(input);
    PCollection<KV<String, Integer>> output = pipeline.apply(Create.of(input)).apply(ParDo.of(fn));
    PAssert.that(output).containsInAnyOrder(expectedOutput);
    pipeline.run();
}
Also used : ArrayList(java.util.ArrayList) StringUtils.byteArrayToJsonString(org.apache.beam.sdk.util.StringUtils.byteArrayToJsonString) Matchers.containsString(org.hamcrest.Matchers.containsString) KV(org.apache.beam.sdk.values.KV) StateSpec(org.apache.beam.sdk.state.StateSpec) ValueState(org.apache.beam.sdk.state.ValueState) OnTimer(org.apache.beam.sdk.transforms.DoFn.OnTimer) Timer(org.apache.beam.sdk.state.Timer) BoundedWindow(org.apache.beam.sdk.transforms.windowing.BoundedWindow) TimerSpec(org.apache.beam.sdk.state.TimerSpec) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Example 3 with OnTimer

use of org.apache.beam.sdk.transforms.DoFn.OnTimer in project beam by apache.

the class ParDoTest method testSimpleProcessingTimerTimer.

@Test
@Category({ NeedsRunner.class, UsesTimersInParDo.class, UsesTestStream.class })
public void testSimpleProcessingTimerTimer() throws Exception {
    final String timerId = "foo";
    DoFn<KV<String, Integer>, Integer> fn = new DoFn<KV<String, Integer>, Integer>() {

        @TimerId(timerId)
        private final TimerSpec spec = TimerSpecs.timer(TimeDomain.PROCESSING_TIME);

        @ProcessElement
        public void processElement(ProcessContext context, @TimerId(timerId) Timer timer) {
            timer.offset(Duration.standardSeconds(1)).setRelative();
            context.output(3);
        }

        @OnTimer(timerId)
        public void onTimer(OnTimerContext context) {
            context.output(42);
        }
    };
    TestStream<KV<String, Integer>> stream = TestStream.create(KvCoder.of(StringUtf8Coder.of(), VarIntCoder.of())).addElements(KV.of("hello", 37)).advanceProcessingTime(Duration.standardSeconds(2)).advanceWatermarkToInfinity();
    PCollection<Integer> output = pipeline.apply(stream).apply(ParDo.of(fn));
    PAssert.that(output).containsInAnyOrder(3, 42);
    pipeline.run();
}
Also used : OnTimer(org.apache.beam.sdk.transforms.DoFn.OnTimer) Timer(org.apache.beam.sdk.state.Timer) StringUtils.byteArrayToJsonString(org.apache.beam.sdk.util.StringUtils.byteArrayToJsonString) Matchers.containsString(org.hamcrest.Matchers.containsString) KV(org.apache.beam.sdk.values.KV) TimerSpec(org.apache.beam.sdk.state.TimerSpec) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Example 4 with OnTimer

use of org.apache.beam.sdk.transforms.DoFn.OnTimer in project beam by apache.

the class ParDoTest method testEventTimeTimerUnbounded.

@Test
@Category({ NeedsRunner.class, UsesTimersInParDo.class, UsesTestStream.class })
public void testEventTimeTimerUnbounded() throws Exception {
    final String timerId = "foo";
    DoFn<KV<String, Integer>, Integer> fn = new DoFn<KV<String, Integer>, Integer>() {

        @TimerId(timerId)
        private final TimerSpec spec = TimerSpecs.timer(TimeDomain.EVENT_TIME);

        @ProcessElement
        public void processElement(ProcessContext context, @TimerId(timerId) Timer timer) {
            timer.offset(Duration.standardSeconds(1)).setRelative();
            context.output(3);
        }

        @OnTimer(timerId)
        public void onTimer(OnTimerContext context) {
            context.output(42);
        }
    };
    TestStream<KV<String, Integer>> stream = TestStream.create(KvCoder.of(StringUtf8Coder.of(), VarIntCoder.of())).advanceWatermarkTo(new Instant(0)).addElements(KV.of("hello", 37)).advanceWatermarkTo(new Instant(0).plus(Duration.standardSeconds(1))).advanceWatermarkToInfinity();
    PCollection<Integer> output = pipeline.apply(stream).apply(ParDo.of(fn));
    PAssert.that(output).containsInAnyOrder(3, 42);
    pipeline.run();
}
Also used : Instant(org.joda.time.Instant) StringUtils.byteArrayToJsonString(org.apache.beam.sdk.util.StringUtils.byteArrayToJsonString) Matchers.containsString(org.hamcrest.Matchers.containsString) KV(org.apache.beam.sdk.values.KV) OnTimer(org.apache.beam.sdk.transforms.DoFn.OnTimer) Timer(org.apache.beam.sdk.state.Timer) TimerSpec(org.apache.beam.sdk.state.TimerSpec) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Example 5 with OnTimer

use of org.apache.beam.sdk.transforms.DoFn.OnTimer in project beam by apache.

the class ParDoTest method testEventTimeTimerBounded.

/**
   * Tests that an event time timer fires and results in supplementary output.
   *
   * <p>This test relies on two properties:
   *
   * <ol>
   * <li>A timer that is set on time should always get a chance to fire. For this to be true, timers
   *     per-key-and-window must be delivered in order so the timer is not wiped out until the
   *     window is expired by the runner.
   * <li>A {@link Create} transform sends its elements on time, and later advances the watermark to
   *     infinity
   * </ol>
   *
   * <p>Note that {@link TestStream} is not applicable because it requires very special runner hooks
   * and is only supported by the direct runner.
   */
@Test
@Category({ ValidatesRunner.class, UsesTimersInParDo.class })
public void testEventTimeTimerBounded() throws Exception {
    final String timerId = "foo";
    DoFn<KV<String, Integer>, Integer> fn = new DoFn<KV<String, Integer>, Integer>() {

        @TimerId(timerId)
        private final TimerSpec spec = TimerSpecs.timer(TimeDomain.EVENT_TIME);

        @ProcessElement
        public void processElement(ProcessContext context, @TimerId(timerId) Timer timer) {
            timer.offset(Duration.standardSeconds(1)).setRelative();
            context.output(3);
        }

        @OnTimer(timerId)
        public void onTimer(OnTimerContext context) {
            context.output(42);
        }
    };
    PCollection<Integer> output = pipeline.apply(Create.of(KV.of("hello", 37))).apply(ParDo.of(fn));
    PAssert.that(output).containsInAnyOrder(3, 42);
    pipeline.run();
}
Also used : OnTimer(org.apache.beam.sdk.transforms.DoFn.OnTimer) Timer(org.apache.beam.sdk.state.Timer) StringUtils.byteArrayToJsonString(org.apache.beam.sdk.util.StringUtils.byteArrayToJsonString) Matchers.containsString(org.hamcrest.Matchers.containsString) KV(org.apache.beam.sdk.values.KV) TimerSpec(org.apache.beam.sdk.state.TimerSpec) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Aggregations

Timer (org.apache.beam.sdk.state.Timer)11 TimerSpec (org.apache.beam.sdk.state.TimerSpec)11 OnTimer (org.apache.beam.sdk.transforms.DoFn.OnTimer)11 StringUtils.byteArrayToJsonString (org.apache.beam.sdk.util.StringUtils.byteArrayToJsonString)11 KV (org.apache.beam.sdk.values.KV)11 Matchers.containsString (org.hamcrest.Matchers.containsString)11 Test (org.junit.Test)11 Category (org.junit.experimental.categories.Category)11 Instant (org.joda.time.Instant)6 BoundedWindow (org.apache.beam.sdk.transforms.windowing.BoundedWindow)4 ArrayList (java.util.ArrayList)1 StateSpec (org.apache.beam.sdk.state.StateSpec)1 ValueState (org.apache.beam.sdk.state.ValueState)1 IntervalWindow (org.apache.beam.sdk.transforms.windowing.IntervalWindow)1 SlidingWindows (org.apache.beam.sdk.transforms.windowing.SlidingWindows)1 TypeDescriptor (org.apache.beam.sdk.values.TypeDescriptor)1