Thread Safety for Combine Publishers

I'm not a moderator on the forums, so just my personal 2 cents: I think this forum is a valuable place to have conversations about Combine too. It is clearly the case that the language itself and higher level Swift frameworks have a virtuous circle with each other, so being inclusive in discussions of these topics seems beneficial for everyone in the end.

Now, on to the actual topic at hand.

Here are the thread safety rules for Publisher and Subscriber:

  1. A call to receive(subscriber:) (the implementation-required method) can come from any thread
  2. "Downstream" calls to Subscriber's receive(subscription:), receive(_:), and receive(completion:) must be serialized (but may be on different threads)
  3. "Upstream" calls to Subscription's request(_:) and cancel() must be serialized (but may be on different threads)

This usually results in a lock of some kind in the implementation of Publisher if it maintains a list of Subscribers. For example, PassthroughSubject and CurrentValueSubject do this.

The easiest way to make sure you're following the rules is to simply have your interface privately hold one of these subjects and pass through calls to it.

10 Likes