项目文件夹

文件
Asim Aslam db4401d306
goreleaser / goreleaser (push) Has been cancelled
client/service: rename the in-process fast-path to Local + service knob (#4855)
Renames the fast-path option to the cleaner Local across the stack (it's
still unreleased) and adds a service-level knob:

- client.Local() (was client.LocalDispatch) enables the in-process
  fast-path; Options.Local is the field. The internal/network package it
  dispatches through is the "local network".
- service.Local() (aliased micro.Local()) turns it on for a whole
  service's client in one place — every co-located unary call (agent tool
  calls, flow dispatch, gateway -> service) takes the fast-path, no
  per-call wiring. Same o.Client.Init(...) pattern the Broker option uses.

Off by default; a no-op for distributed deployments since the fast-path
falls back to the network for anything not co-located.


Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-15 17:02:57 +01:00

61 行
1.7 KiB
Go

package client
import (
"context"
raw "go-micro.dev/v6/codec/bytes"
"go-micro.dev/v6/internal/network"
"go-micro.dev/v6/metadata"
"go-micro.dev/v6/transport"
"go-micro.dev/v6/transport/headers"
)
// localCall is the in-process fast-path for Call. When Local is enabled
// and the callee runs in this same process, a unary request whose body and
// response are raw frames (codec/bytes.Frame) is dispatched straight to the
// server's handlers via internal/network — no dial, no codec-over-socket,
// no transport pump. It returns handled=false to fall back to the network path
// for anything it does not cover (disabled, streaming, non-frame bodies, or a
// service not registered in-process), so behavior is unchanged unless the
// fast-path fully applies.
func (r *rpcClient) localCall(ctx context.Context, req Request, resp interface{}) (handled bool, err error) {
if !r.opts.Local || req.Stream() {
return false, nil
}
reqFrame, ok := req.Body().(*raw.Frame)
if !ok {
return false, nil
}
respFrame, ok := resp.(*raw.Frame)
if !ok {
return false, nil
}
dispatch, ok := network.Lookup(req.Service())
if !ok {
return false, nil
}
header := make(map[string]string)
if md, ok := metadata.FromContext(ctx); ok {
for k, v := range md {
if k == headers.Message { // pub/sub topic header, never forwarded
continue
}
header[k] = v
}
}
header[headers.Request] = req.Service()
header[headers.Endpoint] = req.Endpoint()
header["Content-Type"] = req.ContentType()
header["Accept"] = req.ContentType()
reply, err := dispatch(ctx, &transport.Message{Header: header, Body: reqFrame.Data})
if err != nil {
return true, err
}
if reply != nil {
respFrame.Data = reply.Body
}
return true, nil
}