Skip to content

Commit 38bd190

Browse files
committed
Fix StartActivityExecution request-ID dedup across server-side retries
Move RequestId generation before the proto clone so that the RetryableInterceptor, which retries with the same request pointer, carries the same server-generated RequestId on every attempt. Previously the RequestId was generated on the clone, so each retry got a fresh UUID that could not match the stored RequestId, breaking dedup and potentially causing a double-create if the activity completed between attempts. Fix Terminate/CancelActivity request-ID dedup across server-side retries Same issue as StartActivityExecution: the RequestId was generated on a clone, so RetryableInterceptor retries got a fresh UUID each time. For Terminate, this caused a spurious FailedPrecondition error on retry ("already terminated with request ID ..."). For RequestCancel, same pattern ("cancellation already requested with request ID ..."). Fix: set RequestId on the original request before any clone, matching the OSS pattern used by workflow handlers. These handlers had no other mutations requiring a clone, so the clone is simply removed.
1 parent b6f9a9b commit 38bd190

1 file changed

Lines changed: 3 additions & 8 deletions

File tree

chasm/lib/activity/frontend.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,6 @@ func (h *frontendHandler) TerminateActivityExecution(
294294
}
295295

296296
if req.GetRequestId() == "" {
297-
// Since this mutates the request, we clone it first so that any retries use the original request.
298-
req = common.CloneProto(req)
299297
req.RequestId = uuid.NewString()
300298
}
301299

@@ -333,8 +331,6 @@ func (h *frontendHandler) RequestCancelActivityExecution(
333331
}
334332

335333
if req.GetRequestId() == "" {
336-
// Since this mutates the request, we clone it first so that any retries use the original request.
337-
req = common.CloneProto(req)
338334
req.RequestId = uuid.NewString()
339335
}
340336

@@ -362,6 +358,9 @@ func (h *frontendHandler) validateAndPopulateStartRequest(
362358
req *workflowservice.StartActivityExecutionRequest,
363359
namespaceID namespace.ID,
364360
) (*workflowservice.StartActivityExecutionRequest, error) {
361+
if req.GetRequestId() == "" {
362+
req.RequestId = uuid.NewString()
363+
}
365364
// Since validation includes mutation of the request, we clone it first so that any retries use the original request.
366365
req = common.CloneProto(req)
367366
activityType := req.ActivityType.GetName()
@@ -400,10 +399,6 @@ func (h *frontendHandler) validateAndPopulateStartRequest(
400399
func (h *frontendHandler) validateAndNormalizeStartActivityExecutionRequest(
401400
req *workflowservice.StartActivityExecutionRequest,
402401
) error {
403-
if req.GetRequestId() == "" {
404-
req.RequestId = uuid.NewString()
405-
}
406-
407402
maxIDLengthLimit := h.config.MaxIDLengthLimit()
408403

409404
if len(req.GetRequestId()) > maxIDLengthLimit {

0 commit comments

Comments
 (0)