All the runScheduledAction complexity seems to be redundant
From the https://github.com/haskell-distributed/network-transport-tcp/commit/3855e91dcad7381f6626fc47adb8f4c9c60d5279:
Simply doing
thingToSend <- modifyMVar (....) send thingToSend
is not good enough, because now if we have to threads doing the above the sends may be done in the wrong order.
Before https://github.com/haskell-distributed/network-transport-tcp/commit/876a3dc94e516c9ec60ea8b0a65ea3f13b8c1f27 it was true. But after sendOn was protected with MVar it seems that it became redundant, because, as @simonmar states in his book:
if a thread T is blocked in takeMVar and there are regular putMVar operations on the same MVar, it is guaranteed that at some point thread T’s takeMVar will return. In GHC, this guarantee is implemented by keeping blocked threads in a FIFO queue attached to the MVar...
In other words, the first thread called sendOn and blocked on MVar will be served first when the MVar will be available (if I understood correctly the book). So it seems that "simply doing" approach mentioned in the beginning will just do. No?
CC @edsko
Sorry, there was some misunderstanding from my side - I missed the fact that we want to keep the order in which modifyMVar on remote EP state is done.
The effectiveness of runScheduledAction is a long-standing question (#24).
In sum, it is not clear exactly why the ordering matters. And if the order matters as conjectured in haskell-distributed/distributed-process#440, runScheduledAction doesn't ensure it.
Right. The ordering is ensured by MVar and its FIFO scheduling in GHC (see my quote above from the book). runScheduledAct and schedule approach just ensures that the MVar is taken in the same order in which it was scheduled (by the schedule function). (I mean the MVar from sendOn, for example). This, in turn, is provided by getting the actions from the channel in the FIFO order by runScheduledAction. So it is not important in which order the threads will execute runScheduledAction - all the scheduled actions will be executed from the channel in the right order. (I.e. the sendOn's MVar, for example, will be taken in the right order.)
However, all this is true provided the operation of taking the action from the channel and executing that action at runScheduledAction (code) is atomic, which I'm not sure of...