Files
zip/here.go
T
zeekayandHanzo Dev f048747237 a peer that is this process is a function call, not a socket
zip.Ask names an app and reaches it over that app's canonical socket. When the
app IS this process — a fused binary, or a service asking one of its own ops —
that socket is a loop: the value the caller holds is encoded, handed to the
kernel, read back, and parsed into a copy for a function pointer that was in
memory the whole time. Only the ADDRESSING ever needed a wire, and a by-name
call already has that.

So a bound listener records which App answers for it. Serving(name) reads it
back and Here runs the op through the op's OWN invoke seam — the same
opByName the socket plane uses, the same validate and authorize a REST request
and an MCP tools/call get. registeredOp.direct and registeredOp.invoke now
share one contract closure rather than each carrying a copy, so there is no way
into a handler that skips a check another way makes; direct differs only in
that it is handed the In instead of bytes to decode it from.

Serving goes false before the listeners close, so the in-process door and the
socket cannot disagree about whether the app is up.

This is what a co-resident caller uses instead of building a request for its own
router to take apart again. That pattern cost cloud a re-entrancy counter keyed
on a goroutine id parsed out of runtime.Stack, because dispatching into the
whole app re-ran every edge middleware and a middleware that read the subsystem
it was serving recursed without bound. Entering one op cannot express that.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-05 19:14:00 -07:00

100 lines
4.0 KiB
Go

package zip
import (
"context"
"fmt"
"sync"
)
// here.go — the peer that is not a peer.
//
// [Ask] names an app and reaches it over that app's canonical socket. When the
// app is THIS process, that socket is a loop: the value the caller holds is
// serialized, handed to the kernel, read back, parsed into a fresh copy, and
// dispatched to a function pointer that was in memory the whole time. Nothing
// about the call needed a wire; only the ADDRESSING did, and addressing is
// exactly what a by-name call already has.
//
// So a bound listener records which App answers for it, [Serving] reads that
// back, and [Here] runs the op through the op's OWN invoke seam — the same
// validate → authorize → run core a REST request, an MCP tools/call, a CLI
// command and a socket call all land on. It is one fewer transport, not one more:
// the contract is the op, and only the encoding was ever the transport's.
//
// This is what a co-resident caller uses INSTEAD of building a request for its
// own router to take apart again. That pattern cost cloud a re-entrancy counter
// keyed on a goroutine id parsed out of runtime.Stack, because dispatching a
// request into the whole app re-ran every edge middleware, and a middleware that
// read the app it was serving recursed without bound. A direct op call cannot
// express that shape: it enters one op, not one router.
// serving maps a bound address to the App answering on it. The ADDRESS is the
// key rather than a name, because an address is what a listener has and
// [SocketPath] is already the one mapping from a name to it — so this holds no
// second opinion about where an app lives.
var serving sync.Map // addr -> *App
// bound records that a answers at addr, and returns the undo. Called by
// listenOn for every address it binds.
func bound(addr string, a *App) func() {
serving.Store(addr, a)
return func() { serving.Delete(addr) }
}
// Serving returns the App THIS PROCESS serves at name's canonical socket, or
// nil when the app is somewhere else.
//
// It answers a question a caller has to be able to ask before it spends a wake
// or a dial on a peer that is already in memory. It is a fact about the process,
// not a configuration: an app is here because something in this program bound
// its socket.
//
// Nil is the ordinary answer — a fleet of one-app processes is every app but
// one — and it means "not here", never "not deployed". Absence in the DEPLOYMENT
// is the router's word.
func Serving(name string) *App {
if a, ok := serving.Load(SocketPath(name)); ok {
return a.(*App)
}
return nil
}
// Here invokes op on a — in this process, with no wire under it.
//
// It is [Call] with the Conn removed. The op is found by the same [App.opByName]
// the socket plane uses and run through the same invoke seam, so it validates
// and authorizes identically; what it does NOT do is encode the input, because
// there is nothing between the two ends to encode it for.
//
// The reply is the handler's OWN value. Over a wire a caller gets a fresh copy
// because a wire cannot hand back anything else; here it does not, and a reply
// is a reply — read it, do not write it.
//
// In and Out must be the pair the op declared. A socket call learns that from a
// decode failure at the far end; here it is a type assertion, and the error says
// so plainly.
func Here[In, Out any](ctx context.Context, a *App, op string, in *In) (*Out, error) {
if a == nil {
return nil, fmt.Errorf("zip: %s: no app here", op)
}
// opByName is the ONE by-name lookup — the same one the call plane and
// tools/call run. An op this app does not answer is the same error whichever
// way it was reached.
o := a.opByName(op)
if o == nil || o.direct == nil {
return nil, ErrNotFound("unknown op: " + op)
}
out, err := o.direct(ctx, in)
if err != nil {
return nil, err
}
if out == nil {
return nil, nil
}
reply, ok := out.(*Out)
if !ok {
return nil, fmt.Errorf("zip: %s answers %T, not %T", op, out, reply)
}
return reply, nil
}