Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pushing operations to a message queue for processing when able to

My title isn't great because I'm finding it hard to explain what I want in a small snippet...soo I'll try in depth!

I'm writing an Elixir app using the Phoenix web framework.

What I want to do is this:

  • Call a web route, which phoenix handles and passes off to a controller
  • The controller to initiate a process that is to be handed off to a message queue
  • The latest item in the queue to be processed when resource is available to do so (i.e. CPU/Memory/etc)

The process does not need to return back to the web route (i.e. its Async)

I know how I would handle this in other languages by using a message queue (Beanstalk, RabbitMQ, sidekiq) and have something that hands the "job" off to a worker and then write a worker to handle the jobs on the queue.

But....I know in Elixir it has queues by default as everything gets pushed into a "mailbox" (saw it in a youtube video :p)

But I cant find any decent code examples that show how to have a controller (in phoenix) spawn an async process that will be processed off the message queue.

Does anyone know of any decent resources that show what I'm looking for, or does anyone have any code snippets that would give me a basic description of how to do it.

Thanks :)

EDIT:

As mentioned in the comments, I've created a basic tutorial for how to get Poolboy up and running in an Elixir app. I hope it is helpful (and correct!) for people :)

https://github.com/thestonefox/elixir_poolboy_example

like image 559
TheStoneFox Avatar asked May 05 '15 17:05

TheStoneFox


People also ask

What is a message queue and where is it used?

Message queues allow different parts of a system to communicate and process operations asynchronously. A message queue provides a lightweight buffer which temporarily stores messages, and endpoints that allow software components to connect to the queue in order to send and receive messages.

What is message queue in operating system?

In programming, message queueing is a method by which process (or program instances) can exchange or pass data using an interface to a system-managed queue of messages. Messages can vary in length and be assigned different types or usages.

How is a message queue implemented?

Message queues implement an asynchronous communication pattern between two or more processes/threads whereby the sending and receiving party do not need to interact with the message queue at the same time. Messages placed onto the queue are stored until the recipient retrieves them.

Do I need a message queue?

Message queues provide communication and coordination for these distributed applications. Message queues can significantly simplify coding of decoupled applications, while improving performance, reliability and scalability.

What are the components of a message queue?

The Message Queue model has four basic components: Producer: a service that sends a message in order to notify an event, or request execution of a task, for example; Consumer: the service responsible for retrieving messages from the queue and processing them accordingly;

How to put a message on a queue and close it?

If you want to put a single message on a queue and close the queue immediately afterward, you can use the MQPUT1 call. MQPUT1 performs the same functions as the following sequence of calls: Generally however, if you have more than one message to put on the queue, it is more efficient to use the MQPUT call.

How to create a System V message queue in Linux?

Step 1 − Create a message queue or connect to an already existing message queue (msgget ()) Step 4 − Perform control operations on the message queue (msgctl ()) Now, let us check the syntax and certain information on the above calls. This system call creates or allocates a System V message queue.

What happens when a queue fails to queue?

In case of a queue failure, there could be back-up or dead-letter queues to capture messages not queued during the downtime. A third service would be responsible for moving messages from the backup/dead-letter ones into the main queue once it’s back online. Both Service A and Service B would remain online during the queue failure.


2 Answers

If the jobs are "important", you still want to use some storage to persist them. Otherwise, if the node goes down for any reason, you lose all jobs that are in the system. If this is the case, you can use something like RabbitMQ and create a bunch of workers in your application:

children = [
  worker(QueueConsumer, [], id: :consumer_1),
  worker(QueueConsumer, [], id: :consumer_2),
  worker(QueueConsumer, [], id: :consumer_3),
  worker(QueueConsumer, [], id: :consumer_4)
]

The consumers would get the next message from RabbitMQ and process them as they come.

If you don't care about persisting them or if you want to regulate them based on other criteria like CPU usage, then I recommend you to look into the jobs library (in Erlang): https://github.com/uwiger/jobs

like image 165
José Valim Avatar answered Nov 22 '22 13:11

José Valim


Sounds like you are describing Poolboy.

http://hashnuke.com/2013/10/03/managing-processes-with-poolboy-in-elixir.html

like image 25
Fred the Magic Wonder Dog Avatar answered Nov 22 '22 13:11

Fred the Magic Wonder Dog