use bb_ir::proto::onnx::NodeProto;
use bb_runtime::atomic::DispatchResult;
use bb_runtime::bus::OpError;
use bb_runtime::runtime::RuntimeResourceRef;
use bb_runtime::slot_value::SlotValue;
pub struct BackoffGateRxOp;
pub const DOMAIN: &str = "ai.bytesandbrains.syscall";
pub const OP_TYPE: &str = "BackoffGateRx";
pub fn invoke(
_node: &NodeProto,
inputs: &[(&str, &dyn SlotValue)],
ctx: &mut RuntimeResourceRef<'_>,
) -> Result<DispatchResult, OpError> {
let (_, value) = inputs.first().ok_or_else(|| OpError {
detail: "BackoffGateRx requires one input".into(),
..Default::default()
})?;
let Some(src_peer) = ctx.current.inbound.src_peer else {
return Err(OpError {
detail: "BackoffGateRx: no envelope source peer in runtime context".into(),
..Default::default()
});
};
let now_ns = ctx.time.scheduler.now_ns();
if ctx.peers.backoff.should_retry(src_peer, now_ns) {
Ok(DispatchResult::Immediate(vec![(
"value".to_string(),
value.clone_boxed(),
)]))
} else {
Err(OpError {
detail: format!(
"BackoffGateRx dropped envelope from peer {src_peer:?}: reason=cooldown"
),
..Default::default()
})
}
}
use bb_runtime::registry::OpRegistration as _BbOpsSyscallReg;
inventory::submit! {
_BbOpsSyscallReg {
domain: DOMAIN,
op_type: OP_TYPE,
invoke,
kind: bb_runtime::registry::RegistrationKind::Syscall,
}
}