Last active
April 20, 2020 15:46
-
-
Save jasdev/56bc22532bda31797ab84a006806c874 to your computer and use it in GitHub Desktop.
`ReplaySubject` with `.send(completion:)`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final class ReplaySubject<Output, Failure: Error>: Subject { | |
typealias Output = Output | |
typealias Failure = Failure | |
private let bufferSize: Int | |
private var completion: Subscribers.Completion<Failure>? /// (1) We’ll need to hold onto any received completion event. | |
private var isActive: Bool { /// (2) Providing a more readable shim over `completion`, we can lean on this | |
/// computed property to bottom out any value or completion events sent after the first (since forwarding them | |
/// through would likely cause undefined behavior in the subscription graph). | |
completion == nil | |
} | |
private var subscriptions = [Subscription]() /// (3) Holding onto any existing subscriptions, so we can | |
/// forward completions their way. | |
init(bufferSize: Int) { | |
self.bufferSize = bufferSize | |
} | |
func send(subscription: Combine.Subscription) { | |
subscription.request(.unlimited) | |
} | |
func send(completion: Subscribers.Completion<Failure>) { | |
guard isActive else { return } /// (4) Fence off any completions received after the first. | |
self.completion = completion | |
subscriptions.forEach { $0.forward(completion: completion) } /// (5) Forwarding completions. For now, let’s | |
/// add a placeholder `ReplaySubject.Subscription.forward(completion:)` method over at `(6)`. | |
} | |
func send(_ value: Output) { /* … */ } | |
func receive<Subscriber: Combine.Subscriber>( | |
subscriber: Subscriber | |
) where Failure == Subscriber.Failure, Output == Subscriber.Input { /* … */ } | |
} | |
extension ReplaySubject { | |
final class Subscription: Combine.Subscription { | |
func request(_ demand: Subscribers.Demand) { /* … */ } | |
func cancel() { /* … */ } | |
func forward(completion: Subscribers.Completion<Failure>) { /// (6) To be filled in, soon. | |
/* … */ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment