Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signal adaptivity. #163

Closed
andersio opened this issue Dec 18, 2016 · 2 comments
Closed

Signal adaptivity. #163

andersio opened this issue Dec 18, 2016 · 2 comments
Labels

Comments

@andersio
Copy link
Member

andersio commented Dec 18, 2016

We usually have lots of Signals sticking around. But not all of them is always in use at any point — by "in use", I mean a Signal graph as a whole is not observed by anyone. Some can be freed in this circumstance, e.g. Notification signals if not transformed, but generally they cannot.

Let's say reactive.trigger(for: selector) — it creates a Signal that would stick around forever until the object is gone. So it still costs a bit CPU time even if it gets no observers. Convenience Signals, e.g. Action.values, Action.errors, also fall into this category.

Inspired by CwlSignal's notion of activation, we might optimize this by having adaptive Signals.

Signal adaptivity

What does adaptivity mean to a Signal?

It means a Signal would adapt to the situations that the event delivery would not yield an substantial effect, and would deactivate accordingly. Deactivation means all subsequent value events received are silently dropped until reactivation.

Deactivated Signal can be reactivated simply by attaching an observer.

Currently, value events would be going through the entire event delivery routine — and all the derived Signals — even if eventually it would reach no one.

Limited propagation

Edit: While Signal adaptivity is designed to cater a Signal graph, only stateless Signals should propagate the deactivation. In other words, adaptivity is an opt-in.

For example, stateful operators like combineLatest rely on being always informed of the latest value, and therefore should not inform its upstream of its deactivation at all.

How would it work?

First, we would have to make a distinction between the types of Signal observers:

  1. external observers.
  2. event emitters of a Signal's descendants.

With that, we would define that a Signal should deactivate if it has:

  1. no external observer; and
  2. its descendants has all declared inactivation

Similarly, we would define that a Signal should reactivate if:

  1. is deactivated; AND
  2. is attached with a external observer; or
  3. is informed the reactivation of its descendants.

This requires a reversed channel to the event flow, similarly to producer interruption.

Is it breaking?

Apparently yes. But not for the general crowd of ReactiveSwift. It affects the same group of audience as the new Signal lifetime semantic.

The introduction of Signal adaptivity would further restrict the Signal semantic:

  • If a Signal graph does not have any external observer, injected side effects (e.g. on) would not be evaluated.

How does it affect the public API?

It is expected not to affect the public API at all, except for the bit about lifetime we've just mentioned.

Synergy with #144 (Remove interrupted)

With a real reversed channel, #144 may share it with Signal adaptivity, and eliminate the workarounds of startWithSignal.

@mdiep
Copy link
Contributor

mdiep commented Dec 24, 2016

The idea definitely makes sense. It's reminiscent of #140. But it's hard to know for sure what this will look like.

@andersio
Copy link
Member Author

andersio commented Jan 14, 2017

Sadly, after a second thought, the adaptivity cannot be propagated in all cases, as we have many operators being stateful and events should not be dropped at all for them.

Only stateless operators like map and mapError can take advantage of this, and fortunately it still covers all the said use cases.

@andersio andersio removed this from the 2.0 milestone Jan 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants