Multicasting of cold signals in RAC3/4

96 Views Asked by At

I want to have two cold SignalProducers B and C, both of them depends on other cold SignalProducer A, which emits db entity objects — so it's critical for me to multicast so exactly same object arrive to both B and C. Here is some graph:

     --(transformations)--B
    /
-A ----(transformations)--C

But because B and C has some transformations, which may require significant amount of work, I don't want them to happen until they are connected.

In RAC2 we had [[RACSignal-publish]-autoconnect] which worked ok in this case.

As CHANGELOG says, multicasting from RAC2 made cleaner with startWithSignal, but it 1) starts immediately, 2) pushes me to use hot signal all over the rest of the chain

SignalProducer.buffer seems so be an acceptable solution.

What is the proper solution in this case?

1

There are 1 best solutions below

0
ReDetection On

Currently I reimplemented -publish -autoconnect from RAC2 in RAC3/Swift1.2 like that:

func buffer<T, E>(capacity: Int) -> SignalProducer<T, E> -> SignalProducer<T, E> {
    return { (signal: SignalProducer<T, E>) -> SignalProducer<T, E> in

        let (buffer, bufferSink) = SignalProducer<T, E>.buffer(capacity)
        var connectionsCount = 0
        var upperDisposable: Disposable? = nil

        let addSubscriber: ()->() = {
            if (connectionsCount == 0) {
                upperDisposable = signal.start(bufferSink)
            }
            connectionsCount++
        }

        let removeSubscriber: ()->() = {
            connectionsCount--
            if connectionsCount == 0 {
                upperDisposable?.dispose()
                upperDisposable = nil
            }
        }


        return SignalProducer { (sink, disposable) in
            disposable.addDisposable(removeSubscriber)
            sendNext(sink, buffer)
            addSubscriber()
        }
        |> flatten(.Concat)
    }
}

It's not thread safe and probably can contain other issues