Skip to content

Commit 0106813

Browse files
committed
Create worker deployment based versioning sample
1 parent 0dbfe22 commit 0106813

16 files changed

+606
-2
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ target
1717
.project
1818
.settings/
1919
bin/
20-
core/.vscode/
20+
core/.vscode/
21+
.claude/

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ See the README.md file in each main sample directory for cut/paste Gradle comman
108108

109109
- [**Custom Annotation**](/core/src/main/java/io/temporal/samples/customannotation): Demonstrates how to create a custom annotation using an interceptor.
110110

111-
- [**Asnyc Packet Delivery**](/core/src/main/java/io/temporal/samples/packetdelivery): Demonstrates running multiple execution paths async within single execution.
111+
- [**Async Packet Delivery**](/core/src/main/java/io/temporal/samples/packetdelivery): Demonstrates running multiple execution paths async within single execution.
112112

113+
- [**Worker Versioning**](/core/src/main/java/io/temporal/samples/workerversioning): Demonstrates how to use worker versioning to manage workflow code changes.
113114

114115
#### API demonstrations
115116

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.temporal.samples.workerversioning;
2+
3+
import io.temporal.activity.ActivityInterface;
4+
import io.temporal.activity.ActivityMethod;
5+
6+
@ActivityInterface
7+
public interface Activities {
8+
9+
@ActivityMethod
10+
String someActivity(String calledBy);
11+
12+
@ActivityMethod
13+
String someIncompatibleActivity(IncompatibleActivityInput input);
14+
15+
class IncompatibleActivityInput {
16+
String calledBy;
17+
String moreData;
18+
19+
public IncompatibleActivityInput() {}
20+
21+
public IncompatibleActivityInput(String calledBy, String moreData) {
22+
this.calledBy = calledBy;
23+
this.moreData = moreData;
24+
}
25+
26+
public String getCalledBy() {
27+
return calledBy;
28+
}
29+
30+
public String getMoreData() {
31+
return moreData;
32+
}
33+
34+
public void setCalledBy(String calledBy) {
35+
this.calledBy = calledBy;
36+
}
37+
38+
public void setMoreData(String moreData) {
39+
this.moreData = moreData;
40+
}
41+
}
42+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.temporal.samples.workerversioning;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
public class ActivitiesImpl implements Activities {
7+
8+
private static final Logger logger = LoggerFactory.getLogger(ActivitiesImpl.class);
9+
10+
@Override
11+
public String someActivity(String calledBy) {
12+
logger.info("SomeActivity called by {}", calledBy);
13+
return "SomeActivity called by " + calledBy;
14+
}
15+
16+
@Override
17+
public String someIncompatibleActivity(IncompatibleActivityInput input) {
18+
logger.info(
19+
"SomeIncompatibleActivity called by {} with {}", input.getCalledBy(), input.getMoreData());
20+
return "SomeIncompatibleActivity called by "
21+
+ input.getCalledBy()
22+
+ " with "
23+
+ input.getMoreData();
24+
}
25+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.temporal.samples.workerversioning;
2+
3+
import io.temporal.workflow.SignalMethod;
4+
import io.temporal.workflow.WorkflowInterface;
5+
import io.temporal.workflow.WorkflowMethod;
6+
7+
@WorkflowInterface
8+
public interface AutoUpgradingWorkflow {
9+
10+
@WorkflowMethod
11+
void run();
12+
13+
@SignalMethod
14+
void doNextSignal(String signal);
15+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package io.temporal.samples.workerversioning;
2+
3+
import io.temporal.activity.ActivityOptions;
4+
import io.temporal.common.VersioningBehavior;
5+
import io.temporal.workflow.Workflow;
6+
import io.temporal.workflow.WorkflowVersioningBehavior;
7+
import java.time.Duration;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import org.slf4j.Logger;
11+
12+
public class AutoUpgradingWorkflowV1Impl implements AutoUpgradingWorkflow {
13+
14+
private static final Logger logger = Workflow.getLogger(AutoUpgradingWorkflowV1Impl.class);
15+
16+
private final List<String> signals = new ArrayList<>();
17+
private final Activities activities =
18+
Workflow.newActivityStub(
19+
Activities.class,
20+
ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build());
21+
22+
@Override
23+
@WorkflowVersioningBehavior(VersioningBehavior.AUTO_UPGRADE)
24+
public void run() {
25+
logger.info("Changing workflow v1 started. StartTime: {}", Workflow.currentTimeMillis());
26+
27+
// This workflow will listen for signals from our starter, and upon each signal either run
28+
// an activity, or conclude execution.
29+
while (true) {
30+
Workflow.await(() -> !signals.isEmpty());
31+
String signal = signals.remove(0);
32+
33+
if ("do-activity".equals(signal)) {
34+
logger.info("Changing workflow v1 running activity");
35+
activities.someActivity("v1");
36+
} else {
37+
logger.info("Concluding workflow v1");
38+
return;
39+
}
40+
}
41+
}
42+
43+
@Override
44+
public void doNextSignal(String signal) {
45+
signals.add(signal);
46+
}
47+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package io.temporal.samples.workerversioning;
2+
3+
import io.temporal.activity.ActivityOptions;
4+
import io.temporal.common.VersioningBehavior;
5+
import io.temporal.workflow.Workflow;
6+
import io.temporal.workflow.WorkflowVersioningBehavior;
7+
import java.time.Duration;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import org.slf4j.Logger;
11+
12+
public class AutoUpgradingWorkflowV1bImpl implements AutoUpgradingWorkflow {
13+
14+
private static final Logger logger = Workflow.getLogger(AutoUpgradingWorkflowV1bImpl.class);
15+
16+
private final List<String> signals = new ArrayList<>();
17+
private final Activities activities =
18+
Workflow.newActivityStub(
19+
Activities.class,
20+
ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build());
21+
22+
@Override
23+
@WorkflowVersioningBehavior(VersioningBehavior.AUTO_UPGRADE)
24+
public void run() {
25+
logger.info("Changing workflow v1b started. StartTime: {}", Workflow.currentTimeMillis());
26+
27+
// This workflow will listen for signals from our starter, and upon each signal either run
28+
// an activity, or conclude execution.
29+
while (true) {
30+
Workflow.await(() -> !signals.isEmpty());
31+
String signal = signals.remove(0);
32+
33+
if ("do-activity".equals(signal)) {
34+
logger.info("Changing workflow v1b running activity");
35+
int version = Workflow.getVersion("DifferentActivity", Workflow.DEFAULT_VERSION, 1);
36+
if (version == 1) {
37+
activities.someIncompatibleActivity(
38+
new Activities.IncompatibleActivityInput("v1b", "hello!"));
39+
} else {
40+
// Note it is a valid compatible change to alter the input to an activity.
41+
// However, because we're using the getVersion API, this branch will never be
42+
// taken.
43+
activities.someActivity("v1b");
44+
}
45+
} else {
46+
logger.info("Concluding workflow v1b");
47+
break;
48+
}
49+
}
50+
}
51+
52+
@Override
53+
public void doNextSignal(String signal) {
54+
signals.add(signal);
55+
}
56+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.temporal.samples.workerversioning;
2+
3+
public final class Constants {
4+
public static final String TASK_QUEUE = "worker-versioning";
5+
public static final String DEPLOYMENT_NAME = "my-deployment";
6+
7+
private Constants() {
8+
// Utility class
9+
}
10+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.temporal.samples.workerversioning;
2+
3+
import io.temporal.workflow.SignalMethod;
4+
import io.temporal.workflow.WorkflowInterface;
5+
import io.temporal.workflow.WorkflowMethod;
6+
7+
@WorkflowInterface
8+
public interface PinnedWorkflow {
9+
10+
@WorkflowMethod
11+
void run();
12+
13+
@SignalMethod
14+
void doNextSignal(String signal);
15+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.temporal.samples.workerversioning;
2+
3+
import io.temporal.activity.ActivityOptions;
4+
import io.temporal.common.VersioningBehavior;
5+
import io.temporal.workflow.Workflow;
6+
import io.temporal.workflow.WorkflowVersioningBehavior;
7+
import java.time.Duration;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import org.slf4j.Logger;
11+
12+
public class PinnedWorkflowV1Impl implements PinnedWorkflow {
13+
14+
private static final Logger logger = Workflow.getLogger(PinnedWorkflowV1Impl.class);
15+
16+
private final List<String> signals = new ArrayList<>();
17+
private final Activities activities =
18+
Workflow.newActivityStub(
19+
Activities.class,
20+
ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build());
21+
22+
@Override
23+
@WorkflowVersioningBehavior(VersioningBehavior.PINNED)
24+
public void run() {
25+
logger.info("Pinned Workflow v1 started. StartTime: {}", Workflow.currentTimeMillis());
26+
27+
while (true) {
28+
Workflow.await(() -> !signals.isEmpty());
29+
String signal = signals.remove(0);
30+
if ("conclude".equals(signal)) {
31+
break;
32+
}
33+
}
34+
35+
activities.someActivity("Pinned-v1");
36+
}
37+
38+
@Override
39+
public void doNextSignal(String signal) {
40+
signals.add(signal);
41+
}
42+
}

0 commit comments

Comments
 (0)