Skip to content

Commit 6771213

Browse files
committed
pull from latest
2 parents 75e6993 + c4d0cdb commit 6771213

File tree

23 files changed

+1024
-58
lines changed

23 files changed

+1024
-58
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
package com.function;
5+
6+
import com.microsoft.azure.functions.annotation.*;
7+
import com.microsoft.azure.functions.*;
8+
9+
import java.util.*;
10+
11+
import com.microsoft.durabletask.*;
12+
import com.microsoft.durabletask.azurefunctions.DurableActivityTrigger;
13+
import com.microsoft.durabletask.azurefunctions.DurableOrchestrationTrigger;
14+
15+
public class IsReplayingChecks {
16+
17+
@FunctionName("IsReplayingEcho")
18+
public String isReplayingEcho(
19+
@DurableActivityTrigger(name = "value") String value,
20+
final ExecutionContext context) {
21+
// Bug: https://github.com/microsoft/durabletask-java/issues/235
22+
if (value != null && value.length() >= 2 && value.startsWith("\"") && value.endsWith("\"")) {
23+
value = value.substring(1, value.length() - 1);
24+
}
25+
return value;
26+
}
27+
28+
@FunctionName("IsReplayingBasic")
29+
public Map<String, Object> isReplayingBasic(
30+
@DurableOrchestrationTrigger(name = "context") TaskOrchestrationContext ctx) {
31+
boolean before = ctx.getIsReplaying();
32+
String result = ctx.callActivity("IsReplayingEcho", "hello", String.class).await();
33+
boolean after = ctx.getIsReplaying();
34+
35+
Map<String, Object> output = new LinkedHashMap<>();
36+
output.put("before_activity", before);
37+
output.put("after_activity", after);
38+
output.put("activity_result", result);
39+
return output;
40+
}
41+
42+
@FunctionName("IsReplayingMultiActivity")
43+
public Map<String, Object> isReplayingMultiActivity(
44+
@DurableOrchestrationTrigger(name = "context") TaskOrchestrationContext ctx) {
45+
List<Map<String, Object>> snapshots = new ArrayList<>();
46+
47+
Map<String, Object> s0 = new LinkedHashMap<>();
48+
s0.put("step", 0);
49+
s0.put("label", "start");
50+
s0.put("is_replaying", ctx.getIsReplaying());
51+
snapshots.add(s0);
52+
53+
String r1 = ctx.callActivity("IsReplayingEcho", "one", String.class).await();
54+
55+
Map<String, Object> s1 = new LinkedHashMap<>();
56+
s1.put("step", 1);
57+
s1.put("label", "after_first");
58+
s1.put("is_replaying", ctx.getIsReplaying());
59+
snapshots.add(s1);
60+
61+
String r2 = ctx.callActivity("IsReplayingEcho", "two", String.class).await();
62+
63+
Map<String, Object> s2 = new LinkedHashMap<>();
64+
s2.put("step", 2);
65+
s2.put("label", "after_second");
66+
s2.put("is_replaying", ctx.getIsReplaying());
67+
snapshots.add(s2);
68+
69+
String r3 = ctx.callActivity("IsReplayingEcho", "three", String.class).await();
70+
71+
Map<String, Object> s3 = new LinkedHashMap<>();
72+
s3.put("step", 3);
73+
s3.put("label", "after_third");
74+
s3.put("is_replaying", ctx.getIsReplaying());
75+
snapshots.add(s3);
76+
77+
Map<String, Object> output = new LinkedHashMap<>();
78+
output.put("snapshots", snapshots);
79+
output.put("activities", Arrays.asList(r1, r2, r3));
80+
return output;
81+
}
82+
83+
@FunctionName("IsReplayingConditionalLog")
84+
public Map<String, Object> isReplayingConditionalLog(
85+
@DurableOrchestrationTrigger(name = "context") TaskOrchestrationContext ctx,
86+
final ExecutionContext executionContext) {
87+
int liveLogCount = 0;
88+
89+
if (!ctx.getIsReplaying()) {
90+
executionContext.getLogger().info("IsReplayingConditionalLog: LIVE before activity");
91+
liveLogCount++;
92+
} else {
93+
executionContext.getLogger().info("IsReplayingConditionalLog: REPLAY before activity");
94+
}
95+
96+
String result = ctx.callActivity("IsReplayingEcho", "logged", String.class).await();
97+
98+
if (!ctx.getIsReplaying()) {
99+
executionContext.getLogger().info("IsReplayingConditionalLog: LIVE after activity");
100+
liveLogCount++;
101+
} else {
102+
executionContext.getLogger().info("IsReplayingConditionalLog: REPLAY after activity");
103+
}
104+
105+
Map<String, Object> output = new LinkedHashMap<>();
106+
output.put("live_log_count", liveLogCount);
107+
output.put("activity_result", result);
108+
return output;
109+
}
110+
111+
@FunctionName("IsReplayingCounter")
112+
public Map<String, Object> isReplayingCounter(
113+
@DurableOrchestrationTrigger(name = "context") TaskOrchestrationContext ctx) {
114+
int nonReplayCount = 0;
115+
int replayCount = 0;
116+
117+
if (ctx.getIsReplaying()) { replayCount++; } else { nonReplayCount++; }
118+
119+
String r1 = ctx.callActivity("IsReplayingEcho", "a", String.class).await();
120+
if (ctx.getIsReplaying()) { replayCount++; } else { nonReplayCount++; }
121+
122+
String r2 = ctx.callActivity("IsReplayingEcho", "b", String.class).await();
123+
if (ctx.getIsReplaying()) { replayCount++; } else { nonReplayCount++; }
124+
125+
String r3 = ctx.callActivity("IsReplayingEcho", "c", String.class).await();
126+
if (ctx.getIsReplaying()) { replayCount++; } else { nonReplayCount++; }
127+
128+
Map<String, Object> output = new LinkedHashMap<>();
129+
output.put("non_replay_count", nonReplayCount);
130+
output.put("replay_count", replayCount);
131+
output.put("total_checkpoints", nonReplayCount + replayCount);
132+
output.put("activities", Arrays.asList(r1, r2, r3));
133+
return output;
134+
}
135+
136+
@FunctionName("IsReplayingFanOutFanIn")
137+
public Map<String, Object> isReplayingFanOutFanIn(
138+
@DurableOrchestrationTrigger(name = "context") TaskOrchestrationContext ctx) {
139+
boolean before = ctx.getIsReplaying();
140+
141+
Task<String> t1 = ctx.callActivity("IsReplayingEcho", "alpha", String.class);
142+
Task<String> t2 = ctx.callActivity("IsReplayingEcho", "beta", String.class);
143+
Task<String> t3 = ctx.callActivity("IsReplayingEcho", "gamma", String.class);
144+
ctx.allOf(Arrays.asList(t1, t2, t3)).await();
145+
146+
boolean after = ctx.getIsReplaying();
147+
148+
Map<String, Object> output = new LinkedHashMap<>();
149+
output.put("before_fan_out", before);
150+
output.put("after_fan_in", after);
151+
output.put("activities", Arrays.asList(t1.await(), t2.await(), t3.await()));
152+
return output;
153+
}
154+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
import * as df from 'durable-functions';
5+
import { ActivityHandler, OrchestrationContext, OrchestrationHandler } from 'durable-functions';
6+
7+
// ---------------------------------------------------------------------------
8+
// Activity used by the is_replaying orchestrators
9+
// ---------------------------------------------------------------------------
10+
11+
const IsReplayingEcho: ActivityHandler = (input: string): string => {
12+
return input;
13+
};
14+
df.app.activity('IsReplayingEcho', { handler: IsReplayingEcho });
15+
16+
// ---------------------------------------------------------------------------
17+
// 1. IsReplayingBasic
18+
// ---------------------------------------------------------------------------
19+
20+
const IsReplayingBasic: OrchestrationHandler = function* (context: OrchestrationContext) {
21+
// Workaround: context.df.isReplaying is undefined before the first yield.
22+
// See https://github.com/Azure/azure-functions-durable-js/issues/564
23+
const before: boolean = context.df.isReplaying ?? true;
24+
const result: string = yield context.df.callActivity('IsReplayingEcho', 'hello');
25+
const after: boolean = context.df.isReplaying;
26+
return {
27+
before_activity: before,
28+
after_activity: after,
29+
activity_result: result,
30+
};
31+
};
32+
df.app.orchestration('IsReplayingBasic', IsReplayingBasic);
33+
34+
// ---------------------------------------------------------------------------
35+
// 2. IsReplayingMultiActivity
36+
// ---------------------------------------------------------------------------
37+
38+
const IsReplayingMultiActivity: OrchestrationHandler = function* (context: OrchestrationContext) {
39+
// Workaround: context.df.isReplaying is undefined before the first yield.
40+
// See https://github.com/Azure/azure-functions-durable-js/issues/564
41+
const snapshots: object[] = [];
42+
43+
snapshots.push({ step: 0, label: 'start', is_replaying: context.df.isReplaying ?? true });
44+
45+
const r1: string = yield context.df.callActivity('IsReplayingEcho', 'one');
46+
snapshots.push({ step: 1, label: 'after_first', is_replaying: context.df.isReplaying });
47+
48+
const r2: string = yield context.df.callActivity('IsReplayingEcho', 'two');
49+
snapshots.push({ step: 2, label: 'after_second', is_replaying: context.df.isReplaying });
50+
51+
const r3: string = yield context.df.callActivity('IsReplayingEcho', 'three');
52+
snapshots.push({ step: 3, label: 'after_third', is_replaying: context.df.isReplaying });
53+
54+
return {
55+
snapshots,
56+
activities: [r1, r2, r3],
57+
};
58+
};
59+
df.app.orchestration('IsReplayingMultiActivity', IsReplayingMultiActivity);
60+
61+
// ---------------------------------------------------------------------------
62+
// 3. IsReplayingConditionalLog
63+
// ---------------------------------------------------------------------------
64+
65+
const IsReplayingConditionalLog: OrchestrationHandler = function* (context: OrchestrationContext) {
66+
// Workaround: context.df.isReplaying is undefined before the first yield.
67+
// See https://github.com/Azure/azure-functions-durable-js/issues/564
68+
let liveLogCount = 0;
69+
70+
if (!(context.df.isReplaying ?? true)) {
71+
console.log('IsReplayingConditionalLog: LIVE before activity');
72+
liveLogCount++;
73+
} else {
74+
console.log('IsReplayingConditionalLog: REPLAY before activity');
75+
}
76+
77+
const result: string = yield context.df.callActivity('IsReplayingEcho', 'logged');
78+
79+
if (!context.df.isReplaying) {
80+
console.log('IsReplayingConditionalLog: LIVE after activity');
81+
liveLogCount++;
82+
} else {
83+
console.log('IsReplayingConditionalLog: REPLAY after activity');
84+
}
85+
86+
return {
87+
live_log_count: liveLogCount,
88+
activity_result: result,
89+
};
90+
};
91+
df.app.orchestration('IsReplayingConditionalLog', IsReplayingConditionalLog);
92+
93+
// ---------------------------------------------------------------------------
94+
// 4. IsReplayingCounter
95+
// ---------------------------------------------------------------------------
96+
97+
const IsReplayingCounter: OrchestrationHandler = function* (context: OrchestrationContext) {
98+
// Workaround: context.df.isReplaying is undefined before the first yield.
99+
// See https://github.com/Azure/azure-functions-durable-js/issues/564
100+
let nonReplayCount = 0;
101+
let replayCount = 0;
102+
103+
if (context.df.isReplaying ?? true) { replayCount++; } else { nonReplayCount++; }
104+
105+
const r1: string = yield context.df.callActivity('IsReplayingEcho', 'a');
106+
if (context.df.isReplaying) { replayCount++; } else { nonReplayCount++; }
107+
108+
const r2: string = yield context.df.callActivity('IsReplayingEcho', 'b');
109+
if (context.df.isReplaying) { replayCount++; } else { nonReplayCount++; }
110+
111+
const r3: string = yield context.df.callActivity('IsReplayingEcho', 'c');
112+
if (context.df.isReplaying) { replayCount++; } else { nonReplayCount++; }
113+
114+
return {
115+
non_replay_count: nonReplayCount,
116+
replay_count: replayCount,
117+
total_checkpoints: nonReplayCount + replayCount,
118+
activities: [r1, r2, r3],
119+
};
120+
};
121+
df.app.orchestration('IsReplayingCounter', IsReplayingCounter);
122+
123+
// ---------------------------------------------------------------------------
124+
// 5. IsReplayingFanOutFanIn
125+
// ---------------------------------------------------------------------------
126+
127+
const IsReplayingFanOutFanIn: OrchestrationHandler = function* (context: OrchestrationContext) {
128+
// Workaround: context.df.isReplaying is undefined before the first yield.
129+
// See https://github.com/Azure/azure-functions-durable-js/issues/564
130+
const before: boolean = context.df.isReplaying ?? true;
131+
132+
const tasks = [
133+
context.df.callActivity('IsReplayingEcho', 'alpha'),
134+
context.df.callActivity('IsReplayingEcho', 'beta'),
135+
context.df.callActivity('IsReplayingEcho', 'gamma'),
136+
];
137+
const results: string[] = yield context.df.Task.all(tasks);
138+
139+
const after: boolean = context.df.isReplaying;
140+
141+
return {
142+
before_fan_out: before,
143+
after_fan_in: after,
144+
activities: results,
145+
};
146+
};
147+
df.app.orchestration('IsReplayingFanOutFanIn', IsReplayingFanOutFanIn);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"bindings": [
3+
{
4+
"name": "Context",
5+
"type": "orchestrationTrigger",
6+
"direction": "in"
7+
}
8+
]
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
param($Context)
2+
3+
$before = $Context.IsReplaying
4+
$result = Invoke-DurableActivity -FunctionName 'IsReplayingEcho' -Input 'hello'
5+
$after = $Context.IsReplaying
6+
7+
[ordered]@{
8+
before_activity = $before
9+
after_activity = $after
10+
activity_result = $result
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"bindings": [
3+
{
4+
"name": "Context",
5+
"type": "orchestrationTrigger",
6+
"direction": "in"
7+
}
8+
]
9+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
param($Context)
2+
3+
$liveLogCount = 0
4+
5+
if (-not $Context.IsReplaying) {
6+
Write-Host "IsReplayingConditionalLog: LIVE before activity"
7+
$liveLogCount++
8+
} else {
9+
Write-Host "IsReplayingConditionalLog: REPLAY before activity"
10+
}
11+
12+
$result = Invoke-DurableActivity -FunctionName 'IsReplayingEcho' -Input 'logged'
13+
14+
if (-not $Context.IsReplaying) {
15+
Write-Host "IsReplayingConditionalLog: LIVE after activity"
16+
$liveLogCount++
17+
} else {
18+
Write-Host "IsReplayingConditionalLog: REPLAY after activity"
19+
}
20+
21+
[ordered]@{
22+
live_log_count = $liveLogCount
23+
activity_result = $result
24+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"bindings": [
3+
{
4+
"name": "Context",
5+
"type": "orchestrationTrigger",
6+
"direction": "in"
7+
}
8+
]
9+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
param($Context)
2+
3+
$nonReplayCount = 0
4+
$replayCount = 0
5+
6+
if ($Context.IsReplaying) { $replayCount++ } else { $nonReplayCount++ }
7+
8+
$r1 = Invoke-DurableActivity -FunctionName 'IsReplayingEcho' -Input 'a'
9+
if ($Context.IsReplaying) { $replayCount++ } else { $nonReplayCount++ }
10+
11+
$r2 = Invoke-DurableActivity -FunctionName 'IsReplayingEcho' -Input 'b'
12+
if ($Context.IsReplaying) { $replayCount++ } else { $nonReplayCount++ }
13+
14+
$r3 = Invoke-DurableActivity -FunctionName 'IsReplayingEcho' -Input 'c'
15+
if ($Context.IsReplaying) { $replayCount++ } else { $nonReplayCount++ }
16+
17+
[ordered]@{
18+
non_replay_count = $nonReplayCount
19+
replay_count = $replayCount
20+
total_checkpoints = $nonReplayCount + $replayCount
21+
activities = @($r1, $r2, $r3)
22+
}

0 commit comments

Comments
 (0)