• (nodebb)

    Doth not confuse Observer with Publisher/Subscriber nor with Long Poll...... (yes, the code is an apparent WTF)

  • Industrial Automation Engineer (unregistered)

    But what about the cat? Is it alive, or is it dead?

  • (nodebb)

    Probably both.

    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::asiowhich 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.))

  • RLB (unregistered)

    In response to the Easy Reader question: that's petit_princeCase: it's a snake which has eaten a camel.

  • AnAnonDevLead (unregistered)

    I'm suddenly concerned that "Lucas" might be a colleague of mine :D

  • WTFGuy (unregistered)

    Quis observiet ipso observators?

    Plures vel non.

  • WTFGuy (unregistered)

    Damn. ipsos, not ipso.

  • (nodebb)

    Steve_The_Cynic - Ahhh you fall into the fallacy that time is linear rather than a "wibbly wobbly timey wimey" condition.

  • pif (unregistered)

    it was then copy-pasted all over

    I maintain that programmers should only be allowed keyboards and mice that cause a light electrical shock on every cut-and-paste.

  • (nodebb) in reply to TheCPUWizard

    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 :-)

  • Charles (unregistered) in reply to Steve_The_Cynic

    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.

  • Yikes (unregistered) in reply to Charles

    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.

  • (nodebb) in reply to Yikes

    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.

  • (nodebb) in reply to Steve_The_Cynic

    Can't you just not listen for cancellation notifications?

    Addendum 2022-05-11 18:46: PAY ME NO MIND. I misunderstood.

  • Backseat driver (unregistered) in reply to pif

    Cut & paste would be excusable, but I agree with shocking COPY & paste.

  • asynchronous (unregistered) in reply to Charles

    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.

    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.

  • (nodebb) in reply to Charles

    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.

    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.

  • (nodebb) in reply to Charles

    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.

    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.

  • Max (unregistered)

    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.

  • (nodebb) in reply to Steve_The_Cynic

    It's a single thread, and all the events in question are happening in that thread

    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.

  • ram shah (unregistered)
    Comment held for moderation.
  • ram shah (unregistered)
    Comment held for moderation.
  • BusCharter NationwideUSA (unregistered)
    Comment held for moderation.

Leave a comment on “Observing the Observer”

Log In or post as a guest

Replying to comment #:

« Return to Article