workflow_state_replicator.go ×28

Frontier kind: Code frontier

unlabeled · c_e691d36f35a5

2 tests · 6495 LOC · 221 files · introduces 0 tests · 176 LOC · 4 files

Introduces — evidence that enters the hierarchy at this concept

Code
35 ranges176 lines · 4 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1220 ranges6495 lines · 221 files · Browse complete extent
All tests (intent)
2 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

4 files ranked by introduced lines: 176 introduced LOC across 35 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

go.temporal.io/server/service/history/ndc/workflow_state_replicator.go 153 introduced LOC · 28 ranges

Open complete file

149 ms, err := wfCtx.LoadMutableState(ctx, r.shardContext)
150 switch err.(type) {
151 > case *serviceerror.NotFound: workflow_state_replicator.go
152 // no-op, continue to replicate workflow state
153 case nil:
204 return err
205 }
206 > skipCloseTransferTask := request.GetIsForceReplication() && request.GetIsCloseTransferTaskAcked() workflow_state_replicator.go
207 > return r.applySnapshotWhenWorkflowNotExist(
208 > ctx,
209 > namespaceID,
210 > wid,
211 > rid,
212 > chasm.WorkflowArchetypeID,
213 > wfCtx,
214 > releaseFn,
215 > request.GetWorkflowState(),
216 > request.RemoteCluster,
217 > nil,
218 > false,
219 > skipCloseTransferTask,
220 > )
221 }
222
1566 isStateBased bool,
1567 skipGenerateCloseTransferTask bool,
1568 > ) error { workflow_state_replicator.go
1569 > var lastWriteVersion int64
1570 > executionInfo := sourceMutableState.ExecutionInfo
1571 > if transitionHistory := executionInfo.GetTransitionHistory(); len(transitionHistory) != 0 {
1572 lastWriteVersion = transitionhistory.LastVersionedTransition(transitionHistory).NamespaceFailoverVersion
1574 > // TODO: remove following logic once transition history is fully enabled.
1575 > currentVersionHistory, err := versionhistory.GetCurrentVersionHistory(executionInfo.VersionHistories)
1576 > if err != nil {
1577 return err
1578 }
1579 > lastEventItem, err := versionhistory.GetLastVersionHistoryItem(currentVersionHistory) workflow_state_replicator.go
1580 > if err != nil {
1581 return err
1582 }
1583 > lastWriteVersion = lastEventItem.GetVersion() workflow_state_replicator.go
1584 }
1585
1586 > ns, err := r.namespaceRegistry.GetNamespaceByID(namespaceID) workflow_state_replicator.go
1587 > if err != nil {
1588 return err
1589 }
1590
1591 > mutableState, err := workflow.NewSanitizedMutableState( workflow_state_replicator.go
1592 > r.shardContext,
1593 > r.shardContext.GetEventsCache(),
1594 > r.logger,
1595 > ns,
1596 > sourceMutableState,
1597 > lastWriteVersion,
1598 > )
1599 > if err != nil {
1600 return err
1601 }
1602
1603 > if err := r.backfillHistory( workflow_state_replicator.go
1604 > ctx,
1605 > sourceCluster,
1606 > namespaceID,
1607 > workflowID,
1608 > runID,
1609 > mutableState,
1610 > isStateBased,
1611 > ); err != nil {
1612 return err
1613 }
1614
1615 > if newRunInfo != nil { workflow_state_replicator.go
1616 err = r.createNewRunWorkflow(
1617 ctx,
1628 }
1629
1630 > taskRefresher := workflow.NewTaskRefresher(r.shardContext) workflow_state_replicator.go
1631 > err = taskRefresher.Refresh(ctx, mutableState, skipGenerateCloseTransferTask)
1632 > if err != nil {
1633 return err
1634 }
1635 > return r.transactionMgr.CreateWorkflow( workflow_state_replicator.go
1636 > ctx,
1637 > archtypeID,
1638 > NewWorkflow(
1639 > r.clusterMetadata,
1640 > wfCtx,
1641 > mutableState,
1642 > releaseFn,
1643 > ),
1644 > )
1645 }
1646
1716 mutableState *workflow.MutableStateImpl,
1717 isStateBased bool,
1718 > ) (retError error) { workflow_state_replicator.go
1719 > versionHistories := mutableState.GetExecutionInfo().VersionHistories
1720 > isEmpty, err := versionhistory.IsCurrentVersionHistoryEmpty(versionHistories)
1721 > if err != nil || isEmpty {
1722 return err
1723 }
1724
1725 > currentVersionHistory, err := versionhistory.GetCurrentVersionHistory(versionHistories) workflow_state_replicator.go
1726 > if err != nil {
1727 return err
1728 }
1729 > lastEventItem, err := versionhistory.GetLastVersionHistoryItem(currentVersionHistory) workflow_state_replicator.go
1730 > if err != nil {
1731 return err
1732 }
1733
1734 // The following sanitizes the branch token from the source cluster to this target cluster by re-initializing it.
1735 > branchInfo, err := r.shardContext.GetExecutionManager().GetHistoryBranchUtil().ParseHistoryBranchInfo( workflow_state_replicator.go
1736 > currentVersionHistory.GetBranchToken(),
1737 > )
1738 > if err != nil {
1739 return err
1740 }
1741
1742 > archetypeID := mutableState.ChasmTree().ArchetypeID() workflow_state_replicator.go
1743 > if archetypeID != chasm.WorkflowArchetypeID {
1744 return softassert.UnexpectedInternalErr(
1745 r.logger,
1753 }
1754
1755 > backfillBranchToken, err := r.shardContext.GetExecutionManager().GetHistoryBranchUtil().NewHistoryBranch( workflow_state_replicator.go
1756 > namespaceID.String(),
1757 > workflowID,
1758 > runID,
1759 > branchInfo.GetTreeId(),
1760 > &branchInfo.BranchId,
1761 > branchInfo.Ancestors,
1762 > time.Duration(0),
1763 > time.Duration(0),
1764 > time.Duration(0),
1765 > )
1766 > if err != nil {
1767 return err
1768 }
1771 // Use the history tree id to be the original run id.
1772 // https://github.com/temporalio/temporal/issues/6501
1773 > originalRunID := branchInfo.GetTreeId() workflow_state_replicator.go
1774 > if runID != originalRunID {
1775 // At this point, it already acquired the workflow lock on the run ID.
1776 // Get the lock of root run id to make sure no concurrent backfill history across multiple runs.
1800
1801 // Get the last batch node id to check if the history data is already in DB.
1802 > localHistoryIterator := collection.NewPagingIterator(r.getHistoryFromLocalPaginationFn( workflow_state_replicator.go
1803 > ctx,
1804 > backfillBranchToken,
1805 > lastEventItem.EventId,
1806 > ))
1807 > var lastBatchNodeID int64
1808 > for localHistoryIterator.HasNext() {
1809 > localHistoryBatch, err := localHistoryIterator.Next()
1810 > switch err.(type) {
1811 case nil:
1812 if len(localHistoryBatch.GetEvents()) > 0 {
1819 }
1820
1821 > remoteHistoryIterator := collection.NewPagingIterator(r.getHistoryFromRemotePaginationFn( workflow_state_replicator.go
1822 > ctx,
1823 > remoteClusterName,
1824 > namespaceID,
1825 > workflowID,
1826 > runID,
1827 > common.EmptyEventID,
1828 > common.EmptyVersion,
1829 > lastEventItem.EventId+1,
1830 > lastEventItem.Version),
1831 > )
1832 > historyBranchUtil := r.executionMgr.GetHistoryBranchUtil()
1833 > historyBranch, err := historyBranchUtil.ParseHistoryBranchInfo(backfillBranchToken)
1834 > if err != nil {
1835 return err
1836 }
1837
1838 > nsName := namespace.EmptyName.String() workflow_state_replicator.go
1839 > ns, err := r.namespaceRegistry.GetNamespaceByID(namespaceID)
1840 > if err == nil && ns != nil {
1841 > nsName = ns.Name().String()
1842 > }
1843 // In standby cluster, use a background low priority which is higher than the standby task processing
1844 > callerType := headers.CallerTypeBackgroundLow workflow_state_replicator.go
1845 > if ns.ActiveClusterName(namespace.RoutingKey{ID: workflowID}) == r.clusterMetadata.GetCurrentClusterName() {
1846 // In active cluster, use lowest priority to minimize the impact to live traffic
1847 callerType = headers.CallerTypePreemptable
1848 }
1849 > quotaRequest := quotas.NewRequest( workflow_state_replicator.go
1850 > "AppendRawHistoryNodes",
1851 > 1,
1852 > nsName,
1853 > callerType,
1854 > 0,
1855 > "",
1856 > )
1857 >
1858 > prevTxnID := common.EmptyEventTaskID
1859 > var prevBranchID string
1860 > sortedAncestors := sortAncestors(historyBranch.GetAncestors())
1861 > sortedAncestorsIdx := 0
1862 > var ancestors []*persistencespb.HistoryBranchRange
1863 >
1864 > BackfillLoop:
1865 > for remoteHistoryIterator.HasNext() {
1866 historyBlob, err := remoteHistoryIterator.Next()
1867 if err != nil {
1962 }
1963
1964 > mutableState.GetExecutionInfo().LastFirstEventTxnId = prevTxnID workflow_state_replicator.go
1965 > return mutableState.SetCurrentBranchToken(backfillBranchToken)
1966 }
1967
1970 branchToken []byte,
1971 lastEventID int64,
1972 > ) collection.PaginationFn[*historypb.History] { workflow_state_replicator.go
1973 >
1974 > return func(paginationToken []byte) ([]*historypb.History, []byte, error) {
1975 > response, err := r.executionMgr.ReadHistoryBranchByBatch(ctx, &persistence.ReadHistoryBranchRequest{
1976 > ShardID: r.shardContext.GetShardID(),
1977 > BranchToken: branchToken,
1978 > MinEventID: common.FirstEventID,
1979 > MaxEventID: lastEventID + 1,
1980 > PageSize: 100,
1981 > NextPageToken: paginationToken,
1982 > })
1983 > if err != nil {
1984 return nil, nil, err
1985 }
2062 }
2063
2064 > func sortAncestors(ans []*persistencespb.HistoryBranchRange) []*persistencespb.HistoryBranchRange { workflow_state_replicator.go
2065 > if len(ans) > 0 {
2066 // sort ans based onf EndNodeID so that we can set BeginNodeID
2067 sort.Slice(ans, func(i, j int) bool { return ans[i].GetEndNodeId() < ans[j].GetEndNodeId() })
go.temporal.io/server/service/history/workflow/mutable_state_impl.go 15 introduced LOC · 5 ranges

Open complete file

607 mutableStateRecord *persistencespb.WorkflowMutableState,
608 lastWriteVersion int64,
609 > ) (*MutableStateImpl, error) { mutable_state_impl.go
610 > // Although new versions of temporal server will perform state sanitization,
611 > // we have to keep the sanitization logic here as well for backward compatibility in case
612 > // source cluster is running an old version and doesn't do the sanitization.
613 > SanitizeMutableState(mutableStateRecord)
614 > if err := common.DiscardUnknownProto(mutableStateRecord); err != nil {
615 return nil, err
616 }
617
618 > mutableState, err := NewMutableStateFromDB(shard, eventsCache, logger, namespaceEntry, mutableStateRecord, 1) mutable_state_impl.go
619 > if err != nil {
620 return nil, err
621 }
622
623 > mutableState.currentVersion = lastWriteVersion mutable_state_impl.go
624 > return mutableState, nil
625 }
626
1923 func (ms *MutableStateImpl) GetWorkflowCloseTime(ctx context.Context) (time.Time, error) {
1924 if ms.executionState.GetState() == enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED && ms.executionInfo.CloseTime == nil {
1925 > // This is for backward compatible. Prior to v1.16 does not have close time in mutable state (Added by 05/21/2022). mutable_state_impl.go
1926 > // TODO: remove this logic when all mutable state contains close time.
1927 > completionEvent, err := ms.GetCompletionEvent(ctx)
1928 > if err != nil {
1929 return time.Time{}, err
1930 }
1931 > return completionEvent.GetEventTime().AsTime(), nil mutable_state_impl.go
1932 }
1933 return ms.executionInfo.CloseTime.AsTime(), nil
go.temporal.io/server/api/historyservice/v1/request_response.pb.go 4 introduced LOC · 1 range

Open complete file

4423 }
4424
4425 > func (x *ReplicateWorkflowStateRequest) GetIsForceReplication() bool { request_response.pb.go
4426 > if x != nil {
4427 > return x.IsForceReplication
4428 > }
4429 return false
4430 }
go.temporal.io/server/api/persistence/v1/history_tree.pb.go 4 introduced LOC · 1 range

Open complete file

153 }
154
155 > func (x *HistoryBranch) GetAncestors() []*HistoryBranchRange { history_tree.pb.go
156 > if x != nil {
157 > return x.Ancestors
158 > }
159 return nil
160 }