@@ -17,7 +17,9 @@ use crate::util::get_random_u128;
17
17
use pravega_client_channel:: { create_channel, ChannelSender } ;
18
18
use pravega_client_shared:: { ScopedStream , WriterId } ;
19
19
20
+ use std:: collections:: VecDeque ;
20
21
use tokio:: sync:: oneshot;
22
+ use tokio:: sync:: oneshot:: error:: TryRecvError ;
21
23
use tracing:: info_span;
22
24
use tracing_futures:: Instrument ;
23
25
@@ -75,6 +77,7 @@ use tracing_futures::Instrument;
75
77
pub struct EventWriter {
76
78
writer_id : WriterId ,
77
79
sender : ChannelSender < Incoming > ,
80
+ event_handles : VecDeque < oneshot:: Receiver < Result < ( ) , Error > > > ,
78
81
}
79
82
80
83
impl EventWriter {
@@ -93,6 +96,7 @@ impl EventWriter {
93
96
EventWriter {
94
97
writer_id,
95
98
sender : tx,
99
+ event_handles : VecDeque :: new ( ) ,
96
100
}
97
101
}
98
102
@@ -118,10 +122,13 @@ impl EventWriter {
118
122
pub async fn write_event ( & mut self , event : Vec < u8 > ) -> oneshot:: Receiver < Result < ( ) , Error > > {
119
123
let size = event. len ( ) ;
120
124
let ( tx, rx) = oneshot:: channel ( ) ;
125
+ let ( tx_flush, rx_flush) = oneshot:: channel ( ) ;
121
126
let routing_info = RoutingInfo :: RoutingKey ( None ) ;
122
- if let Some ( pending_event) = PendingEvent :: with_header ( routing_info, event, None , tx) {
127
+ if let Some ( pending_event) =
128
+ PendingEvent :: with_header_flush ( routing_info, event, None , tx, Some ( tx_flush) )
129
+ {
123
130
let append_event = Incoming :: AppendEvent ( pending_event) ;
124
- self . writer_event_internal ( append_event, size, rx) . await
131
+ self . writer_event_internal ( append_event, size, rx, rx_flush ) . await
125
132
} else {
126
133
rx
127
134
}
@@ -137,10 +144,13 @@ impl EventWriter {
137
144
) -> oneshot:: Receiver < Result < ( ) , Error > > {
138
145
let size = event. len ( ) ;
139
146
let ( tx, rx) = oneshot:: channel ( ) ;
147
+ let ( tx_flush, rx_flush) = oneshot:: channel ( ) ;
140
148
let routing_info = RoutingInfo :: RoutingKey ( Some ( routing_key) ) ;
141
- if let Some ( pending_event) = PendingEvent :: with_header ( routing_info, event, None , tx) {
149
+ if let Some ( pending_event) =
150
+ PendingEvent :: with_header_flush ( routing_info, event, None , tx, Some ( tx_flush) )
151
+ {
142
152
let append_event = Incoming :: AppendEvent ( pending_event) ;
143
- self . writer_event_internal ( append_event, size, rx) . await
153
+ self . writer_event_internal ( append_event, size, rx, rx_flush ) . await
144
154
} else {
145
155
rx
146
156
}
@@ -151,8 +161,14 @@ impl EventWriter {
151
161
append_event : Incoming ,
152
162
size : usize ,
153
163
rx : oneshot:: Receiver < Result < ( ) , Error > > ,
164
+ rx_flush : oneshot:: Receiver < Result < ( ) , Error > > ,
154
165
) -> oneshot:: Receiver < Result < ( ) , Error > > {
155
- if let Err ( _e) = self . sender . send ( ( append_event, size) ) . await {
166
+ if let Err ( err) = self . clear_initial_complete_events ( ) {
167
+ // fail fast upon checking previous write events
168
+ let ( tx_error, rx_error) = oneshot:: channel ( ) ;
169
+ tx_error. send ( Err ( err) ) . expect ( "send error" ) ;
170
+ rx_error
171
+ } else if let Err ( _e) = self . sender . send ( ( append_event, size) ) . await {
156
172
let ( tx_error, rx_error) = oneshot:: channel ( ) ;
157
173
tx_error
158
174
. send ( Err ( Error :: InternalFailure {
@@ -161,9 +177,48 @@ impl EventWriter {
161
177
. expect ( "send error" ) ;
162
178
rx_error
163
179
} else {
180
+ self . event_handles . push_back ( rx_flush) ;
164
181
rx
165
182
}
166
183
}
184
+
185
+ /// Flush data.
186
+ ///
187
+ /// It will wait until all pending appends have acknowledgment.
188
+ pub async fn flush ( & mut self ) -> Result < ( ) , Error > {
189
+ while let Some ( receiver) = self . event_handles . pop_front ( ) {
190
+ let recv = receiver. await . map_err ( |e| Error :: InternalFailure {
191
+ msg : format ! ( "oneshot error {:?}" , e) ,
192
+ } ) ?;
193
+
194
+ recv?;
195
+ }
196
+ Ok ( ( ) )
197
+ }
198
+
199
+ /// Clear initial completed events from flush queue.
200
+ fn clear_initial_complete_events ( & mut self ) -> Result < ( ) , Error > {
201
+ while let Some ( mut receiver) = self . event_handles . pop_front ( ) {
202
+ let try_recv = receiver. try_recv ( ) ;
203
+
204
+ match try_recv {
205
+ Err ( TryRecvError :: Empty ) => {
206
+ self . event_handles . push_front ( receiver) ;
207
+ break ;
208
+ }
209
+ Err ( TryRecvError :: Closed ) => {
210
+ let res = try_recv. map_err ( |e| Error :: InternalFailure {
211
+ msg : format ! ( "Trying to flush a closed channel {:?}" , e) ,
212
+ } ) ?;
213
+
214
+ return res;
215
+ }
216
+ Ok ( _) => { }
217
+ }
218
+ }
219
+
220
+ Ok ( ( ) )
221
+ }
167
222
}
168
223
169
224
impl Drop for EventWriter {
0 commit comments