Search in sources :

Example 1 with Promise

use of com.uber.cadence.workflow.Promise in project cadence-client by uber-java.

the class DeterministicRunnerTest method workflowThreadsWillEvictCacheWhenMaxThreadCountIsHit.

@Test
public void workflowThreadsWillEvictCacheWhenMaxThreadCountIsHit() throws Throwable {
    // Arrange
    // Arrange
    Map<String, String> tags = new ImmutableMap.Builder<String, String>(2).put(MetricsTag.DOMAIN, "domain").put(MetricsTag.TASK_LIST, "stickyTaskList").build();
    StatsReporter reporter = mock(StatsReporter.class);
    Scope scope = new RootScopeBuilder().reporter(reporter).reportEvery(com.uber.m3.util.Duration.ofMillis(300)).tagged(tags);
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 3, 1, TimeUnit.SECONDS, new SynchronousQueue<>());
    AtomicReference<String> status = new AtomicReference<>();
    DeciderCache cache = new DeciderCache(3, scope);
    DecisionContext decisionContext = mock(DecisionContext.class);
    when(decisionContext.getMetricsScope()).thenReturn(scope);
    when(decisionContext.getDomain()).thenReturn("domain");
    when(decisionContext.getWorkflowType()).thenReturn(new WorkflowType());
    DeterministicRunnerImpl d = new DeterministicRunnerImpl(threadPool, new SyncDecisionContext(decisionContext, JsonDataConverter.getInstance(), null, next -> next, null), // clock override
    () -> 0L, () -> {
        Promise<Void> thread = Async.procedure(() -> {
            status.set("started");
            WorkflowThread.await("doing something", () -> false);
            status.set("done");
        });
        thread.get();
    }, cache);
    Decider decider = new DetermisiticRunnerContainerDecider(d);
    PollForDecisionTaskResponse response = HistoryUtils.generateDecisionTaskWithInitialHistory();
    cache.getOrCreate(response, () -> decider);
    cache.addToCache(response, decider);
    d.runUntilAllBlocked();
    assertEquals(2, threadPool.getActiveCount());
    DeterministicRunnerImpl d2 = new DeterministicRunnerImpl(threadPool, new SyncDecisionContext(decisionContext, JsonDataConverter.getInstance(), null, next -> next, null), // clock override
    () -> 0L, () -> {
        Promise<Void> thread = Async.procedure(() -> {
            status.set("started");
            WorkflowThread.await("doing something else", () -> false);
            status.set("done");
        });
        thread.get();
    }, cache);
    // Root thread added for d2 therefore we expect a total of 3 threads used
    assertEquals(3, threadPool.getActiveCount());
    assertEquals(1, cache.size());
    // Act: This should kick out threads consumed by 'd'
    d2.runUntilAllBlocked();
    // Assert: Cache is evicted and only threads consumed by d2 remain.
    assertEquals(2, threadPool.getActiveCount());
    // cache was evicted
    assertEquals(0, cache.size());
    // Wait for reporter
    Thread.sleep(600);
    verify(reporter, atLeastOnce()).reportCounter(eq(MetricsType.STICKY_CACHE_THREAD_FORCED_EVICTION), eq(tags), anyInt());
}
Also used : MetricsType(com.uber.cadence.internal.metrics.MetricsType) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) JsonDataConverter(com.uber.cadence.converter.JsonDataConverter) Promise(com.uber.cadence.workflow.Promise) DecisionContext(com.uber.cadence.internal.replay.DecisionContext) TimeoutException(java.util.concurrent.TimeoutException) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) Functions(com.uber.cadence.workflow.Functions) TestCase.assertNotNull(junit.framework.TestCase.assertNotNull) StatsReporter(com.uber.m3.tally.StatsReporter) WorkflowTest(com.uber.cadence.workflow.WorkflowTest) Duration(java.time.Duration) Map(java.util.Map) After(org.junit.After) WorkflowType(com.uber.cadence.WorkflowType) ExecutorService(java.util.concurrent.ExecutorService) Before(org.junit.Before) Workflow(com.uber.cadence.workflow.Workflow) MetricsTag(com.uber.cadence.internal.metrics.MetricsTag) CancellationScope(com.uber.cadence.workflow.CancellationScope) Scope(com.uber.m3.tally.Scope) CancellationException(java.util.concurrent.CancellationException) SynchronousQueue(java.util.concurrent.SynchronousQueue) TestCase.fail(junit.framework.TestCase.fail) Decider(com.uber.cadence.internal.replay.Decider) Test(org.junit.Test) NoopScope(com.uber.cadence.internal.metrics.NoopScope) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) RetryOptions(com.uber.cadence.common.RetryOptions) PollForDecisionTaskResponse(com.uber.cadence.PollForDecisionTaskResponse) Async(com.uber.cadence.workflow.Async) List(java.util.List) Rule(org.junit.Rule) TestCase.assertTrue(junit.framework.TestCase.assertTrue) CompletablePromise(com.uber.cadence.workflow.CompletablePromise) Assert.assertFalse(org.junit.Assert.assertFalse) RootScopeBuilder(com.uber.m3.tally.RootScopeBuilder) WorkflowQuery(com.uber.cadence.WorkflowQuery) HistoryUtils(com.uber.cadence.testUtils.HistoryUtils) DeciderCache(com.uber.cadence.internal.replay.DeciderCache) TestCase.assertEquals(junit.framework.TestCase.assertEquals) ImmutableMap(com.uber.m3.util.ImmutableMap) RootScopeBuilder(com.uber.m3.tally.RootScopeBuilder) AtomicReference(java.util.concurrent.atomic.AtomicReference) PollForDecisionTaskResponse(com.uber.cadence.PollForDecisionTaskResponse) DeciderCache(com.uber.cadence.internal.replay.DeciderCache) StatsReporter(com.uber.m3.tally.StatsReporter) ImmutableMap(com.uber.m3.util.ImmutableMap) Decider(com.uber.cadence.internal.replay.Decider) CancellationScope(com.uber.cadence.workflow.CancellationScope) Scope(com.uber.m3.tally.Scope) NoopScope(com.uber.cadence.internal.metrics.NoopScope) WorkflowType(com.uber.cadence.WorkflowType) DecisionContext(com.uber.cadence.internal.replay.DecisionContext) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) WorkflowTest(com.uber.cadence.workflow.WorkflowTest) Test(org.junit.Test)

