@ -110,10 +110,17 @@ public enum ConfigurationSyncJob: JobExecutor {
. collect ( )
. eraseToAnyPublisher ( )
}
. map { ( responses : [ HTTP . BatchResponse ] ) -> [ SuccessfulChange ] in
. flatMap { ( responses : [ HTTP . BatchResponse ] ) -> AnyPublisher < [ SuccessfulChange ] , Error > in
// W e m a k e a s e q u e n c e c a l l f o r t h i s s o i t ' s p o s s i b l e t o g e t f e w e r r e s p o n s e s t h a n
// e x p e c t e d s o i f t h a t h a p p e n s f a i l a n d r e - r u n l a t e r
guard responses . count = = pendingSwarmConfigChanges . count else {
return Fail ( error : HTTPError . invalidResponse )
. eraseToAnyPublisher ( )
}
// P r o c e s s t h e r e s p o n s e d a t a i n t o a n e a s y t o u n d e r s t a n d f o r ( t h i s i s n ' t s t r i c t l y
// n e e d e d b u t t h e c o d e g e t s c o n v o l u t e d w i t h o u t t h i s )
zip ( responses , pendingSwarmConfigChanges )
let successfulChanges : [ SuccessfulChange ] = zip ( responses , pendingSwarmConfigChanges )
. compactMap { ( batchResponse : HTTP . BatchResponse , pendingSwarmChange : SingleDestinationChanges ) -> [ SuccessfulChange ] ? in
let maybePublicKey : String ? = {
switch pendingSwarmChange . destination {
@ -145,6 +152,7 @@ public enum ConfigurationSyncJob: JobExecutor {
guard
let subResponse : HTTP . BatchSubResponse < SendMessagesResponse > = ( next . response as ? HTTP . BatchSubResponse < SendMessagesResponse > ) ,
200. . . 299 ~= subResponse . code ,
! subResponse . failedToParseBody ,
let sendMessageResponse : SendMessagesResponse = subResponse . body
else { return }
@ -162,6 +170,10 @@ public enum ConfigurationSyncJob: JobExecutor {
}
}
. flatMap { $0 }
return Just ( successfulChanges )
. setFailureType ( to : Error . self )
. eraseToAnyPublisher ( )
}
. map { ( successfulChanges : [ SuccessfulChange ] ) -> [ ConfigDump ] in
// N o w t h a t w e h a v e t h e s u c c e s s f u l c h a n g e s , w e n e e d t o m a r k t h e m a s p u s h e d a n d
@ -189,6 +201,13 @@ public enum ConfigurationSyncJob: JobExecutor {
}
}
. sinkUntilComplete (
receiveCompletion : { result in
switch result {
case . finished : break
case . failure ( let error ) :
failure ( job , error , false )
}
} ,
receiveValue : { ( configDumps : [ ConfigDump ] ) in
// F l a g t o i n d i c a t e w h e t h e r t h e j o b s h o u l d b e f i n i s h e d o r w i l l r u n a g a i n
var shouldFinishCurrentJob : Bool = false
@ -209,12 +228,17 @@ public enum ConfigurationSyncJob: JobExecutor {
let existingJob : Job = try ? Job
. filter ( Job . Columns . id != job . id )
. filter ( Job . Columns . variant = = Job . Variant . configurationSync )
. fetchOne ( db ) ,
! JobRunner . isCurrentlyRunning ( existingJob )
. fetchOne ( db )
{
_ = try existingJob
. with ( nextRunTimestamp : nextRunTimestamp )
. saved ( db )
// I f t h e n e x t j o b i s n ' t c u r r e n t l y r u n n i n g t h e n d e l a y i t ' s s t a r t t i m e
// u n t i l t h e ' n e x t R u n T i m e s t a m p '
if ! JobRunner . isCurrentlyRunning ( existingJob ) {
_ = try existingJob
. with ( nextRunTimestamp : nextRunTimestamp )
. saved ( db )
}
// I f t h e r e i s a n o t h e r j o b t h e n w e s h o u l d f i n i s h t h i s o n e
shouldFinishCurrentJob = true
return job
}
@ -302,10 +326,10 @@ public extension ConfigurationSyncJob {
@ discardableResult static func createOrUpdateIfNeeded ( _ db : Database ) -> Job {
// T r y t o g e t a n e x i s t i n g j o b ( i f t h e r e i s o n e t h a t ' s n o t r u n n i n g )
if
let existingJob : Job = try ? Job
let existingJob s : [ Job ] = try ? Job
. filter ( Job . Columns . variant = = Job . Variant . configurationSync )
. fetch One ( db ) ,
! JobRunner . isCurrentlyRunning ( existingJob )
. fetch All ( db ) ,
let existingJob : Job = existingJobs . first ( where : { ! JobRunner . isCurrentlyRunning ( $0 ) } )
{
return existingJob
}