gproxy_protocol/adapt/generate/stream/fanout/
mod.rs1mod bridge;
5mod driver;
6mod event;
7mod images;
8mod prepare;
9mod run;
10
11use super::{
12 StreamChunk, StreamInvocation, StreamSettings, StreamStart, bridge::StreamBridge,
13 event::NativeEvent, invoke::ClientFull, output::Encoder,
14};
15use super::{codec_error, conflict, invalid, limit};
16use crate::{
17 adapt::generate::{
18 GenerationStateAccess,
19 fanout::{FanoutOptions, group_id},
20 },
21 capability::StateStore,
22 transform::{
23 Report, TransformError,
24 identity::{IdentityFlow, IdentityRole},
25 },
26};
27use std::collections::{BTreeMap, BTreeSet};
28
29pub use bridge::FanoutBridge;
30pub use event::FanoutEvent;
31
32pub struct FanoutStream<B: FanoutBridge>
35where
36 B::ClientEvent: FanoutEvent,
37{
38 children: Vec<StreamInvocation<B>>,
39 id: String,
40 settings: StreamSettings,
41 index: usize,
42 seeded: bool,
43 seen: BTreeMap<String, usize>,
44 response_ids: BTreeSet<String>,
45 completed: Vec<ClientFull<B>>,
46 encoder: Encoder,
47 collector: Option<<B::ClientEvent as NativeEvent>::Collector>,
48 created: Option<i64>,
49 report: Report,
50 aggregate: Option<ClientFull<B>>,
51 tail: Option<B::ClientEvent>,
52 tail_emitted: bool,
53 emit_usage: bool,
54 finished: bool,
55 failed: bool,
56
57 retained_bytes: usize,
58}
59
60impl<B: FanoutBridge> FanoutStream<B>
61where
62 B::ClientEvent: FanoutEvent,
63{
64 async fn new<S: StateStore>(
65 mut children: Vec<StreamInvocation<B>>,
66 options: FanoutOptions,
67 state: &GenerationStateAccess<'_, S>,
68 ) -> Result<Self, TransformError> {
69 let ids: Vec<_> = children
70 .iter()
71 .map(|v| v.selected.identities.clone())
72 .collect();
73 let id = group_id(&options)?;
74 let settings = children[0].settings;
75
76 for child in &children {
77 child.binding.check(state)?;
78 }
79 let collector = B::ClientEvent::collector(
80 IdentityFlow::new(options.namespace),
81 ids[0].response_policy.clone(),
82 settings.events,
83 );
84 let emit_usage = children[0].emit_usage;
85 for child in &mut children {
88 child.emit_usage = true;
89 }
90 let response_ids = BTreeSet::from([id.clone()]);
91 Ok(Self {
92 children,
93 id,
94 settings,
95 index: 0,
96 seeded: false,
97 seen: Default::default(),
98 response_ids,
99 completed: Vec::new(),
100 encoder: Encoder::new(settings.client_framing, settings.codec),
101 collector: Some(collector),
102 created: None,
103 report: Report::default(),
104 aggregate: None,
105 tail: None,
106 tail_emitted: false,
107 emit_usage,
108 finished: false,
109 failed: false,
110
111 retained_bytes: 0,
112 })
113 }
114 pub fn children(&self) -> &[StreamInvocation<B>] {
115 &self.children
116 }
117 pub fn response_id(&self) -> &str {
118 &self.id
119 }
120 pub fn report(&self) -> &Report {
121 &self.report
122 }
123 pub fn client_result(&self) -> Option<&ClientFull<B>> {
124 self.aggregate.as_ref()
125 }
126 fn fail(&mut self) {
127 self.failed = true;
128 for child in &mut self.children {
129 child.reader = None;
130 }
131 }
132 fn emit(
133 &mut self,
134 event: B::ClientEvent,
135 ) -> Result<StreamChunk<B::ClientEvent>, TransformError> {
136 let bytes = self.encoder.event(&event, self.settings.codec)?;
137 Ok(StreamChunk {
138 event: Some(event),
139 bytes,
140 finished: false,
141 })
142 }
143}