- modules/pier: Host contract, mcp.* config, catalog compiled from pact.HasMCP (prefixing, route binding, guard resolution, schema reflection, annotations), per-request identity through the published verifier and resolvers, built-in backend guard provider, in-process dispatch with the bouncer marker, per-identity SDK server with the per-request re-filter, stateful session router with rehydration over a memory store, audit lines - modules/surf/pier_on.go: the summercms_mcp hook adapting the router to pier.Host; the untagged hello binary carries no SDK - go.mod: go-sdk v1.8.0 and jsonschema-go v0.4.3 (decision note committed before this change) - TestPierTracerSmoke: SDK client lists and calls acme_echo end to end through surf's compiled guard chain; README and root table row
47 lines
1.7 KiB
Go
47 lines
1.7 KiB
Go
package pier
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
)
|
|
|
|
// Record is one stored session: the binding key of the identity that opened
|
|
// it, the JSON of the SDK's ServerSessionState once initialised (nil until
|
|
// then) and the creation time.
|
|
type Record struct {
|
|
Binding string `json:"binding"`
|
|
State json.RawMessage `json:"state,omitempty"`
|
|
Created time.Time `json:"created"`
|
|
}
|
|
|
|
// Event is what instances publish to each other: a session ended by DELETE
|
|
// (EventEnded, with SessionID) or a subject change (the pact
|
|
// MCPSubjectChanged kinds, with Guard and UserID). Instance names the
|
|
// publisher so it can skip its own echo when it has already acted.
|
|
type Event struct {
|
|
Kind string `json:"kind"`
|
|
Guard string `json:"guard,omitempty"`
|
|
UserID uint `json:"user_id,omitempty"`
|
|
SessionID string `json:"session_id,omitempty"`
|
|
Instance string `json:"instance,omitempty"`
|
|
}
|
|
|
|
// EventEnded is the kind of a session-ended event.
|
|
const EventEnded = "ended"
|
|
|
|
// Store is the session registry and the event channel shared by every
|
|
// instance of the application: memory for one instance (and tests), Redis
|
|
// for several. Put writes a record with a TTL, Touch slides it, Count
|
|
// answers the live sessions of one binding, Publish and Subscribe carry
|
|
// Events.
|
|
type Store interface {
|
|
Put(ctx context.Context, id string, rec Record, ttl time.Duration) error
|
|
Get(ctx context.Context, id string) (Record, bool, error)
|
|
Touch(ctx context.Context, id string, ttl time.Duration) error
|
|
Delete(ctx context.Context, id string) error
|
|
Count(ctx context.Context, binding string) (int, error)
|
|
Publish(ctx context.Context, ev Event) error
|
|
Subscribe(ctx context.Context, fn func(Event)) error
|
|
}
|