You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by zi...@apache.org on 2026/10/14 02:36:26 UTC
(dolphinscheduler) branch dev updated: [Fix-18692][Master] Fix ignored dependent task check interval (#18694)
This is an automated email from the ASF dual-hosted git repository.
SbloodyS pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new fa0fe2eab9 [Fix-18692][Master] Fix ignored dependent task check interval (#18694)
fa0fe2eab9 is described below
commit fa0fe2eab93abc2032af9558f1a7ffb6548152c8
Author: huangsheng <hu...@163.com>
AuthorDate: Wed Oct 14 10:36:19 2026 +0800
[Fix-18692][Master] Fix ignored dependent task check interval (#18694)
---
.../plugin/dependent/DependentLogicTask.java | 57 ++++++-
.../engine/executor/LogicTaskExecutorTest.java | 145 ++++++++++++++++
.../plugin/dependent/DependentLogicTaskTest.java | 189 +++++++++++++++++++++
3 files changed, 386 insertions(+), 5 deletions(-)
diff --git a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/executor/plugin/dependent/DependentLogicTask.java b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/executor/plugin/dependent/DependentLogicTask.java
index 484c7ef360..5dae467643 100644
--- a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/executor/plugin/dependent/DependentLogicTask.java
+++ b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/executor/plugin/dependent/DependentLogicTask.java
@@ -32,17 +32,29 @@ import org.apache.dolphinscheduler.server.master.engine.executor.plugin.ITaskPar
import org.apache.dolphinscheduler.server.master.engine.workflow.execution.IWorkflowExecution;
import org.apache.dolphinscheduler.server.master.exception.MasterTaskExecuteException;
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongSupplier;
+
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.annotations.VisibleForTesting;
@Slf4j
public class DependentLogicTask extends AbstractLogicTask<DependentParameters> {
+ private static final int DEFAULT_CHECK_INTERVAL_SECONDS = 10;
+
private final TaskExecutionContext taskExecutionContext;
private final DependentTaskTracker dependentTaskTracker;
+ private final long checkIntervalNanos;
+
+ private final LongSupplier nanoTimeSupplier;
+
+ private Long lastCheckTimeNanos;
+
public DependentLogicTask(TaskExecutionContext taskExecutionContext,
ProjectDao projectDao,
WorkflowDefinitionDao workflowDefinitionDao,
@@ -51,8 +63,26 @@ public class DependentLogicTask extends AbstractLogicTask<DependentParameters> {
WorkflowInstanceDao workflowInstanceDao,
IWorkflowExecution workflowExecution,
TaskInstanceContextDao taskInstanceContextDao) {
+ this(taskExecutionContext, projectDao, workflowDefinitionDao, taskDefinitionDao, taskInstanceDao,
+ workflowInstanceDao, workflowExecution, taskInstanceContextDao, System::nanoTime);
+ }
+
+ @VisibleForTesting
+ DependentLogicTask(TaskExecutionContext taskExecutionContext,
+ ProjectDao projectDao,
+ WorkflowDefinitionDao workflowDefinitionDao,
+ TaskDefinitionDao taskDefinitionDao,
+ TaskInstanceDao taskInstanceDao,
+ WorkflowInstanceDao workflowInstanceDao,
+ IWorkflowExecution workflowExecution,
+ TaskInstanceContextDao taskInstanceContextDao,
+ LongSupplier nanoTimeSupplier) {
super(taskExecutionContext);
this.taskExecutionContext = taskExecutionContext;
+ this.nanoTimeSupplier = nanoTimeSupplier;
+ final Integer checkInterval = taskParameters.getDependence().getCheckInterval();
+ this.checkIntervalNanos = TimeUnit.SECONDS.toNanos(
+ checkInterval == null ? DEFAULT_CHECK_INTERVAL_SECONDS : checkInterval);
this.dependentTaskTracker = new DependentTaskTracker(
taskExecutionContext,
taskParameters,
@@ -72,22 +102,39 @@ public class DependentLogicTask extends AbstractLogicTask<DependentParameters> {
@Override
public TaskExecutionStatus getTaskExecutionState() {
- if (isRunning()) {
- taskExecutionStatus = dependentTaskTracker.getDependentTaskStatus();
+ synchronized (this) {
+ if (!isRunning()) {
+ return taskExecutionStatus;
+ }
+ final long now = nanoTimeSupplier.getAsLong();
+ if (lastCheckTimeNanos != null && now - lastCheckTimeNanos < checkIntervalNanos) {
+ return taskExecutionStatus;
+ }
+ lastCheckTimeNanos = now;
+ }
+ final TaskExecutionStatus dependentState = dependentTaskTracker.getDependentTaskStatus();
+ synchronized (this) {
+ // A pause or kill may have completed while the dependency query was running.
+ if (isRunning()) {
+ taskExecutionStatus = dependentState;
+ }
return taskExecutionStatus;
}
- return taskExecutionStatus;
}
@Override
public void pause() throws MasterTaskExecuteException {
- onTaskPaused();
+ synchronized (this) {
+ onTaskPaused();
+ }
log.info("Pause task : {} success", taskExecutionContext.getTaskName());
}
@Override
public void kill() throws MasterTaskExecuteException {
- onTaskKilled();
+ synchronized (this) {
+ onTaskKilled();
+ }
log.info("Kill task : {} success", taskExecutionContext.getTaskName());
}
diff --git a/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/engine/executor/LogicTaskExecutorTest.java b/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/engine/executor/LogicTaskExecutorTest.java
new file mode 100644
index 0000000000..131ca9ac44
--- /dev/null
+++ b/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/engine/executor/LogicTaskExecutorTest.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.server.master.engine.executor;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockConstruction;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import org.apache.dolphinscheduler.common.enums.Flag;
+import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
+import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus;
+import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters;
+import org.apache.dolphinscheduler.server.master.engine.executor.plugin.ILogicTask;
+import org.apache.dolphinscheduler.server.master.engine.executor.plugin.ILogicTaskPluginFactory;
+import org.apache.dolphinscheduler.server.master.engine.executor.plugin.LogicTaskPluginFactoryBuilder;
+import org.apache.dolphinscheduler.server.master.engine.executor.plugin.dependent.DependentLogicTask;
+import org.apache.dolphinscheduler.server.master.engine.executor.plugin.dependent.DependentTaskTracker;
+import org.apache.dolphinscheduler.task.executor.TaskExecutorState;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullSource;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.MockedConstruction;
+
+class LogicTaskExecutorTest {
+
+ private static final long FRAMEWORK_CHECK_INTERVAL_MILLIS = TimeUnit.SECONDS.toMillis(10);
+
+ private MockedConstruction<DependentTaskTracker> dependentTaskTrackers;
+
+ @BeforeEach
+ void setUp() {
+ dependentTaskTrackers = mockConstruction(DependentTaskTracker.class,
+ (tracker, context) -> when(tracker.getDependentTaskStatus())
+ .thenReturn(TaskExecutionStatus.RUNNING_EXECUTION));
+ }
+
+ @AfterEach
+ void tearDown() {
+ dependentTaskTrackers.close();
+ }
+
+ @ParameterizedTest
+ @NullSource
+ @ValueSource(ints = {1, 5, 10, 20})
+ void frameworkUsesFixedCheckInterval(Integer checkInterval) throws Exception {
+ LogicTaskExecutor taskExecutor = createDependentTaskExecutor(checkInterval);
+
+ assertThat(taskExecutor.getRemainingTrackDelay()).isZero();
+ long beforeTrack = System.currentTimeMillis();
+ assertThat(taskExecutor.trackTaskExecutorState()).isEqualTo(TaskExecutorState.RUNNING);
+ long remainingDelay = taskExecutor.getRemainingTrackDelay();
+ long afterTrack = System.currentTimeMillis();
+
+ assertThat(remainingDelay).isBetween(
+ FRAMEWORK_CHECK_INTERVAL_MILLIS - (afterTrack - beforeTrack), FRAMEWORK_CHECK_INTERVAL_MILLIS);
+ verify(dependentTaskTrackers.constructed().get(0)).getDependentTaskStatus();
+ }
+
+ @Test
+ void pauseIsReportedOnNextFrameworkCheck() throws Exception {
+ LogicTaskExecutor taskExecutor = createDependentTaskExecutor(20);
+ taskExecutor.trackTaskExecutorState();
+
+ taskExecutor.pause();
+
+ assertThat(taskExecutor.getRemainingTrackDelay()).isPositive()
+ .isLessThanOrEqualTo(FRAMEWORK_CHECK_INTERVAL_MILLIS);
+ assertThat(taskExecutor.trackTaskExecutorState()).isEqualTo(TaskExecutorState.PAUSED);
+ DependentTaskTracker tracker = dependentTaskTrackers.constructed().get(0);
+ verify(tracker).getDependentTaskStatus();
+ verifyNoMoreInteractions(tracker);
+ }
+
+ @Test
+ void killIsReportedOnNextFrameworkCheck() throws Exception {
+ LogicTaskExecutor taskExecutor = createDependentTaskExecutor(20);
+ taskExecutor.trackTaskExecutorState();
+
+ taskExecutor.kill();
+
+ assertThat(taskExecutor.getRemainingTrackDelay()).isPositive()
+ .isLessThanOrEqualTo(FRAMEWORK_CHECK_INTERVAL_MILLIS);
+ assertThat(taskExecutor.trackTaskExecutorState()).isEqualTo(TaskExecutorState.KILLED);
+ DependentTaskTracker tracker = dependentTaskTrackers.constructed().get(0);
+ verify(tracker).getDependentTaskStatus();
+ verifyNoMoreInteractions(tracker);
+ }
+
+ private LogicTaskExecutor createDependentTaskExecutor(Integer checkInterval) throws Exception {
+ TaskExecutionContext taskExecutionContext = new TaskExecutionContext();
+ taskExecutionContext.setTaskType("DEPENDENT");
+ taskExecutionContext.setTaskName("dependent");
+ taskExecutionContext.setDryRun(Flag.NO.getCode());
+ taskExecutionContext.setTaskParams(checkInterval == null ? "{\"dependence\":{}}"
+ : "{\"dependence\":{\"checkInterval\":" + checkInterval + "}}");
+
+ return createTaskExecutor(taskExecutionContext, new DependentLogicTask(
+ taskExecutionContext, null, null, null, null, null, null, null));
+ }
+
+ @SuppressWarnings("unchecked")
+ private LogicTaskExecutor createTaskExecutor(TaskExecutionContext taskExecutionContext,
+ ILogicTask<? extends AbstractParameters> logicTask) throws Exception {
+ ILogicTaskPluginFactory<? extends ILogicTask<? extends AbstractParameters>> taskPluginFactory =
+ mock(ILogicTaskPluginFactory.class);
+ when(taskPluginFactory.getTaskType()).thenReturn(taskExecutionContext.getTaskType());
+ when(taskPluginFactory.createLogicTask(any())).thenAnswer(invocation -> logicTask);
+ List<ILogicTaskPluginFactory<? extends ILogicTask<? extends AbstractParameters>>> taskPluginFactories =
+ new ArrayList<>();
+ taskPluginFactories.add(taskPluginFactory);
+ LogicTaskExecutor taskExecutor = new LogicTaskExecutor(LogicTaskExecutorBuilder.builder()
+ .taskExecutionContext(taskExecutionContext)
+ .logicTaskPluginFactoryBuilder(new LogicTaskPluginFactoryBuilder(taskPluginFactories))
+ .build());
+ taskExecutor.start();
+ return taskExecutor;
+ }
+}
diff --git a/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/engine/executor/plugin/dependent/DependentLogicTaskTest.java b/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/engine/executor/plugin/dependent/DependentLogicTaskTest.java
new file mode 100644
index 0000000000..46bcca16bf
--- /dev/null
+++ b/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/engine/executor/plugin/dependent/DependentLogicTaskTest.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.server.master.engine.executor.plugin.dependent;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mockConstruction;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
+import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.mockito.MockedConstruction;
+
+class DependentLogicTaskTest {
+
+ private static final int ASYNC_TEST_TIMEOUT_SECONDS = 5;
+
+ private final AtomicLong currentTimeNanos = new AtomicLong();
+
+ private MockedConstruction<DependentTaskTracker> dependentTaskTrackers;
+
+ @BeforeEach
+ void setUp() {
+ dependentTaskTrackers = mockConstruction(DependentTaskTracker.class,
+ (tracker, context) -> when(tracker.getDependentTaskStatus())
+ .thenReturn(TaskExecutionStatus.RUNNING_EXECUTION));
+ }
+
+ @AfterEach
+ void tearDown() {
+ dependentTaskTrackers.close();
+ }
+
+ @ParameterizedTest
+ @CsvSource(value = {"null, 10", "1, 1", "5, 5", "10, 10", "20, 20"}, nullValues = "null")
+ void dependencyQueriesUseConfiguredInterval(Integer checkInterval, long expectedIntervalSeconds) {
+ DependentLogicTask logicTask = createDependentLogicTask(checkInterval);
+ DependentTaskTracker tracker = dependentTaskTrackers.constructed().get(0);
+ when(tracker.getDependentTaskStatus())
+ .thenReturn(TaskExecutionStatus.RUNNING_EXECUTION, TaskExecutionStatus.SUCCESS);
+
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(TaskExecutionStatus.RUNNING_EXECUTION);
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(TaskExecutionStatus.RUNNING_EXECUTION);
+
+ long expectedIntervalNanos = TimeUnit.SECONDS.toNanos(expectedIntervalSeconds);
+ currentTimeNanos.set(expectedIntervalNanos - 1);
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(TaskExecutionStatus.RUNNING_EXECUTION);
+ verify(tracker).getDependentTaskStatus();
+
+ currentTimeNanos.set(expectedIntervalNanos);
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(TaskExecutionStatus.SUCCESS);
+ verify(tracker, times(2)).getDependentTaskStatus();
+ verifyNoMoreInteractions(tracker);
+ }
+
+ @ParameterizedTest
+ @CsvSource({"10, 2, 3", "15, 1, 2", "20, 1, 2"})
+ void frameworkChecksReturnCachedStateUntilQueryIsDue(int checkInterval, int queriesAtTenSeconds,
+ int queriesAtTwentySeconds) {
+ DependentLogicTask logicTask = createDependentLogicTask(checkInterval);
+ DependentTaskTracker tracker = dependentTaskTrackers.constructed().get(0);
+
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(TaskExecutionStatus.RUNNING_EXECUTION);
+ verify(tracker).getDependentTaskStatus();
+
+ currentTimeNanos.set(TimeUnit.SECONDS.toNanos(10));
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(TaskExecutionStatus.RUNNING_EXECUTION);
+ verify(tracker, times(queriesAtTenSeconds)).getDependentTaskStatus();
+
+ currentTimeNanos.set(TimeUnit.SECONDS.toNanos(20));
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(TaskExecutionStatus.RUNNING_EXECUTION);
+ verify(tracker, times(queriesAtTwentySeconds)).getDependentTaskStatus();
+ verifyNoMoreInteractions(tracker);
+ }
+
+ @ParameterizedTest
+ @EnumSource(value = TaskExecutionStatus.class, names = {"PAUSE", "KILL"})
+ void controlStateIsReturnedBeforeNextDependencyQuery(TaskExecutionStatus controlState) throws Exception {
+ DependentLogicTask logicTask = createDependentLogicTask(20);
+ DependentTaskTracker tracker = dependentTaskTrackers.constructed().get(0);
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(TaskExecutionStatus.RUNNING_EXECUTION);
+
+ currentTimeNanos.set(TimeUnit.SECONDS.toNanos(10));
+ controlTask(logicTask, controlState);
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(controlState);
+
+ currentTimeNanos.set(TimeUnit.SECONDS.toNanos(40));
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(controlState);
+ verify(tracker).getDependentTaskStatus();
+ verifyNoMoreInteractions(tracker);
+ }
+
+ @ParameterizedTest
+ @EnumSource(value = TaskExecutionStatus.class, names = {"SUCCESS", "FAILURE"})
+ void finishedTaskDoesNotQueryDependenciesAgain(TaskExecutionStatus finalState) {
+ DependentLogicTask logicTask = createDependentLogicTask(20);
+ DependentTaskTracker tracker = dependentTaskTrackers.constructed().get(0);
+ when(tracker.getDependentTaskStatus()).thenReturn(finalState);
+
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(finalState);
+ currentTimeNanos.set(TimeUnit.SECONDS.toNanos(20));
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(finalState);
+ verify(tracker).getDependentTaskStatus();
+ verifyNoMoreInteractions(tracker);
+ }
+
+ @ParameterizedTest
+ @CsvSource({"PAUSE, RUNNING_EXECUTION", "PAUSE, SUCCESS", "PAUSE, FAILURE",
+ "KILL, RUNNING_EXECUTION", "KILL, SUCCESS", "KILL, FAILURE"})
+ void dependentCheckDoesNotOverwriteConcurrentControlState(TaskExecutionStatus expectedState,
+ TaskExecutionStatus dependentState) throws Exception {
+ DependentLogicTask logicTask = createDependentLogicTask(20);
+ DependentTaskTracker tracker = dependentTaskTrackers.constructed().get(0);
+ CountDownLatch checkStarted = new CountDownLatch(1);
+ CountDownLatch finishCheck = new CountDownLatch(1);
+ when(tracker.getDependentTaskStatus()).thenAnswer(invocation -> {
+ checkStarted.countDown();
+ assertThat(finishCheck.await(ASYNC_TEST_TIMEOUT_SECONDS, TimeUnit.SECONDS)).isTrue();
+ return dependentState;
+ });
+
+ ExecutorService stateTracker = Executors.newSingleThreadExecutor();
+ try {
+ Future<TaskExecutionStatus> trackedState = stateTracker.submit(logicTask::getTaskExecutionState);
+ assertThat(checkStarted.await(ASYNC_TEST_TIMEOUT_SECONDS, TimeUnit.SECONDS)).isTrue();
+
+ controlTask(logicTask, expectedState);
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(expectedState);
+ finishCheck.countDown();
+
+ assertThat(trackedState.get(ASYNC_TEST_TIMEOUT_SECONDS, TimeUnit.SECONDS)).isEqualTo(expectedState);
+ assertThat(logicTask.getTaskExecutionState()).isEqualTo(expectedState);
+ verify(tracker).getDependentTaskStatus();
+ verifyNoMoreInteractions(tracker);
+ } finally {
+ finishCheck.countDown();
+ stateTracker.shutdownNow();
+ assertThat(stateTracker.awaitTermination(ASYNC_TEST_TIMEOUT_SECONDS, TimeUnit.SECONDS)).isTrue();
+ }
+ }
+
+ private void controlTask(DependentLogicTask logicTask, TaskExecutionStatus controlState) throws Exception {
+ if (controlState == TaskExecutionStatus.PAUSE) {
+ logicTask.pause();
+ } else {
+ logicTask.kill();
+ }
+ }
+
+ private DependentLogicTask createDependentLogicTask(Integer checkInterval) {
+ TaskExecutionContext taskExecutionContext = new TaskExecutionContext();
+ taskExecutionContext.setTaskName("dependent");
+ taskExecutionContext.setTaskParams(checkInterval == null ? "{\"dependence\":{}}"
+ : "{\"dependence\":{\"checkInterval\":" + checkInterval + "}}");
+
+ return new DependentLogicTask(taskExecutionContext, null, null, null, null, null, null, null,
+ currentTimeNanos::get);
+ }
+}