Example 2 with Promise

use of com.uber.cadence.workflow.Promise in project cadence-client by uber-java.

the class WorkflowRetryerInternal method retryAsync.

private static <R> Promise<R> retryAsync(String retryId, RetryOptions options, Functions.Func<Promise<R>> func, long startTime, long attempt) {
    options.validate();
    RetryOptions retryOptions = WorkflowInternal.mutableSideEffect(retryId, RetryOptions.class, RetryOptions.class, Object::equals, () -> options);
    CompletablePromise<R> funcResult = WorkflowInternal.newCompletablePromise();
    try {
        funcResult.completeFrom(func.apply());
    } catch (RuntimeException e) {
        funcResult.completeExceptionally(e);
    }
    return funcResult.handle((r, e) -> {
        if (e == null) {
            return WorkflowInternal.newPromise(r);
        }
        long elapsed = WorkflowInternal.currentTimeMillis() - startTime;
        long sleepTime = retryOptions.calculateSleepTime(attempt);
        if (retryOptions.shouldRethrow(e, attempt, elapsed, sleepTime)) {
            throw e;
        }
        // recursion.
        return WorkflowInternal.newTimer(Duration.ofMillis(sleepTime)).thenCompose((nil) -> retryAsync(retryId, retryOptions, func, startTime, attempt + 1));
    }).thenCompose((r) -> r);
}
Also used : Workflow(com.uber.cadence.workflow.Workflow) RetryOptions(com.uber.cadence.common.RetryOptions) Functions(com.uber.cadence.workflow.Functions) CompletablePromise(com.uber.cadence.workflow.CompletablePromise) Promise(com.uber.cadence.workflow.Promise) Duration(java.time.Duration) ActivityFailureException(com.uber.cadence.workflow.ActivityFailureException) RetryOptions(com.uber.cadence.common.RetryOptions)

