Skip to content

Commit 7d4a409

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 25b5771 commit 7d4a409

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
@@ -307,8 +307,6 @@ func (h *frontendHandler) TerminateActivityExecution(
307307
}
308308

309309
if req.GetRequestId() == "" {
310-
// Since this mutates the request, we clone it first so that any retries use the original request.
311-
req = common.CloneProto(req)
312310
req.RequestId = uuid.NewString()
313311
}
314312

@@ -346,8 +344,6 @@ func (h *frontendHandler) RequestCancelActivityExecution(
346344
}
347345

348346
if req.GetRequestId() == "" {
349-
// Since this mutates the request, we clone it first so that any retries use the original request.
350-
req = common.CloneProto(req)
351347
req.RequestId = uuid.NewString()
352348
}
353349

@@ -375,6 +371,9 @@ func (h *frontendHandler) validateAndPopulateStartRequest(
375371
req *workflowservice.StartActivityExecutionRequest,
376372
namespaceID namespace.ID,
377373
) (*workflowservice.StartActivityExecutionRequest, error) {
374+
if req.GetRequestId() == "" {
375+
req.RequestId = uuid.NewString()
376+
}
378377
// Since validation includes mutation of the request, we clone it first so that any retries use the original request.
379378
req = common.CloneProto(req)
380379
activityType := req.ActivityType.GetName()
@@ -413,10 +412,6 @@ func (h *frontendHandler) validateAndPopulateStartRequest(
413412
func (h *frontendHandler) validateAndNormalizeStartActivityExecutionRequest(
414413
req *workflowservice.StartActivityExecutionRequest,
415414
) error {
416-
if req.GetRequestId() == "" {
417-
req.RequestId = uuid.NewString()
418-
}
419-
420415
maxIDLengthLimit := h.config.MaxIDLengthLimit()
421416

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

0 commit comments

Comments
 (0)