Live data from Hacker News

Queue Despair: Ordering and Poison Messages

openmymind.net

21–30 of 49 posts

Re: Queue Despair: Ordering and Poison Messages

#21
post #14

Earlier quoted context omitted.

Because SmartThings was born out of a software consultancy that knew how to do backend cloud services, but not embedded. The v1 hub was just a pic microcontoller that sent raw radio messages up to the cloud for all parsing and processing.

(1) If you are letting people code their own event handlers you wouldn't trust them to run them on a tiny machine like that. (2) A system like that probably wants to be able to respond to events both inside and outside the house. For instance, turn on your lights remotely with a phone. A cloud component is the reliable way to do that. (3) At the time I couldn't find decent Zigbee or ZWave hubs other than the SmartThi…

> If you are letting people code their own event handlers you wouldn't trust them to run them on a tiny machine like that.

Actually, you can do exactly that now: https://developer-preview.smartthings.com/docs/devices/hub-c... Though that's only for device integrations, so not an exact solution to removing the cloud from the loop on your stuff.

ST is slowly getting away from being totally cloud-centric.

Re: Queue Despair: Ordering and Poison Messages

#22

Ordering is too expensive. Don't ever count on it when using an asynchronous queue. It's akin to storing session in a cache -- you're mixing your metaphors. A queue should NEVER drop messages - otherwise it's a shit queue. Or you have a bug in your application code that needs to be fixed. Poison messages are DEFINITELY A SMELL. This means you essentially have a broken interface contract. The code that is adding messa…

...it might be a smell, but they sure are bound to happen eventually; Corrupt user state or unhanded corner cases etc. Better plan for that in advance.

This is why I prefer putting the "bad" message into a deadletter queue instead of dropping it entirely(and alert on messages going into this queue). This unblocks the queue so it can continue working and allows one to decide if it should be dropped or re-processed.

Re: Queue Despair: Ordering and Poison Messages

#23

Ordering is too expensive. Don't ever count on it when using an asynchronous queue. It's akin to storing session in a cache -- you're mixing your metaphors. A queue should NEVER drop messages - otherwise it's a shit queue. Or you have a bug in your application code that needs to be fixed. Poison messages are DEFINITELY A SMELL. This means you essentially have a broken interface contract. The code that is adding messa…

> Ordering is too expensive. Don't ever count on it when using an asynchronous queue

In a field where precision is absolutely necessary, it's unfortunate to use the term queue to describe something that is not a queue.

Re: Queue Despair: Ordering and Poison Messages

#24
Sidekiq has a lot of code to deal with both of these issues.

Sidekiq does not guarantee ordering within a queue; that’s a terrible, very expensive guarantee. Developers don’t want total ordering of jobs within a queue, they want to know that Job A will fully execute before Job B. There might be 1000 other jobs in the queue that are completely independent of that ordering but we’ve screwed ourselves by forcing total queue ordering. Instead Sidekiq Pro provides a workflow API, Sidekiq::Batch, which allows the developer to author higher-level workflows for Job A -> Job B which provides the ordering guarantee.

For poison pills, we detect jobs which were running when a Sidekiq process died. If this happens multiple times, the job will be sent to the dead letter queue so the developer can deal with them manually. If they were part of a Batch, the workflow will stall until the developer fixes the issue and executes the job manually to resume the workflow.

Re: Queue Despair: Ordering and Poison Messages

#25
post #23

Ordering is too expensive. Don't ever count on it when using an asynchronous queue. It's akin to storing session in a cache -- you're mixing your metaphors. A queue should NEVER drop messages - otherwise it's a shit queue. Or you have a bug in your application code that needs to be fixed. Poison messages are DEFINITELY A SMELL. This means you essentially have a broken interface contract. The code that is adding messa…

> Ordering is too expensive. Don't ever count on it when using an asynchronous queue In a field where precision is absolutely necessary, it's unfortunate to use the term queue to describe something that is not a queue.

Curious, what's your definition of queue?

Re: Queue Despair: Ordering and Poison Messages

#26

> Even if we ignore poison messages, strict ordering on its own isn't that easy to pull off. Namely, you're limited to a single consumer and can only fetch one message at a time. Yup. If you want to be sure, you need to persist which message for each entity X you have already processed and ignore older ones. And also make sure you handle race conditions where both messages are handled almost at the same time at two d…

Have you considered frameworks like Orleans? Presumably you would have an individual actor “grain” for each vehicle and it would serialise the messages to it for you.

The state of the vehicle is kept in memory for some time.

Re: Queue Despair: Ordering and Poison Messages

#28
> Adding a timestamp to each message is an easy way for consumers to discard any out-of-order messages.

Not correct, but it's very easy to think timestamps will solve this. Timestamps aren't good because system times aren't synced across different computers precisely. Meaning if Producer A creates the first event, and Producer B creates a second event 50ms after (imagine a single row gets updated very quickly twice), but the system time on Producer A is 100ms ahead of Producer B and the event from Producer B gets to the consumers first (variable network latency), the event from Producer A will look like the latest event from a timestamp perspective and overwrite the Producer B event.

One way to solve is it to use not use timestamps, but use a monotonically increasing version number associated with a row that gets updated for every event/update or whatever and is sent along with the event message payload. The book, Designing data intensive systems, goes into this problem a whole lot. Recommend it to anyone discussing architecture. Issues like this will seem obvious to you after reading

Re: Queue Despair: Ordering and Poison Messages

#29
Total ordering is rarely required, and even more rarely actually possible (without lamport or atomic clocks etc).

For more common use cases it is possible to provide the minimum guarantees required to reliably reconstruct a domain object throughout a distribute system whilst still providing a fuck-ton of scope for concurrency, batching and high throughput through better partition key choice, informed by:

A: The maximum ordering guarantees that can be provided by the data source

B: the minimum ordering guarantees required to reconstruct a domain object

Re: Queue Despair: Ordering and Poison Messages

#30
Introduce processing log messages in order to maintain order and not lose any messages, even a poisoned one. The faulty messages are processed as any other message (write a 'did msg x : faulted') and then go to a fault-queue.

If you have inter-dependence between messages, you need to have a message id scheme that shows the interdependence. For example, a hierarchical message order can have a .dot delimited scheme. If a poison message is a parent, the subsequent message can go to the fault-queue as well.

Post reply on HN