pub trait PushSender:
Send
+ Sync
+ 'static {
// Required method
fn send<'a>(
&'a self,
url: &'a str,
event: &'a StreamResponse,
config: &'a TaskPushNotificationConfig,
) -> Pin<Box<dyn Future<Output = A2aResult<()>> + Send + 'a>>;
// Provided methods
fn allows_private_urls(&self) -> bool { ... }
fn max_delivery_duration(&self) -> Option<Duration> { ... }
}Expand description
Trait for delivering push notifications to client webhooks.
Object-safe; used as Box<dyn PushSender>.
Required Methods§
Provided Methods§
Sourcefn allows_private_urls(&self) -> bool
fn allows_private_urls(&self) -> bool
Returns true if this sender allows webhook URLs targeting
private/loopback addresses. Used by the handler to skip SSRF
validation at push config creation time in testing environments.
Default: false (SSRF protection enabled).
Sourcefn max_delivery_duration(&self) -> Option<Duration>
fn max_delivery_duration(&self) -> Option<Duration>
The longest a single send can take, if this sender can
say — its whole retry schedule, not one attempt.
§Why this exists
Background delivery bounds every send with
HandlerLimits::push_delivery_timeout, and a sender whose own
schedule is longer than that bound never finishes it. At the shipped
defaults the two contradict: HttpPushSender promises three attempts
at 30s each with [1s, 2s] backoff — 93s — against a 5-second bound.
Measured 2026-08-19 against a real socket: exactly one of the three
attempts reaches the webhook, and the outer timeout fires at 5.001s.
max_attempts and backoff are, at the defaults, configuration that
cannot take effect.
Reporting a duration here lets the server tell “your webhook is slow”
apart from “your two timeouts disagree” — see
push_outcome::TIMEOUT_TRUNCATED.
Default: None, meaning “I cannot say”. A None sender is never
reported as truncated, because nothing is known to have been cut short.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".