Example 3 with Promise

use of com.uber.cadence.workflow.Promise in project cadence-client by uber-java.

the class DeterministicRunnerImpl method close.

@Override
public void close() {
    List<Future<?>> threadFutures = new ArrayList<>();
    lock.lock();
    if (closed) {
        lock.unlock();
        return;
    }
    // Do not close while runUntilAllBlocked executes.
    // closeRequested tells it to call close() at the end.
    closeRequested = true;
    if (inRunUntilAllBlocked) {
        lock.unlock();
        return;
    }
    try {
        for (WorkflowThread c : threadsToAdd) {
            threads.addLast(c);
        }
        threadsToAdd.clear();
        for (WorkflowThread c : threads) {
            threadFutures.add(c.stopNow());
        }
        threads.clear();
        // We cannot use an iterator to unregister failed Promises since f.get()
        // will remove the promise directly from failedPromises. This causes an
        // ConcurrentModificationException
        // For this reason we will loop over a copy of failedPromises.
        Set<Promise> failedPromisesLoop = new HashSet<>(failedPromises);
        for (Promise f : failedPromisesLoop) {
            if (!f.isCompleted()) {
                throw new Error("expected failed");
            }
            try {
                f.get();
                throw new Error("unreachable");
            } catch (RuntimeException e) {
                log.warn("Promise that was completedExceptionally was never accessed. " + "The ignored exception:", CheckedExceptionWrapper.unwrap(e));
            }
        }
    } finally {
        closed = true;
        lock.unlock();
    }
    // these tasks use the same lock to execute.
    for (Future<?> future : threadFutures) {
        try {
            future.get();
        } catch (InterruptedException e) {
            throw new Error("Unexpected interrupt", e);
        } catch (ExecutionException e) {
            throw new Error("Unexpected failure stopping coroutine", e);
        }
    }
}
Also used : Promise(com.uber.cadence.workflow.Promise) ArrayList(java.util.ArrayList) Future(java.util.concurrent.Future) ExecutionException(java.util.concurrent.ExecutionException) HashSet(java.util.HashSet)

Aggregations

Promise (com.uber.cadence.workflow.Promise)3 RetryOptions (com.uber.cadence.common.RetryOptions)2 CompletablePromise (com.uber.cadence.workflow.CompletablePromise)2 Functions (com.uber.cadence.workflow.Functions)2 Workflow (com.uber.cadence.workflow.Workflow)2 Duration (java.time.Duration)2 ArrayList (java.util.ArrayList)2 PollForDecisionTaskResponse (com.uber.cadence.PollForDecisionTaskResponse)1 WorkflowQuery (com.uber.cadence.WorkflowQuery)1 WorkflowType (com.uber.cadence.WorkflowType)1 JsonDataConverter (com.uber.cadence.converter.JsonDataConverter)1 MetricsTag (com.uber.cadence.internal.metrics.MetricsTag)1 MetricsType (com.uber.cadence.internal.metrics.MetricsType)1 NoopScope (com.uber.cadence.internal.metrics.NoopScope)1 Decider (com.uber.cadence.internal.replay.Decider)1 DeciderCache (com.uber.cadence.internal.replay.DeciderCache)1 DecisionContext (com.uber.cadence.internal.replay.DecisionContext)1 HistoryUtils (com.uber.cadence.testUtils.HistoryUtils)1 ActivityFailureException (com.uber.cadence.workflow.ActivityFailureException)1 Async (com.uber.cadence.workflow.Async)1