mirror of
https://github.com/hanzoai/tasks.git
synced 2026-11-03 03:56:04 +00:00
Full module path rebrand from Temporal to Hanzo Tasks: - go.mod module: github.com/hanzoai/tasks - All internal Go imports updated (1906 files) - cmd/server renamed to cmd/tasksd - Binary name: tasksd (was temporal-server) - Docker images: hanzoai/tasks (was temporalio/server) - README rewritten with Hanzo Tasks branding - LLM.md created with integration notes - Makefile, goreleaser, CI workflows updated - go.temporal.io/sdk and go.temporal.io/api imports preserved (separate repos) Fork of Temporal.io (MIT license).
103 lines
3.1 KiB
Go
103 lines
3.1 KiB
Go
package chasm
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
|
|
"go.temporal.io/api/serviceerror"
|
|
"github.com/hanzoai/tasks/common/softassert"
|
|
)
|
|
|
|
const (
|
|
parentPtrInternalFieldName = "Internal"
|
|
)
|
|
|
|
// ParentPtr is a in-memory pointer to the parent component of a CHASM component.
|
|
//
|
|
// CHASM map is not a component, so if a component is inside a map, its ParentPtr
|
|
// will point to the nearest ancestor component that is not a map.
|
|
//
|
|
// ParentPtr is only initialized and available for use **after** the transition that
|
|
// creates the component using ParentPtr is completed.
|
|
type ParentPtr[T any] struct {
|
|
// Exporting this field as this generic struct needs to be created via reflection,
|
|
// and reflection can't set private fields.
|
|
Internal parentPtrInternal
|
|
}
|
|
|
|
type parentPtrInternal struct {
|
|
// Storing currentNode instead of parent component Node here so that
|
|
// we can differentiate between root node and non-initialized ParentPtr.
|
|
currentNode *Node
|
|
}
|
|
|
|
// Get returns the parent component, deserializing it if necessary.
|
|
// Panics rather than returning an error, as errors are supposed to be handled by the framework as opposed to the
|
|
// application.
|
|
func (p ParentPtr[T]) Get(chasmContext Context) T {
|
|
vT, ok := p.TryGet(chasmContext)
|
|
if !ok {
|
|
// nolint:forbidigo // Panic is intended here for framework error handling.
|
|
panic(serviceerror.NewInternal("expect parent component value but got nil"))
|
|
}
|
|
return vT
|
|
}
|
|
|
|
// TryGet returns the parent component and a boolean indicating if the value was found,
|
|
// deserializing if necessary.
|
|
// Panics rather than returning an error, as errors are supposed to be handled by the framework as opposed to the
|
|
// application.
|
|
func (p ParentPtr[T]) TryGet(chasmContext Context) (T, bool) {
|
|
var nilT T
|
|
if p.Internal.currentNode == nil {
|
|
// ParentPtr not initialized
|
|
return nilT, false
|
|
}
|
|
|
|
parent := p.Internal.currentNode.parent
|
|
if parent == nil {
|
|
return nilT, false
|
|
}
|
|
|
|
for parent.isMap() {
|
|
parent = parent.parent
|
|
if parent == nil {
|
|
encodedPath, _ := p.Internal.currentNode.getEncodedPath()
|
|
// nolint:forbidigo // Panic is intended here for framework error handling.
|
|
panic(softassert.UnexpectedInternalErr(
|
|
p.Internal.currentNode.logger,
|
|
"unable to find parent component for CHASM component inside a map",
|
|
fmt.Errorf("child node name: %s", encodedPath),
|
|
))
|
|
}
|
|
}
|
|
|
|
if !parent.isComponent() {
|
|
// nolint:forbidigo // Panic is intended here for framework error handling.
|
|
panic(softassert.UnexpectedInternalErr(
|
|
parent.logger,
|
|
"unexpected CHASM node that has a child component",
|
|
fmt.Errorf("node %s, node metadata: %s",
|
|
parent.nodeName,
|
|
parent.serializedNode.GetMetadata().String(),
|
|
),
|
|
))
|
|
}
|
|
|
|
if err := parent.prepareComponentValue(chasmContext); err != nil {
|
|
// nolint:forbidigo // Panic is intended here for framework error handling.
|
|
panic(err)
|
|
}
|
|
|
|
if parent.value == nil {
|
|
return nilT, false
|
|
}
|
|
|
|
vT, isT := parent.value.(T)
|
|
if !isT {
|
|
// nolint:forbidigo // Panic is intended here for framework error handling.
|
|
panic(serviceerror.NewInternalf("parent component value doesn't implement %s", reflect.TypeFor[T]().Name()))
|
|
}
|
|
return vT, true
|
|
}
|