[ 
https://issues.apache.org/jira/browse/BEAM-7112?focusedWorklogId=232893&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-232893
 ]

ASF GitHub Bot logged work on BEAM-7112:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 25/Apr/19 14:13
            Start Date: 25/Apr/19 14:13
    Worklog Time Spent: 10m 
      Work Description: tweise commented on pull request #8399: [BEAM-7112] 
Timer race with state cleanup - take two
URL: https://github.com/apache/beam/pull/8399#discussion_r278570469
 
 

 ##########
 File path: 
runners/flink/src/test/java/org/apache/beam/runners/flink/translation/wrappers/streaming/ExecutableStageDoFnOperatorTest.java
 ##########
 @@ -449,6 +466,92 @@ public void 
testEnsureStateCleanupWithKeyedInputStateCleaner() throws Exception
     }
   }
 
+  @Test
+  public void testStateCleanup() throws Exception {
+    TupleTag<Integer> mainOutput = new TupleTag<>("main-output");
+    DoFnOperator.MultiOutputOutputManagerFactory<Integer> outputManagerFactory 
=
+        new DoFnOperator.MultiOutputOutputManagerFactory(mainOutput, 
VoidCoder.of());
+    StringUtf8Coder keyCoder = StringUtf8Coder.of();
+
+    WindowingStrategy windowingStrategy =
+        WindowingStrategy.of(FixedWindows.of(Duration.millis(1000)));
+
+    ExecutableStageDoFnOperator<Integer, Integer> operator =
+        getOperator(
+            mainOutput, Collections.emptyList(), outputManagerFactory, 
windowingStrategy, keyCoder);
+
+    @SuppressWarnings("unchecked")
+    RemoteBundle bundle = Mockito.mock(RemoteBundle.class);
+    when(stageBundleFactory.getBundle(any(), any(), any())).thenReturn(bundle);
+
+    String timerInputId = "timerInput";
+    AtomicBoolean timerInputReceived = new AtomicBoolean();
+    Instant windowEnd = new Instant(1000);
+    IntervalWindow window = new IntervalWindow(new Instant(0), windowEnd);
+    IntervalWindow.IntervalWindowCoder windowCoder = 
IntervalWindow.IntervalWindowCoder.of();
+    WindowedValue<KV<String, Integer>> one =
+        WindowedValue.of(
+            KV.of("one", 1), window.maxTimestamp(), ImmutableList.of(window), 
PaneInfo.NO_FIRING);
+
+    FnDataReceiver<WindowedValue<?>> receiver = 
Mockito.mock(FnDataReceiver.class);
+    FnDataReceiver<WindowedValue<?>> timerReceiver = 
Mockito.mock(FnDataReceiver.class);
+    doAnswer(
+            (invocation) -> {
+              timerInputReceived.set(true);
+              return null;
+            })
+        .when(timerReceiver)
+        .accept(any());
+
+    when(bundle.getInputReceivers())
+        .thenReturn(ImmutableMap.of("input", receiver, timerInputId, 
timerReceiver));
+
+    KeyedOneInputStreamOperatorTestHarness<
+            String, WindowedValue<KV<String, Integer>>, 
WindowedValue<KV<String, Integer>>>
+        testHarness =
+            new KeyedOneInputStreamOperatorTestHarness(
+                operator, val -> val, new CoderTypeInformation<>(keyCoder));
+
+    testHarness.open();
+
+    Lock stateBackendLock = (Lock) Whitebox.getInternalState(operator, 
"stateBackendLock");
+    stateBackendLock.lock();
+
+    KeyedStateBackend<ByteBuffer> keyedStateBackend = 
operator.getKeyedStateBackend();
+    ByteBuffer key =
+        FlinkKeyUtils.encodeKey(one.getValue().getKey(), keyCoder, 
Coder.Context.NESTED);
+    keyedStateBackend.setCurrentKey(key);
+
+    DoFnOperator.FlinkTimerInternals timerInternals =
+        (DoFnOperator.FlinkTimerInternals) Whitebox.getInternalState(operator, 
"timerInternals");
+    Collection<?> cleanupTimers = (Collection) 
Whitebox.getInternalState(operator, "cleanupTimers");
+
+    TimerInternals.TimerData timerData =
+        TimerInternals.TimerData.of(
+            timerInputId,
+            StateNamespaces.window(windowCoder, window),
+            windowEnd.plus(1),
+            TimeDomain.EVENT_TIME);
+    timerInternals.setTimer(timerData);
+
+    testHarness.processElement(new StreamRecord<>(one));
+    verify(receiver).accept(one);
+
+    // fire user and cleanup timer while bundle in progress
+    operator.processWatermark(new Watermark(windowEnd.getMillis() + 2));
 
 Review comment:
   This is supposed to trigger both the user timer and the state cleanup. User 
timer is scheduled after cleanup since I want to verify that the execution gets 
reordered. Added comments.
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


Issue Time Tracking
-------------------

    Worklog Id:     (was: 232893)
    Time Spent: 5h 10m  (was: 5h)

> State cleanup interferes with user timer callback
> -------------------------------------------------
>
>                 Key: BEAM-7112
>                 URL: https://issues.apache.org/jira/browse/BEAM-7112
>             Project: Beam
>          Issue Type: Bug
>          Components: runner-flink
>    Affects Versions: 2.12.0
>            Reporter: Thomas Weise
>            Assignee: Thomas Weise
>            Priority: Major
>              Labels: portability-flink
>             Fix For: 2.13.0
>
>          Time Spent: 5h 10m
>  Remaining Estimate: 0h
>
> Cleanup timers and user timers are fired at the watermark. Processing of 
> timers in the SDK worker is asynchronous, so it is possible that the state is 
> already removed when the user timer callback executes.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to