pub struct TaskEventSink { /* private fields */ }Expand description
Publish wrapper for cross-replica task event fanout. Replaces the
previous tokio::sync::broadcast::Sender<TaskEvent> returned by
A2aDispatcher::event_sink.
The sink shares an Arc<Semaphore> with its parent
A2aDispatcher so Self::send can bound the number of
concurrent in-flight publishes. See Self::send for the
saturation-drop semantics.
Implementations§
Source§impl TaskEventSink
impl TaskEventSink
Sourcepub fn new(pubsub: Arc<dyn Pubsub>) -> Self
pub fn new(pubsub: Arc<dyn Pubsub>) -> Self
Wrap an Arc<dyn Pubsub> for publishing per-task events with a
fresh, single-replica default semaphore
(DEFAULT_PUBLISH_PERMITS permits). Multi-replica deployments
or any wiring that wants to share the dispatcher’s bound should
go through A2aDispatcher::event_sink instead, which threads
the dispatcher’s semaphore through.
Sourcepub fn with_permits(pubsub: Arc<dyn Pubsub>, permits: Arc<Semaphore>) -> Self
pub fn with_permits(pubsub: Arc<dyn Pubsub>, permits: Arc<Semaphore>) -> Self
Wrap an Arc<dyn Pubsub> with an explicit publish-concurrency
semaphore. Used by A2aDispatcher::event_sink to share the
dispatcher’s bound across every sink it hands out. The
semaphore’s available_permits() caps the number of concurrent
publishes Self::send will execute; excess sends drop with
Ok(()) and a warn log.
Sourcepub async fn send(&self, event: TaskEvent) -> Result<(), A2aError>
pub async fn send(&self, event: TaskEvent) -> Result<(), A2aError>
Publish event on the per-task bus subject
klieo.a2a.task.{event.task_id}.
task_id is validated against
klieo_core::validate_subject_token before subject
construction; metacharacters (., *, >, whitespace,
non-ASCII) yield A2aError::Bus(BusError::Invalid(_)),
preventing a caller-controlled task id from collapsing or
wildcarding the subject namespace (CWE-74).
§Backpressure
Acquires a permit from the shared semaphore via
Semaphore::try_acquire_owned BEFORE awaiting the publish.
When the semaphore is saturated the event is dropped, a warn
is logged at target a2a.fanout with
available_permits = 0, and the method returns Ok(()) — task
event fanout is best-effort (matches the cluster-0.18 contract
in crate::task_store::A2aTaskStore which already tolerates
publish failures), and surfacing the saturation as an error
would propagate into store writes that succeeded.
Publish failures surface as A2aError::Bus(_); server-side
encode failures (effectively impossible for a server-built
TaskEvent) surface as A2aError::Internal { source } so
the wire envelope is SERVER_ERROR (-32000) rather than
PARSE_ERROR (-32700). Both preserve e.source() for
downstream tracing.
Trait Implementations§
Source§impl Clone for TaskEventSink
impl Clone for TaskEventSink
Source§fn clone(&self) -> TaskEventSink
fn clone(&self) -> TaskEventSink
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more