use std::sync::Arc;
use crate::translate::EventKind;
use tokio::io::{AsyncRead, AsyncWrite};
use super::{JsonRpcResponse, PumpContext, PumpState};
pub(super) fn queue_response<R, W>(
context: &PumpContext<R, W>,
state: &mut PumpState,
response: JsonRpcResponse,
) where
R: AsyncRead + Unpin + Send + 'static,
W: AsyncWrite + Unpin + Send + 'static,
{
while let Some(joined) = state.writers.try_join_next() {
if let Err(error) = joined {
tracing::error!(%error, "acp adapter: a peer-request answer task did not complete");
}
}
let connection = Arc::clone(&context.connection);
state.writers.spawn(async move {
if let Err(error) = connection.send_response(&response).await {
tracing::warn!(%error, "acp adapter: could not answer a peer request");
}
});
}
pub(super) fn emit<R, W>(
context: &PumpContext<R, W>,
state: &mut PumpState,
kinds: Vec<EventKind>,
) {
let PumpState {
worker_seq, open, ..
} = state;
match open.as_ref() {
Some(turn) => emit_into(context, worker_seq, Some(&turn.event_tx), kinds),
None => emit_into(context, worker_seq, None, kinds),
}
}
pub(super) fn emit_for<R, W>(
context: &PumpContext<R, W>,
worker_seq: &mut u64,
turn: &super::OpenTurn,
kinds: Vec<EventKind>,
) {
emit_into(context, worker_seq, Some(&turn.event_tx), kinds);
}
fn emit_into<R, W>(
context: &PumpContext<R, W>,
worker_seq: &mut u64,
sender: Option<&tokio::sync::mpsc::UnboundedSender<aion_core::ActivityEvent>>,
kinds: Vec<EventKind>,
) {
for kind in kinds {
let event = context.identity.stamp(*worker_seq, kind);
*worker_seq = worker_seq.saturating_add(1);
if let Some(sender) = sender {
let _ = sender.send(event);
} else {
tracing::warn!(
kind = ?event.kind,
"acp adapter: a frame arrived with no turn open; the transcript stream for the \
last turn is already closed"
);
}
}
}