0

I have some high-concurrent message handler receiving ordered messages and now need to handle wrong ordered messages: if forward message arrive it should notify and if stale message arrive - it should ignore it.

Example: if 1,2,3,5 messages arrived - it must notify about missed message on 5th, and if 1,2,3,4,2,5 - it must notify only about stale message when receiving 2 after 4.

As it's high-throughput it mustn't use locks.

Here is my current implementation - https://codereview.stackexchange.com/q/10329/5334

-I've solved ABA problem but can't solve problem 1 possible false warning after ignoring stale messsages: on 1,2,3,4,2,5 - it'll notify about stale 2 (after 4) but can also wrongly notify about missed messages on 5th.

Are there ways to fix it or other non-blocking algorithms for this task?

Community
  • 1
  • 1
yetanothercoder
  • 1,689
  • 4
  • 21
  • 43

2 Answers2

1

Why don't you memorize highest id already processed in AtomicLong/AtomicInt and then if next message has lower id then it's 'stale' and you just trow it away and if next message id is different to more than 1 from last memorized you warn about missing.

That should answer your particular question but I would wonder how many such warnings you will get in truly 'high concurrent' environment - probably a lot. Integration solutions, such as Apache Camel usually have built it mechanisms for handling and detecting out of order messages which is pretty elaborate with queues, etc. You might want either use one if them or at least explore how it's built to get more ideas.

maximdim
  • 8,041
  • 3
  • 33
  • 48
  • > if next message has lower id then it's 'stale'...if next message id is different to more than 1 from last... - the problem is how to perform these "check-then-act" actions as atomic with CAS like AtomicLong or so. – yetanothercoder Mar 29 '12 at 19:57
  • I think Apache Camel and other error-prone messaging enterprise solutions implement it via ordered/prioritized queues, but it's locking way and overhead with memory for my task. – yetanothercoder Mar 29 '12 at 20:05
  • True. I didn't noticed your requirement for 'not using locks'. I'm afraid if it's hard requirement then it's not feasible as even AtomicInteger/Long still using some sort of locking inside. – maximdim Mar 30 '12 at 01:24
0

Since both state are invalid, you have the potential of reporting the message twice.

If you get 1,2,3,5,4, then you'll report a "Message 4 not received" message, and a "Message 4 received out of order" message.

You pretty much have to accept that detail, unless you wish to put some kind of timeout on "missed" messages, only reporting them as missed if they don't show up within some window as an out of order message.

That is, you will get a "Message 4 received out of order" immediately when you encounter it, but you may not submit a "Message 4 not received" message until, potentially much later (N seconds later, X messages later, whatever is appropriate).

So you just need to reconcile those two scenarios and how you want to handle them.

Will Hartung
  • 115,893
  • 19
  • 128
  • 203