Files
Yichao YangandGitHub 63839f1a9d CHASM: Propagate ArchetypeID (#8693)
## What changed?
- Use archetypeID everywhere in history service and pass them to
persistence

## Why?
- Required for separate ID space work.

## How did you test it?
- [x] built
- [ ] run locally and tested manually
- [x] covered by existing tests
- [x] added new unit test(s)
- [ ] added new functional test(s)
2025-11-26 16:04:44 -08:00

161 lines
4.7 KiB
Go

package getworkflowexecutionhistoryreverse
import (
"context"
commonpb "go.temporal.io/api/common/v1"
historypb "go.temporal.io/api/history/v1"
"go.temporal.io/api/serviceerror"
"go.temporal.io/api/workflowservice/v1"
historyspb "go.temporal.io/server/api/history/v1"
"go.temporal.io/server/api/historyservice/v1"
tokenspb "go.temporal.io/server/api/token/v1"
"go.temporal.io/server/common"
"go.temporal.io/server/common/namespace"
"go.temporal.io/server/common/persistence/versionhistory"
"go.temporal.io/server/common/persistence/visibility/manager"
"go.temporal.io/server/service/history/api"
"go.temporal.io/server/service/history/consts"
"go.temporal.io/server/service/history/events"
historyi "go.temporal.io/server/service/history/interfaces"
)
func Invoke(
ctx context.Context,
shardContext historyi.ShardContext,
workflowConsistencyChecker api.WorkflowConsistencyChecker,
eventNotifier events.Notifier,
request *historyservice.GetWorkflowExecutionHistoryReverseRequest,
persistenceVisibilityMgr manager.VisibilityManager,
) (_ *historyservice.GetWorkflowExecutionHistoryReverseResponse, retError error) {
namespaceID := namespace.ID(request.GetNamespaceId())
err := api.ValidateNamespaceUUID(namespaceID)
if err != nil {
return nil, err
}
queryMutableState := func(
namespaceUUID namespace.ID,
execution *commonpb.WorkflowExecution,
expectedNextEventID int64,
currentBranchToken []byte,
versionHistoryItem *historyspb.VersionHistoryItem,
) ([]byte, string, int64, *historyspb.VersionHistoryItem, error) {
response, err := api.GetOrPollWorkflowMutableState(
ctx,
shardContext,
&historyservice.GetMutableStateRequest{
NamespaceId: namespaceUUID.String(),
Execution: execution,
ExpectedNextEventId: expectedNextEventID,
CurrentBranchToken: currentBranchToken,
VersionHistoryItem: versionHistoryItem,
},
workflowConsistencyChecker,
eventNotifier,
)
if err != nil {
return nil, "", 0, nil, err
}
currentVersionHistory, err := versionhistory.GetCurrentVersionHistory(response.GetVersionHistories())
if err != nil {
return nil, "", 0, nil, err
}
lastVersionHistoryItem, err := versionhistory.GetLastVersionHistoryItem(currentVersionHistory)
if err != nil {
return nil, "", 0, nil, err
}
return response.CurrentBranchToken,
response.Execution.GetRunId(),
response.GetLastFirstEventTxnId(),
lastVersionHistoryItem,
nil
}
req := request.Request
execution := req.Execution
var continuationToken *tokenspb.HistoryContinuation
var runID string
var lastFirstTxnID int64
if req.NextPageToken == nil {
continuationToken = &tokenspb.HistoryContinuation{}
continuationToken.BranchToken, runID, lastFirstTxnID, continuationToken.VersionHistoryItem, err =
queryMutableState(namespaceID, execution, common.FirstEventID, nil, nil)
if err != nil {
return nil, err
}
execution.RunId = runID
continuationToken.RunId = runID
continuationToken.FirstEventId = common.FirstEventID
continuationToken.NextEventId = common.EmptyEventID
continuationToken.PersistenceToken = nil
} else {
continuationToken, err = api.DeserializeHistoryToken(req.NextPageToken)
if err != nil {
return nil, consts.ErrInvalidNextPageToken
}
if execution.GetRunId() != "" && execution.GetRunId() != continuationToken.GetRunId() {
return nil, consts.ErrNextPageTokenRunIDMismatch
}
execution.RunId = continuationToken.GetRunId()
}
// TODO below is a temporal solution to guard against invalid event batch
// when data inconsistency occurs
// long term solution should check event batch pointing backwards within history store
defer func() {
if _, ok := retError.(*serviceerror.DataLoss); ok {
api.TrimHistoryNode(
ctx,
shardContext,
workflowConsistencyChecker,
eventNotifier,
namespaceID.String(),
execution.GetWorkflowId(),
execution.GetRunId(),
)
}
}()
history := &historypb.History{}
history.Events = []*historypb.HistoryEvent{}
// return all events
history, continuationToken.PersistenceToken, continuationToken.NextEventId, err = api.GetHistoryReverse(
ctx,
shardContext,
namespaceID,
execution,
continuationToken.NextEventId,
lastFirstTxnID,
req.GetMaximumPageSize(),
continuationToken.PersistenceToken,
continuationToken.BranchToken,
persistenceVisibilityMgr,
)
if err != nil {
return nil, err
}
if continuationToken.NextEventId < continuationToken.FirstEventId {
continuationToken = nil
}
nextToken, err := api.SerializeHistoryToken(continuationToken)
if err != nil {
return nil, err
}
return &historyservice.GetWorkflowExecutionHistoryReverseResponse{
Response: &workflowservice.GetWorkflowExecutionHistoryReverseResponse{
History: history,
NextPageToken: nextToken,
},
}, nil
}