Files
tasks/pkg/sdk/client/worker_bridge.go
zeekay 6112841b1e feat(sdk/client): native user-facing RPC surface, zero upstream deps
Implements pkg/sdk/client — the Temporal-replacement surface base,
commerce, and ta call when migrating off go.temporal.io/sdk/client.
Transport is luxfi/zap; zero go.temporal.io/* and zero
google.golang.org/grpc imports.

Opcode allocation (append-only, never reuse):
  0x0050-0x005F pkg/tasks legacy (submit / schedule), reserved
  0x0060-0x006F workflow lifecycle (start, signal, cancel,
                terminate, describe, list)
  0x0070-0x007F schedule ops (create, list, delete, pause)
  0x0080-0x008F namespace ops (register, describe, list)
  0x0090-0x009F health + meta
  0x00A0-0x00AF worker poll / respond (moved up from 0x0070
                to avoid collision with schedule ops)

Wire (v1): request and response bodies are a JSON document wrapped
in a ZAP envelope with three fields:
  field 0  (Bytes)  — body
  field 8  (Uint32) — status (0/200 = ok)
  field 12 (Bytes)  — error detail on non-zero status
Opcode is stamped on the ZAP frame flags (high byte). Native ZAP
serde replaces JSON in a follow-up without changing opcodes.

Files:
- client.go      — Client interface (Close/ExecuteWorkflow/SignalWorkflow/
                   CancelWorkflow/Terminate/Describe/List + schedule +
                   namespace + health), Dial, Transport abstraction,
                   luxfi/zap default transport, envelope codec.
- options.go     — Options, StartWorkflowOptions (RetryPolicy via
                   pkg/sdk/temporal, no upstream import).
- workflow.go    — ExecuteWorkflow, Signal/Cancel/Terminate/Describe/List,
                   WorkflowRun with reflect-based type-name resolution.
- namespace.go   — Register/Describe/List + wire duration-ms codec.
- schedule.go    — Create/List/Delete/Pause + wire duration-ms codec.
- transport.go   — WorkerTransport + PollWorkflowTaskRequest etc. +
                   the worker-opcode constants (now 0x00A0+).
- client_test.go — Dial/Close test, ExecuteWorkflow round-trip with a
                   fake Transport capturing the request and replaying
                   a canned response (same pattern as pkg/tasks).

Worker bridge helpers (worker_bridge.go, worker_transport.go) were
added concurrently on feat/zap-internal; they import and wrap the
Transport this commit defines.

WorkflowRun.Get gap: the v1 schema does not yet declare a
GetWorkflowHistory / GetWorkflowResult RPC, so Get polls
DescribeWorkflow and returns ErrNotImplementedLocally when the
caller asks for a result from a completed workflow. This is marked
in the doc comment and will be filled in when pkg/sdk/worker lands
the history-fetch opcode.

Verification:
  go vet ./pkg/sdk/client/...    — clean
  go test ./pkg/sdk/client/...   — 7/7 pass
  go list -deps ./pkg/sdk/client/...  — no go.temporal.io/*, no
                                        google.golang.org/grpc
2026-04-23 10:38:02 -07:00

41 lines
1.2 KiB
Go

// Copyright © 2026 Hanzo AI. MIT License.
package client
// TransportOf extracts the underlying Transport from a Client returned
// by Dial. pkg/sdk/worker calls this to layer a typed WorkerTransport
// over the generic Transport the Client already owns — workers share
// the ZAP connection and long-poll channel with the Client so users
// pay for one node per process.
//
// Callers that injected a custom Transport via Options.Transport
// receive the same value they passed in.
//
// Returns nil if c was not produced by Dial (future Client
// implementations outside this package simply opt out of worker
// sharing).
func TransportOf(c Client) Transport {
if ci, ok := c.(*clientImpl); ok {
return ci.transport
}
return nil
}
// NamespaceOf returns the namespace a Client was dialed with. Workers
// use it as the default namespace for poll RPCs if the caller's
// worker.Options doesn't override.
func NamespaceOf(c Client) string {
if ci, ok := c.(*clientImpl); ok {
return ci.namespace
}
return ""
}
// IdentityOf returns the identity a Client was dialed with.
func IdentityOf(c Client) string {
if ci, ok := c.(*clientImpl); ok {
return ci.identity
}
return ""
}