Skip to content

Commit 1d86a57

Browse files
Support toString on workflow proxy types (temporalio#2315)
1 parent 16b0bb9 commit 1d86a57

8 files changed

+90
-5
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,9 @@ protected Function<Object[], Object> getActivityFunc(
8383
(a) -> stub.execute(activityName, method.getReturnType(), method.getGenericReturnType(), a);
8484
return function;
8585
}
86+
87+
@Override
88+
protected String proxyToString() {
89+
return "ActivityProxy{" + "options=" + options + '}';
90+
}
8691
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ public static <T> T newProxy(Class<T> activityInterface, InvocationHandler invoc
5353

5454
@Override
5555
public Object invoke(Object proxy, Method method, Object[] args) {
56+
// Proxy the toString method so the stub can be inspected when debugging.
57+
try {
58+
if (method.equals(Object.class.getMethod("toString"))) {
59+
return proxyToString();
60+
}
61+
} catch (NoSuchMethodException e) {
62+
throw new Error("unexpected", e);
63+
}
5664
POJOActivityMethodMetadata methodMetadata = activityMetadata.getMethodMetadata(method);
5765
MethodRetry methodRetry = methodMetadata.getMethod().getAnnotation(MethodRetry.class);
5866
String activityType = methodMetadata.getActivityTypeName();
@@ -62,4 +70,6 @@ public Object invoke(Object proxy, Method method, Object[] args) {
6270

6371
protected abstract Function<Object[], Object> getActivityFunc(
6472
Method method, MethodRetry methodRetry, String activityName);
73+
74+
protected abstract String proxyToString();
6575
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ class ChildWorkflowInvocationHandler implements InvocationHandler {
7171

7272
@Override
7373
public Object invoke(Object proxy, Method method, Object[] args) {
74+
// Proxy the toString method so the stub can be inspected when debugging.
75+
try {
76+
if (method.equals(Object.class.getMethod("toString"))) {
77+
return proxyToString();
78+
}
79+
} catch (NoSuchMethodException e) {
80+
throw new Error("unexpected", e);
81+
}
7482
// Implement StubMarker
7583
if (method.getName().equals(StubMarker.GET_UNTYPED_STUB_METHOD)) {
7684
return stub;
@@ -99,4 +107,14 @@ public Object invoke(Object proxy, Method method, Object[] args) {
99107
}
100108
throw new IllegalArgumentException("unreachable");
101109
}
110+
111+
private String proxyToString() {
112+
return "ChildWorkflowProxy{"
113+
+ "workflowType='"
114+
+ stub.getWorkflowType()
115+
+ '\''
116+
+ ", options="
117+
+ stub.getOptions()
118+
+ '}';
119+
}
102120
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ public ExternalWorkflowInvocationHandler(
4747

4848
@Override
4949
public Object invoke(Object proxy, Method method, Object[] args) {
50+
// Proxy the toString method so the stub can be inspected when debugging.
51+
try {
52+
if (method.equals(Object.class.getMethod("toString"))) {
53+
return proxyToString();
54+
}
55+
} catch (NoSuchMethodException e) {
56+
throw new Error("unexpected", e);
57+
}
5058
// Implement StubMarker
5159
if (method.getName().equals(StubMarker.GET_UNTYPED_STUB_METHOD)) {
5260
return stub;
@@ -73,4 +81,14 @@ public Object invoke(Object proxy, Method method, Object[] args) {
7381
}
7482
return null;
7583
}
84+
85+
private String proxyToString() {
86+
return "ExternalWorkflowProxy{"
87+
+ "workflowType='"
88+
+ workflowMetadata.getWorkflowType().orElse("")
89+
+ '\''
90+
+ ", execution="
91+
+ stub.getExecution()
92+
+ '}';
93+
}
7694
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,9 @@ public Function<Object[], Object> getActivityFunc(
7979
(a) -> stub.execute(activityName, method.getReturnType(), method.getGenericReturnType(), a);
8080
return function;
8181
}
82+
83+
@Override
84+
protected String proxyToString() {
85+
return "LocalActivityProxy{" + "options='" + options + '}';
86+
}
8287
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ public class NexusServiceInvocationHandler implements InvocationHandler {
4848

4949
@Override
5050
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
51+
// Proxy the toString method so the stub can be inspected when debugging.
52+
try {
53+
if (method.equals(Object.class.getMethod("toString"))) {
54+
return proxyToString();
55+
}
56+
} catch (NoSuchMethodException e) {
57+
throw new Error("unexpected", e);
58+
}
59+
5160
if (method.getName().equals(StubMarker.GET_UNTYPED_STUB_METHOD)) {
5261
return stub;
5362
}
@@ -69,4 +78,14 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
6978
this.stub.execute(opName, method.getReturnType(), method.getGenericReturnType(), arg),
7079
method.getReturnType());
7180
}
81+
82+
private String proxyToString() {
83+
return "NexusServiceProxy{"
84+
+ "serviceName="
85+
+ serviceDef.getName()
86+
+ '\''
87+
+ ", options="
88+
+ stub.getOptions()
89+
+ '}';
90+
}
7291
}

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828
import java.util.Collections;
2929

3030
public class NexusServiceStubImpl implements NexusServiceStub {
31-
final String name;
32-
final NexusServiceOptions options;
33-
final WorkflowOutboundCallsInterceptor outboundCallsInterceptor;
34-
final Functions.Proc1<String> assertReadOnly;
31+
private final String name;
32+
private final NexusServiceOptions options;
33+
private final WorkflowOutboundCallsInterceptor outboundCallsInterceptor;
34+
private final Functions.Proc1<String> assertReadOnly;
3535

3636
public NexusServiceStubImpl(
3737
String name,
@@ -118,6 +118,11 @@ public <R> NexusOperationHandle<R> start(
118118
arg,
119119
mergedOptions,
120120
Collections.emptyMap()));
121-
return new NexusOperationHandleImpl(result.getOperationExecution(), result.getResult());
121+
return new NexusOperationHandleImpl<>(result.getOperationExecution(), result.getResult());
122+
}
123+
124+
@Override
125+
public NexusServiceOptions getOptions() {
126+
return options;
122127
}
123128
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,9 @@ <R> Promise<R> executeAsync(
109109
*/
110110
<R> NexusOperationHandle<R> start(
111111
String operationName, Class<R> resultClass, Type resultType, Object arg);
112+
113+
/**
114+
* @return Options used to create this stub.
115+
*/
116+
NexusServiceOptions getOptions();
112117
}

0 commit comments

Comments
 (0)