- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Doth not confuse Observer with Publisher/Subscriber nor with Long Poll...... (yes, the code is an apparent WTF)
Admin
But what about the cat? Is it alive, or is it dead?
Admin
I would say "definitely" instead of "probably". Asynchronous programming is widely misunderstood, even at the best of times. Like when I built a demultiplexer for an application framework, and then someone complained that for a different reason it was hard to build a demultiplexer using the same criterion on top of it.
Or anyone who uses (or maintains)
boost::asio
which is a major bugbear at the moment where I work, because it delivers notifications out-of-order. (In some other notification in the io_context's thread, I cancel timers A, B, C then make a "post" call. Timer B, however, has already expired, but its expiry notification hasn't been delivered yet. I receive notifications, in this order, for A-cancelled, C-cancelled, post-happened, B-expired. That's inexcusable (don't even try to excuse it, I won't listen to you). Anyone with hints on how to force it to deliver notifications in-order is welcome to comment. (Quite frankly, the concept of delivering any notification for a cancelled timer is abhorrent.))Admin
In response to the Easy Reader question: that's petit_princeCase: it's a snake which has eaten a camel.
Admin
I'm suddenly concerned that "Lucas" might be a colleague of mine :D
Admin
Quis observiet ipso observators?
Plures vel non.
Admin
Damn. ipsos, not ipso.
Admin
Steve_The_Cynic - Ahhh you fall into the fallacy that time is linear rather than a "wibbly wobbly timey wimey" condition.
Admin
I maintain that programmers should only be allowed keyboards and mice that cause a light electrical shock on every cut-and-paste.
Admin
Time is convoluted in boost (just like in Lordran).
Now, to be serious, I have learned this lesson twenty years ago, when I wrote a distributed system communicating over TCP and it run just fine on various Linux and Unix systems, but on HP-UX it often failed: as it happened, response to a request was received before the request was sent. Yeah, I was young and naive :-)
Admin
In a purely asynchronous envirinment, it's not only excusable, it's inevitable. At the point where you attempt to cancel, it may have already (just) triggered or have committed to triggering. If it's not purely async (e.g. the timer invokes a callback), then the correct implementation blocks a cancellation if a callback is started until the callback finishes. However delivered events cannot do this, so the event needs to be marked with some form of timestamp or generation number so that when it is received this can be checked and dealt with.
And note that , unless you are running on a single CPU, the concept of 'before' is very complex. Instead you need to have a "happens before" relation which you use to analyse the code. Generally, if you cannot cope with out of order events then you cannot cope with multiple CPUs.
Admin
Yes, but couldn't a library use a Queue for the events associated with a Timer and couldn't that Queue be deleted upon a cancellation event? It could even use a Priority Queue to escalate cancellation.
Admin
When you say Queues, do you mean like Kafka or RabbitMQ? Because it seems like Queues are not purely asynchronous. Which... it seems like Steve_the_Cynic's thing is? Please correct me if I'm way off base.
Admin
Can't you just not listen for cancellation notifications?
Addendum 2022-05-11 18:46: PAY ME NO MIND. I misunderstood.
Admin
Cut & paste would be excusable, but I agree with shocking COPY & paste.
Admin
This is the perfect point for suggesting a classical reading on this topic: Leslie Lamport (yes, the "La" from LaTeX), "Time, Clocks, and the Ordering of Events in a Distributed System". CACM 7(21), July 1978. It is available online at many places, for example here: https://lamport.azurewebsites.net/pubs/time-clocks.pdf
I am always surprised how old this article is, how fundamental it is, and that many of the collegues from now do not know anything of what it is talking about.
Admin
You failed to understand the problem, or maybe I failed to explain it properly. I'm inside the io_context's thread, dealing with a notification. Timer B has just expired, but its callback hasn't yet been called (the notification to call the callback is allegedly in the queue to be delivered). During the callback I'm in, I cancel timers A, B, and C, and then call context.post() to request another action that will follow, theoretically all existing outstanding callbacks.
The expiry callback for timer B, the one that was allegedly already in the queue, happens after the "another action" that I post()ed.
Admin
It's a single thread, and all the events in question are happening in that thread, so the number of CPUs is of exactly no importance.
Admin
Even the first example is wrong. Dealing with Observables only from the view of subscribe() callbacks is its own WTF (the Real WTF?). The point to Observables is composition and pipelines. Subscription callbacks are the side effects at the end of the tunnel and you can do without them. Many good Observable frameworks you never manually subscribe and manual subscription is seen as an anti-pattern.
Admin
If you're getting reordering in that sort of situation, you've got plain old broken code. Yes, a cancellation message could be sent in the time between when an event is committed to occurring and when it happens, but you at least have control over the code that can see that this has happened; dropping the late event is ever so easy and you can have convenient state that decides whether to do it.