async-interop / event-loop

An event loop interface for interoperability in PHP.
MIT License
170 stars 9 forks source link

Undefined callback invocation order #80

Closed trowski closed 8 years ago

trowski commented 8 years ago

Certain underlying loop libraries (libev and libuv in particular) do not guarantee that timers with the same expiration are invoked in the order defined. I also was not able to guarantee order when implementing timers using a heap for a native implementation, as heaps do not maintain original order when sorting. Implementing multiple stream watchers when using libuv as a backend requires sorting of watchers on enable/disable to maintain order the order in which the watchers were defined when invoking watcher callbacks.

This PR proposes making watcher invocation order undefined for timers with the same expiration, watchers on the same stream, and watchers on the same signal. Defer watchers must still be invoked in the order enabled and timers with smaller expirations must be invoked before those with larger expirations (even if past-due).

While technically possible, guaranteeing order requires more user-land code depending on the loop backend and generally will slow down the loop. Watcher callback invocation order does not matter for most use-cases and can be implemented by apps or libraries in cases where order does matter.