227
versionedTransitionArtifact *replicationspb.VersionedTransitionArtifact,
228
sourceClusterName string,
230
>
if versionedTransitionArtifact.StateAttributes == nil {
231
return serviceerror.NewInvalidArgument("both snapshot and mutation are nil")
232
}
233
234
>
_, snapshot, executionState, executionInfo, err := parseVersionedTransitionAttributes(versionedTransitionArtifact)
workflow_state_replicator.go
235
>
if err != nil {
236
return err
237
}
238
240
>
wid := executionInfo.GetWorkflowId()
241
>
rid := executionState.GetRunId()
242
>
243
>
// emitApplied gates the best-effort "applied" lifecycle event; computed once here so the gate
244
>
// lives at the call site, like the other replication lifecycle emitters.
245
>
emitApplied := r.eventLogger != nil && r.shardContext.GetConfig().EmitReplicationLifecycleEvents()
246
>
// ms is the mutable state being applied; appliedMS is a snapshot of its post-apply state taken
247
>
// under the workflow lock (see the releaseFn wrapper below) for the deferred emit. Reading the
248
>
// live ms after the lock is released would race with the next writer.
249
>
var ms historyi.MutableState
250
>
var appliedMS *persistencespb.WorkflowMutableState
251
>
defer func() {
252
>
if emitApplied && retError == nil {
253
r.emitReplicationVersionedTransitionApplied(namespaceID, wid, rid, appliedMS)
254
}
255
}()
256
258
>
ctx,
259
>
r.shardContext,
260
>
namespaceID,
261
>
&commonpb.WorkflowExecution{
262
>
WorkflowId: wid,
263
>
RunId: rid,
264
>
},
265
>
archetypeID,
266
>
locks.PriorityHigh,
267
>
)
268
>
if err != nil {
269
return err
270
}
272
// Snapshot the post-apply mutable state at release time: the only point that is both after
273
// the apply (which mutates ms in place) and still under the workflow lock, since the apply