Erlang message receiving order - concurrency

With the knowledge of these facts about time-order of Erlang message passing behaviour:
If process A sends two messages to process B, then the two messages are guaranteed to arrive in the order they are sent.
If process A sends a message to process B and then a message to process C, there's no guarantee as to the ordering in which they are received.
Similarly, if processes A & B send messages to C, there's no guarantee as to the order in which the messages are received.
My question is:
What is the receive order if process A and B send a message to process C, when A and B send its message exactly in a same (micro) time, with a same inner functionality, in the same node and in the same machine which can run parallel processes?

You can't make any assumptions about the receive order in that case either. The receive order will depend on factors such as when the processes are scheduled to run and can differ between different runs of the same code.

Related

Is it good to send a new RabbitMQ message from consumer to the same queue?

I do mailings via rabbitmq: I send a mailing list from the main application, the consumer reads it and sends it.
A broadcast may consist of different messages, which must be sent in the correct order.
In fact, a mailing list is a list of messages: [message_1, message_2, message_3, message_4]
Some of the messages can be sent and at some point the third-party service stops accepting requests.
I will describe the process of the consumer:
I take out the message from queue which contains distribution.
Sending: 1 part > 2 part
An error occurs. It remains to send 3 part > 4 part.
Acknowledge the original message from the queue.
Put a new one at the beginning of the same queue: [message 3, message 4].
Question 1: Is it good to send a new message (from consumer) created from parts of an old one to the same queue?
Question 2: Is it a good solution?
Are there any other solutions?
The sequence you posted loses a message if the handler process crashes between steps 4 and 5. So you have to switch the order of steps 4 and 5. But as soon as you do that you have to deal with the duplication of messages. If for some reason (like a bug) ack fails for a large percentage of messages you can end up with the same broadcast repeated multiple times in the queue. So if you want to avoid duplicated messages you have to use some external persistence to perform deduping. Also, RabbitMQ doesn't guarantee that messages are delivered in the same order. So you can end up in a situation where two messages for the same address are delivered out of order. So deduping should be on the level of individual parts, not entire messages.
Question 2: Is it a good solution? Are there any other solutions?
Consider using an orchestrator like temporal.io which eliminates most of the consistency problems I described.

Understanding SQS message receive amount

I have a queue which is supposed to receive the messages sent by a lambda function. This function is supposed to send each different message once only. However, I saw a scary amount of receive count on the console:
Since I cannot find any explanation about receive count in the plain English, I need to consult StackOverflow Community. I have 2 theories to verify:
There are actually not so many messages and the reason why "receive count" is that high is simply because I polled the messages for a looooong time so the messages were captured more than once;
the function that sends the messages to the queue is SQS-triggered, those messages might be processed by multiple processors. Though I set VisibilityTimeout already, are the messages which are processed going to be deleted? If they aren't remained, there are no reasons for them to be caught and processed for a second time.
Any debugging suggestion will be appreciated!!
So, receive count is basically the amount of times the lambda (or any other consumer) has received the message. It can be that a consumer receives a message more than once (this is by design, and you should handle that in your logic).
That being said, the receive count also increases if your lambda fails to process the message (or even hits the execution limits). The default is 3 times, so if something with your lambda is wrong, you will have at least 3 receives per message.
Also, when you are polling the message, via the AWS console, you are basically increasing the receive count.

Why one SQS message doesn't get deleted while others do?

I came across this question in my AWS study:
You create an SQS queue and decide to test it out by creating a simple
application which looks for messages in the queue. When a message is
retrieved, the application is supposed to delete the message. You
create three test messages in your SQS queue and discover that
messages 1 and 3 are quickly deleted but message 2 remains in the
queue. What is a possible cause for this behavior? Choose the 2
correct answers
Options:
A. The order that messages are received in is not guaranteed in SQS
B. Message 2 uses JSON formatting
C. You failed to set the correct permissions on message 2
D. Your application is using short polling
Correct Answer:
A. The order that messages are received in is not guaranteed in SQS
D. Your application is using short polling
Why A is considered as one the answer here? I understand A is correct from the SQS feature definition, however, it does not explain to the issue in this question, right? Why it is not the permission issue?
Anything I am missing?
Thank you.
I think that a justification for A & D is:
Various workers might be pulling messages from the queue
Given that it is not a FIFO queue, then message order is not guaranteed (A)
Short-polling will not necessarily check every 'server', it will simply return a message (D)
Message 2 simply hasn't been processed yet
Frankly, I don't think that D is so relevant, because Long Polling returns as soon as it gets a message and it simply means that no worker has requested the message yet.
B is irrelevant because message content has no impact on retrieval.
C is incorrect because there are no permissions on individual messages. Only the queue, or users accessing the queue, have permissions.

Check if Kafka Queue is Empty

Right now I have functionality that writes a couple hundred messages onto a kafka queue. But when all of those messages have been consumed I need to also execute additional functionality. Is there a way to place a listener on a kafka queue to get notified when it has been emptied?
You could solve this two ways, I think:
Kafka's Fetch Response contains a HighwaterMarkOffset, which essentially is an offset of the last message in a partition. You could check whether your message has that offset and if so - you've reached the end. However, this won't work if you have producer and consumer working at the same time - consumer can just consume messages faster and thus stop earlier than you need.
Send a "poison pill" message - say you need to produce 100 messages. Then your producer sends these 100 messages + 1 special message (some UUID for example, but be sure it never appears under normal circumstances in your logic) that would mean "the end". On consumer side you would check whether the received message is a poison pill and shutdown if it is.

How to pass fixed size messages from one process to another process and viceversa?

I need two processes P and Q to communicate via 4KB-long messages. All the messages belong to a session. A session begins with the first message successfully sent by P to Q and finishes when either any of two processes sends a Stop message to the other process or a process terminates. Each process can send and receive a message from the other process. Sending and receiving operations must block until the whole message has been sent or received respectively or until a time out occurs, otherwise an error is thrown.
At the moment, my idea is to use a Socket and two queues in shared memory (one for the messages from P to Q and one for the messages from Q to P). The only purpose of the Socket is to properly implement the session concept I described: it is opened when P sends the first message to Q and is closed when one of two processes wants to deliberately terminate the session (equivalently to the Stop message the described above) or if one of the two processes terminates for some reasons (this would be done automatically by the OS). In both cases the remaining process can be easily notified of the event. The queues are useful for receiving or sending messages "all at once", as I think there is no easy way to do this via Sockets.
Are there any simpler solutions than the above? I have full access to C++11, boost (e.g. for IPC part) and POCO libraries (e.g. for the appropriate Socket type). Other libraries are not allowed unless they are header-only.
I do NOT care about efficiency.