Add race, timeout, and nilTimeout to Guarantee

This adds the following methods to `Guarantee`:

- `Guarantee.race`, a static method. It's like `Promise.race` but it
  returns a Guarantee, not a Promise. (To match `Promise.race`, there
  are actually two versions of this method: one that takes an array of
  Guarantees and one that takes varargs.)
- `timeout`, an instance method. It's like Promise's `timeout` but it
  returns a Guarantee.
- `nilTimeout`, an instance method. It's like Promise's `nilTimeout` but
  it returns a Guarantee.
This commit is contained in:
Evan Hahn 2023-03-14 10:36:28 -05:00 committed by Evan Hahn
parent 941fbecc3d
commit 75f61972e0
2 changed files with 58 additions and 0 deletions

View File

@ -0,0 +1,31 @@
//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public extension Guarantee {
static func race<T>(
on scheduler: Scheduler,
_ guarantees: Guarantee<T>...
) -> Guarantee<T> {
return race(on: scheduler, guarantees)
}
static func race<T>(
on scheduler: Scheduler,
_ guarantees: [Guarantee<T>]
) -> Guarantee<T> {
let (result, future) = Guarantee<T>.pending()
for guarantee in guarantees {
guarantee.done(on: scheduler) { result in
guard !future.isSealed else { return }
future.resolve(result)
}
}
return result
}
}

View File

@ -0,0 +1,27 @@
//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public extension Guarantee {
func nilTimeout(
on scheduler: Scheduler,
seconds: TimeInterval
) -> Guarantee<Value?> {
let withOptionalValue: Guarantee<Value?> = self.map(on: scheduler) { $0 }
return withOptionalValue.timeout(on: scheduler, seconds: seconds, substituteValue: nil)
}
func timeout(
on scheduler: Scheduler,
seconds: TimeInterval,
substituteValue: Value
) -> Guarantee<Value> {
let substitute: Guarantee<Value> = Guarantee<Void>
.after(on: scheduler, seconds: seconds)
.map(on: scheduler) { substituteValue }
return Guarantee<Value>.race(on: scheduler, [self, substitute])
}
}