go.temporal.io/server/chasm/nexus_completion.go
83 LOC · 30 covered · 53 uncovered · 8 ranges · 43 concepts · 4 introducers · 17 tests
File neighbourhood
The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.
Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file
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 related-file, concept, and source links on this page.
Graph controls are ready.
Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.
package chasm
import (
"encoding/base64"
commonpb "go.temporal.io/api/common/v1"
persistencespb "go.temporal.io/server/api/persistence/v1"
tokenspb "go.temporal.io/server/api/token/v1"
"google.golang.org/protobuf/proto"
)
// NexusCompletionHandlerURL is the user-visible URL for Nexus->CHASM callbacks.
const NexusCompletionHandlerURL = "temporal://internal"
// nexusCallbackTokenHeader is the callback header key carrying the completion token.
// NOTE: There's a constant defined for this in common/nexus but to avoid circular dependencies we
// redefine it here. nexus.Header lookups are case-insensitive, so this matches the canonical key.
const nexusCallbackTokenHeader = "temporal-callback-token"
// NexusCompletionHandler is implemented by CHASM components that want to handle Nexus operation completion callbacks.
type NexusCompletionHandler interface {
HandleNexusCompletion(ctx MutableContext, completion *persistencespb.ChasmNexusCompletion) error
}
// GenerateNexusCallback builds a Nexus completion callback targeting the CHASM component identified by
// serializedRef (obtained from Context.Ref). When encodeToken is true, the request ID is packed into
// the callback token (a NexusOperationCompletion envelope), so the completion is matched by a request
// ID that rides in the callback header and survives continue-as-new, rather than one read from mutable
// state. When encodeToken is false, the legacy format is emitted: the token is the bare base64-encoded
// ChasmComponentRef with no request ID. The caller chooses encodeToken (e.g. gated behind dynamic
// config) to keep the envelope format off the wire until the whole fleet can read it. Either format is
// always decodable by UnpackNexusCallbackToken.
func GenerateNexusCallback(serializedRef []byte, requestID string, encodeToken bool) (*commonpb.Callback, error) {
invoker_tasks.go ×7
var token string
if encodeToken {
var err error
token, err = packNexusCallbackToken(serializedRef, requestID)
if err != nil {
return nil, err
}
} else {
// Legacy format: the token is the bare base64-encoded ChasmComponentRef.
token = base64.RawURLEncoding.EncodeToString(serializedRef)
}
Variant: &commonpb.Callback_Nexus_{
Nexus: &commonpb.Callback_Nexus{
Url: NexusCompletionHandlerURL,
Header: map[string]string{nexusCallbackTokenHeader: token},
},
},
}, nil
}
// packNexusCallbackToken encodes a CHASM component ref and request ID into a callback token.
func packNexusCallbackToken(componentRef []byte, requestID string) (string, error) {
invoker_tasks.go ×7
b, err := proto.Marshal(&tokenspb.NexusOperationCompletion{
ComponentRef: componentRef,
RequestId: requestID,
})
if err != nil {
return "", err
}
}
// UnpackNexusCallbackToken decodes a callback token produced by GenerateNexusCallback, returning the
// component ref and request ID. It accepts both token formats regardless of how the token was written:
// the NexusOperationCompletion envelope, and (for backward compatibility) the legacy bare base64-encoded
// ChasmComponentRef, in which case the request ID is empty.
func UnpackNexusCallbackToken(encoded string) (componentRef []byte, requestID string, err error) {
nexus_completion.go ×1
raw, err := base64.RawURLEncoding.DecodeString(encoded)
if err != nil {
}
if proto.Unmarshal(raw, completion) == nil && len(completion.GetComponentRef()) > 0 &&
proto.Unmarshal(completion.GetComponentRef(), &persistencespb.ChasmComponentRef{}) == nil {
return completion.GetComponentRef(), completion.GetRequestId(), nil
}
// Legacy format: the raw bytes are the ChasmComponentRef directly.
}