Documentation
¶
Overview ¶
Package messaging delivers intermediate input through ordinary Dispatcher Effects. A Message freezes one concrete recipient, optional WaitID, and payload. Dispatcher derives its SignalID from the sending EffectID and submits exactly one Signal through a Host-bound DeliveryPort. Mailboxes retain admission, deduplication, accounting, and committed consumption ownership.
The port must authorize the sender and concrete recipient and validate the receiver's payload contract. A logical address must be resolved before the Effect is prepared; replay must never select a replacement gate or episode. The sender and receiver have separate acknowledgment boundaries. No atomic cross-tree transaction or runtime-attested origin is implied by this adapter.
A duplicate single-Signal admission is successful delivery. Every port error remains unknown, including a terminal recipient after an earlier ambiguous attempt. A port can reconcile against the original recipient's authoritative ProcessSnapshot.SignalReceipts, using SignalReceipt.Matches to prove admission even after consumption. Internal wait-opening and child-wait settlement Signals cannot prove external delivery; matching identity and payload alone are insufficient. A missing receipt in an old snapshot proves nothing. Pending Effects may replay under the same identity. Settled Unknown results require explicit adjudication through Process.ResolveUnknownEffect.
Strategies controlling their own direct children use agent.SignalChild for one tree acknowledgment. This adapter serves Host-authorized delivery across other ownership boundaries, including independent root trees.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidMessage = errors.New("messaging: invalid message")
var ErrNilDeliveryPort = errors.New("messaging: delivery port is required")
ErrNilDeliveryPort rejects construction without a delivery authority.
Functions ¶
This section is empty.
Types ¶
type DeliveryPort ¶
type DeliveryPort interface {
Deliver(ctx context.Context, sender, recipient agent.ProcessID, signal agent.SignalRequest) error
}
DeliveryPort admits one Signal to the supplied concrete recipient. The implementation owns destination authority and payload validation, preserves the recipient across replay, and uses atomic single-Signal admission. A nil error confirms that this exact Signal was admitted, either by this call or an earlier identical delivery. New and duplicate admissions share the same acknowledgment contract; the mailbox owns admission accounting. Errors never prove the message was not admitted by this attempt or a previous one. Calls must honor ctx, be bounded and concurrency-safe, and may reconcile authoritative receipts before reporting a terminal recipient error. Retention must preserve identity conflicts and admission evidence for the entire replay obligation.
type Dispatcher ¶
type Dispatcher struct {
// contains filtered or unexported fields
}
Dispatcher delivers each frozen Message under one Effect-derived SignalID. It owns no retry loop, mailbox, routing registry, or background work.
func NewDispatcher ¶
func NewDispatcher(config DispatcherConfig) (*Dispatcher, error)
func (*Dispatcher) Dispatch ¶
func (d *Dispatcher) Dispatch(ctx context.Context, request agent.EffectRequest, _ agent.DeltaEmitter) (agent.Settlement, error)
Dispatch requires a non-nil context and panics if ctx is nil.
func (*Dispatcher) ReplayPolicy ¶
func (d *Dispatcher) ReplayPolicy(effect agent.Effect) agent.ReplayPolicy
type DispatcherConfig ¶
type DispatcherConfig struct {
Port DeliveryPort
}
DispatcherConfig binds the only delivery authority used by this Dispatcher. Its policy and routing configuration belong in the Deployment's exact binding.
type Message ¶
type Message struct {
Recipient agent.ProcessID `json:"recipient"`
WaitID *agent.WaitID `json:"wait_id,omitempty"`
Payload agent.Input `json:"payload"`
}
Message is a request to deliver one input to a concrete Process address. Recipient and WaitID must remain bound to this payload across restoration.
func (Message) Effect ¶
Effect freezes the message as one external operation. Multiple recipients require independent Effects and independently visible settlements.
Example ¶
package main
import (
"fmt"
agent "github.com/Tangerg/scope/agent"
"github.com/Tangerg/scope/agent/messaging"
)
func main() {
recipient, err := agent.ParseProcessID("process:review-coordinator")
if err != nil {
panic(err)
}
payload, err := agent.EncodeInput("The proposed budget needs revision.")
if err != nil {
panic(err)
}
message := messaging.Message{Recipient: recipient, Payload: payload}
effect, err := message.Effect()
if err != nil {
panic(err)
}
// Return this Effect from Step and bind messaging.Dispatcher to the
// Deployment. The Host's DeliveryPort authorizes this concrete recipient.
fmt.Println(effect.Target())
fmt.Println(message.Recipient)
}
Output: dispatcher process:review-coordinator