Provide a generic "pull-based" queue in the eventqueue package and migrate examples/clustermode to it.
package eventqueue
type PullCursor any
type PullResponse struct {
Messages []*eventqueue.Message
Cursor PullCursor
}
type Puller interface {
Pull(ctx context.Context, taskID a2a.TaskID, cusor PullCursor) (*PullResponse, error)
Close(ctx context.Context) error
}
type PullerProvider func(ctx context.Context, taskID a2a.TaskID) (Puller, error)
func NewStaticPullerProvider(es Puller) PullerProvider { ... }
type PullConfig struct {
PollInterval time.Duration // default 30s
InactivityTimeout time.Duration // default 5m, 0 disables
AccessCheck func(context.Context, *a2a.Task) error // optional
OnInactivity func(context.Context, Puller, a2a.TaskID) error // optional
}
func NewPullQueueManager(pp PullerProvider, cfg PullConfig) eventqueue.Manager { ... }
NewPullQueueManager should create an inner in-memory manager internally. CreateWriter always delegates to the in-memory manage inner. CreateReader delegates to inner unless the call context indicates a resubscribe (a2asrv.CallContextFrom(ctx).Method()), otherwise a pullReader is returned which:
- Calls
Provider to get a per-call Puller.
- Spawns a polling goroutine that calls
Pill every PollInterval, pushes events through a channel, and stops on taskupdate.IsFinal.
- First
Read emits the Snapshot task as the initial event (matches current emittedSnapshot logic).
- Subsequent
Reads either drain the channel, return eventqueue.ErrQueueClosed on final state, return ctx.Err() on
cancellation, or return inactivity error after InactivityTimeout (with optional OnInactivity callback to refresh state).
Destroy delegates to inner. The pull-side reader cleans itself up via Close on the source.
Provide a generic "pull-based" queue in the
eventqueuepackage and migrate examples/clustermode to it.NewPullQueueManagershould create aninnerin-memory manager internally.CreateWriteralways delegates to the in-memory manageinner.CreateReaderdelegates toinnerunless the call context indicates a resubscribe (a2asrv.CallContextFrom(ctx).Method()), otherwise apullReaderis returned which:Providerto get a per-callPuller.PilleveryPollInterval, pushes events through a channel, and stops ontaskupdate.IsFinal.Reademits theSnapshottask as the initial event (matches currentemittedSnapshotlogic).Reads either drain the channel, returneventqueue.ErrQueueClosedon final state, returnctx.Err()oncancellation, or return inactivity error after
InactivityTimeout(with optionalOnInactivitycallback to refresh state).Destroydelegates toinner. The pull-side reader cleans itself up viaCloseon the source.