@@ -3,7 +3,6 @@ use async_stream::try_stream;
33use aws_config:: BehaviorVersion ;
44use aws_sdk_s3:: Client ;
55use globset:: { Glob , GlobSet , GlobSetBuilder } ;
6- use log:: warn;
76use std:: sync:: Arc ;
87
98use crate :: base:: field_attrs;
@@ -23,6 +22,20 @@ struct SqsContext {
2322 client : aws_sdk_sqs:: Client ,
2423 queue_url : String ,
2524}
25+
26+ impl SqsContext {
27+ async fn delete_message ( & self , receipt_handle : String ) -> Result < ( ) > {
28+ error ! ( "Deleting message: {}" , receipt_handle) ;
29+ self . client
30+ . delete_message ( )
31+ . queue_url ( & self . queue_url )
32+ . receipt_handle ( receipt_handle)
33+ . send ( )
34+ . await ?;
35+ Ok ( ( ) )
36+ }
37+ }
38+
2639struct Executor {
2740 client : Client ,
2841 bucket_name : String ,
@@ -152,24 +165,26 @@ impl SourceExecutor for Executor {
152165 Ok ( PartialSourceRowData { value, ordinal } )
153166 }
154167
155- async fn change_stream ( & self ) -> Result < Option < BoxStream < ' async_trait , SourceChange > > > {
168+ async fn change_stream (
169+ & self ,
170+ ) -> Result < Option < BoxStream < ' async_trait , Result < SourceChangeMessage > > > > {
156171 let sqs_context = if let Some ( sqs_context) = & self . sqs_context {
157172 sqs_context
158173 } else {
159174 return Ok ( None ) ;
160175 } ;
161176 let stream = stream ! {
162177 loop {
163- let changes = match self . poll_sqs( & sqs_context) . await {
164- Ok ( changes) => changes,
178+ match self . poll_sqs( & sqs_context) . await {
179+ Ok ( messages) => {
180+ for message in messages {
181+ yield Ok ( message) ;
182+ }
183+ }
165184 Err ( e) => {
166- warn!( "Failed to poll SQS: {}" , e) ;
167- continue ;
185+ yield Err ( e) ;
168186 }
169187 } ;
170- for change in changes {
171- yield change;
172- }
173188 }
174189 } ;
175190 Ok ( Some ( stream. boxed ( ) ) )
@@ -206,7 +221,7 @@ pub struct S3Object {
206221}
207222
208223impl Executor {
209- async fn poll_sqs ( & self , sqs_context : & Arc < SqsContext > ) -> Result < Vec < SourceChange > > {
224+ async fn poll_sqs ( & self , sqs_context : & Arc < SqsContext > ) -> Result < Vec < SourceChangeMessage > > {
210225 let resp = sqs_context
211226 . client
212227 . receive_message ( )
@@ -220,36 +235,53 @@ impl Executor {
220235 } else {
221236 return Ok ( Vec :: new ( ) ) ;
222237 } ;
223- let mut changes = vec ! [ ] ;
224- for message in messages. into_iter ( ) . filter_map ( |m| m. body ) {
225- let notification: S3EventNotification = serde_json:: from_str ( & message) ?;
226- for record in notification. records {
227- let s3 = if let Some ( s3) = record. s3 {
228- s3
229- } else {
230- continue ;
231- } ;
232- if s3. bucket . name != self . bucket_name {
233- continue ;
234- }
235- if !self
236- . prefix
237- . as_ref ( )
238- . map_or ( true , |prefix| s3. object . key . starts_with ( prefix) )
239- {
240- continue ;
238+ let mut change_messages = vec ! [ ] ;
239+ for message in messages. into_iter ( ) {
240+ if let Some ( body) = message. body {
241+ let notification: S3EventNotification = serde_json:: from_str ( & body) ?;
242+ let mut changes = vec ! [ ] ;
243+ for record in notification. records {
244+ let s3 = if let Some ( s3) = record. s3 {
245+ s3
246+ } else {
247+ continue ;
248+ } ;
249+ if s3. bucket . name != self . bucket_name {
250+ continue ;
251+ }
252+ if !self
253+ . prefix
254+ . as_ref ( )
255+ . map_or ( true , |prefix| s3. object . key . starts_with ( prefix) )
256+ {
257+ continue ;
258+ }
259+ if record. event_name . starts_with ( "ObjectCreated:" )
260+ || record. event_name . starts_with ( "ObjectDeleted:" )
261+ {
262+ changes. push ( SourceChange {
263+ key : KeyValue :: Str ( s3. object . key . into ( ) ) ,
264+ data : None ,
265+ } ) ;
266+ }
241267 }
242- if record. event_name . starts_with ( "ObjectCreated:" )
243- || record. event_name . starts_with ( "ObjectDeleted:" )
244- {
245- changes. push ( SourceChange {
246- key : KeyValue :: Str ( s3. object . key . into ( ) ) ,
247- data : None ,
248- } ) ;
268+ if let Some ( receipt_handle) = message. receipt_handle {
269+ if !changes. is_empty ( ) {
270+ let sqs_context = sqs_context. clone ( ) ;
271+ change_messages. push ( SourceChangeMessage {
272+ changes,
273+ ack_fn : Some ( Box :: new ( move || {
274+ async move { sqs_context. delete_message ( receipt_handle) . await }
275+ . boxed ( )
276+ } ) ) ,
277+ } ) ;
278+ } else {
279+ sqs_context. delete_message ( receipt_handle) . await ?;
280+ }
249281 }
250282 }
251283 }
252- Ok ( changes )
284+ Ok ( change_messages )
253285 }
254286}
255287
0 commit comments