Skip to content

Commit 2807771

Browse files
Warn if root thread yields (#2483)
Warn if root thread yields
1 parent 620eeaf commit 2807771

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

temporal-sdk/src/main/java/io/temporal/internal/sync/DeterministicRunnerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ private WorkflowThread newRootThread(Runnable runnable) {
449449
"newRootThread can be called only if there is no existing root workflow thread");
450450
}
451451
rootWorkflowThread =
452-
new WorkflowThreadImpl(
452+
new RootWorkflowThreadImpl(
453453
workflowThreadExecutor,
454454
workflowContext,
455455
this,
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
3+
*
4+
* Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this material except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
package io.temporal.internal.sync;
22+
23+
import io.temporal.common.context.ContextPropagator;
24+
import io.temporal.internal.worker.WorkflowExecutorCache;
25+
import java.util.List;
26+
import java.util.Map;
27+
import java.util.function.Supplier;
28+
import javax.annotation.Nonnull;
29+
import org.slf4j.Logger;
30+
import org.slf4j.LoggerFactory;
31+
32+
public class RootWorkflowThreadImpl extends WorkflowThreadImpl {
33+
private static final Logger log = LoggerFactory.getLogger(RootWorkflowThreadImpl.class);
34+
35+
RootWorkflowThreadImpl(
36+
WorkflowThreadExecutor workflowThreadExecutor,
37+
SyncWorkflowContext syncWorkflowContext,
38+
DeterministicRunnerImpl runner,
39+
@Nonnull String name,
40+
int priority,
41+
boolean detached,
42+
CancellationScopeImpl parentCancellationScope,
43+
Runnable runnable,
44+
WorkflowExecutorCache cache,
45+
List<ContextPropagator> contextPropagators,
46+
Map<String, Object> propagatedContexts) {
47+
super(
48+
workflowThreadExecutor,
49+
syncWorkflowContext,
50+
runner,
51+
name,
52+
priority,
53+
detached,
54+
parentCancellationScope,
55+
runnable,
56+
cache,
57+
contextPropagators,
58+
propagatedContexts);
59+
}
60+
61+
@Override
62+
public void yield(String reason, Supplier<Boolean> unblockCondition)
63+
throws DestroyWorkflowThreadError {
64+
log.warn(
65+
"Detected root workflow thread yielding {}. This can happen by making blocking calls during workflow instance creating, such as executing an activity inside a @WorkflowInit constructor. This can cause issues, like Queries or Updates rejection because the workflow instance creation is delayed",
66+
getName());
67+
super.yield(reason, unblockCondition);
68+
}
69+
}

temporal-sdk/src/main/java/io/temporal/workflow/WorkflowInit.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
* thrown by the constructor are treated the same as exceptions thrown by the workflow method.
3535
*
3636
* <p>Workflow initialization methods are called before the workflow method, signal handlers, update
37-
* handlers or query handlers.
37+
* handlers or query handlers. Users should be careful not to block in constructors. Blocking in the
38+
* constructor will delay handling of the workflow method and signal handlers, and cause rejection
39+
* of the update and query handlers.
3840
*
3941
* <p>This annotation applies only to workflow implementation constructors.
4042
*/

0 commit comments

Comments
 (0)