Reputation: 3205
Let's say I have parallel work I want to do, such as downloading multiple images. Each of these downloads is represented by a SignalProducer
. I create them and flatten them using the Merge
strategy. When I start the outer producer and get a disposable I expected that disposing of that would also dispose of the inner producers. What actually happens is that after disposal, my outer producer stops receiving events, but the actual work being done by the inner producers continues, because they have not been disposed.
How do I get the actual work being done by the inner producers to stop? Here's some test code that illustrates the scenario:
func producerOfValues(values: [String]) -> SignalProducer<String, NoError> {
return SignalProducer<String, NoError> {observer, disposable in
for value in values {
sleep(1)
print("doing work: \(value)")
sendNext(observer, value)
if disposable.disposed { // 'disposed' is never true
print("producer disposed")
break
}
}
sendCompleted(observer)
}
}
let (signal, sink) = SignalProducer<SignalProducer<String, NoError>, NoError>.buffer(2)
let flattened = signal.flatten(.Merge)
let letterProducer = producerOfValues(["a", "b", "c"])
let numberProducer = producerOfValues(["1", "2", "3"])
sendNext(sink, letterProducer.startOn(QueueScheduler()))
sendNext(sink, numberProducer.startOn(QueueScheduler()))
sendCompleted(sink)
let disposable = flattened.startWithNext {
print($0)
}
disposable.dispose()
Output:
doing work: a
doing work: 1
doing work: b
doing work: 2
doing work: c
doing work: 3
Upvotes: 1
Views: 697