mirror of
https://github.com/hanzoai/tasks.git
synced 2026-10-04 02:04:03 +00:00
Replaces StubEnv use in dispatch.go with workerEnv, a real CoroutineEnv implementation. Activity dispatch now goes over the wire via ScheduleActivity (opcode 0x006B) + long-poll WaitActivityResult (0x006C), not a pre-populated in-memory map. NewTimer uses time.NewTimer in a per-timer goroutine; Select uses a fan-in wake channel with a 20ms watcher poll (no per-iteration allocation). Root cancel scope propagates to timers, activity polls, and child scopes on return. Workflow return errors are no longer swallowed — non-nil fn returns get encoded via temporal.Encode into a single FailureCommand entry in the commands envelope so the frontend can fail the execution per its retry policy. Phase-1 note documented in struct comment: every dispatch re-runs the workflow from the top with the same input — activities must be idempotent. Phase 2 replaces this with event-sourced replay without changing the public surface. Adds WorkerTransport.ScheduleActivity / WaitActivityResult / StartChildWorkflow with v1 JSON-in-envelope bodies. Schema schema/tasks.zap gains the 0x006B/0x006C struct definitions.
46 lines
1.2 KiB
Go
46 lines
1.2 KiB
Go
package workflow
|
|
|
|
import (
|
|
"reflect"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
// ActivityName returns the registered wire name for an activity
|
|
// value. String activities are returned as-is; function values are
|
|
// reflected to the short Go identifier (pkg.Fn → Fn). Nil yields
|
|
// "nil". Mirrors the upstream Temporal default.
|
|
func ActivityName(v any) string {
|
|
if v == nil {
|
|
return "nil"
|
|
}
|
|
if s, ok := v.(string); ok {
|
|
return s
|
|
}
|
|
return funcName(v)
|
|
}
|
|
|
|
// funcName returns the best-effort name for an activity function
|
|
// value. Used by the stub env to key its registered responses and
|
|
// by the worker at Phase 2 to dispatch by registered name.
|
|
//
|
|
// Kept in its own file so the reflect dependency is obvious and
|
|
// easy to audit — this is the only place the workflow package
|
|
// reflects.
|
|
func funcName(v any) string {
|
|
rv := reflect.ValueOf(v)
|
|
if !rv.IsValid() || rv.Kind() != reflect.Func {
|
|
return "unknown"
|
|
}
|
|
rf := runtime.FuncForPC(rv.Pointer())
|
|
if rf == nil {
|
|
return "unknown"
|
|
}
|
|
full := rf.Name() // e.g. github.com/x/y/z.DoWork
|
|
// Trim to "DoWork" — what Temporal also does by default.
|
|
if i := strings.LastIndex(full, "."); i >= 0 && i < len(full)-1 {
|
|
return full[i+1:]
|
|
}
|
|
return full
|
|
}
|