{"id":12773,"date":"2015-12-02T21:06:00","date_gmt":"2015-12-02T20:06:00","guid":{"rendered":"https:\/\/touk.pl\/blog\/?guid=4400a6e8c1cec1a6d23137386df40ee2"},"modified":"2023-04-27T11:32:10","modified_gmt":"2023-04-27T09:32:10","slug":"scheduling-tasks-using-message-queue","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2015\/12\/02\/scheduling-tasks-using-message-queue\/","title":{"rendered":"Scheduling tasks using Message Queue"},"content":{"rendered":"<h2 id=\"introduction\">Introduction<\/h2>\n<p>How to schedule your task for later execution? You often create table in database, configure job that checks if due time of any task occured and then execute it.<\/p>\n<p>But there is easier way if only you have message broker with your application&#8230; You could publish\/send your message and tell it that it should be delivered with specified delay.<\/p>\n<h2 id=\"scheduling-messages-using-activemq\">Scheduling messages using ActiveMQ<\/h2>\n<p><a href=\"https:\/\/activemq.apache.org\/\">ActiveMQ<\/a> is open source message broker written in Java. It is implementation of JMS (Java Message Service).<\/p>\n<p>You could start its broker with scheduling support by adding flag <code>schedulerSupport<\/code> to broker configuration:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\">&lt;beans ...&gt;\r\n    ...\r\n    &lt;broker xmlns=\"http:\/\/activemq.apache.org\/schema\/core\"\r\n            brokerName=\"localhost\"\r\n            dataDirectory=\"${activemq.data}\"\r\n            schedulerSupport=\"true\"&gt;\r\n            ...\r\n    &lt;\/broker&gt;\r\n    ...\r\n&lt;\/beans&gt;<\/pre>\n<p>&nbsp;<\/p>\n<p>Now, if you want to delay receiving message by few seconds, you could add property during message creation, e.g.:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 8000)<\/pre>\n<p>Delay unit is miliseconds.<\/p>\n<p>Of course queue must be persisted.<\/p>\n<p>When you listen for message on the same queue, then you will see that message indeed will be received with 8 second delay.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">...\r\nSend time: Tue Dec 01 18:51:23 CET 2015\r\n...\r\nMessage received at Tue Dec 01 18:51:31 CET 2015\r\n...<\/pre>\n<h2 id=\"scheduling-messages-using-rabbitmq\">Scheduling messages using RabbitMQ<\/h2>\n<p>Scheduling tasks is not only the feature of ActiveMQ. It is also available with <a href=\"https:\/\/www.rabbitmq.com\/\">RabbitMQ<\/a>.<\/p>\n<p>RabitMQ is message broker written in Erlang. It uses protocol AMQP.<\/p>\n<p>First you have to install plugin <code>rabbitmq_delayed_message_exchange<\/code>. It could be done via command:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">rabbitmq-plugins enable --offline rabbitmq_delayed_message_exchange<\/pre>\n<p>You have to define exchange in RabbitMQ which will use features from this plugin. Queue for delayed messages should be bound to this exchange. Routing key should be set to queue name.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">channel.exchangeDeclare(exchange, 'x-delayed-message', true, false, ['x-delayed-type': 'direct']);\r\nchannel.queueBind(queue, exchange, queue);\r\nchannel.queueDeclare(queue, true, false, false, null);<\/pre>\n<p>Of course queue must be persisted.<\/p>\n<p>To test it just publish new message with property <code>x-delay<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">channel.basicPublish(\r\n    exchange, \r\n    queue, \r\n    new AMQP.BasicProperties.Builder().headers('x-delay': 8000).build(),\r\n    \"Message: $currentUuid\".bytes\r\n)<\/pre>\n<p>Message will be delayed with 8 seconds:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">...\r\nSend time: Tue Dec 01 19:04:18 CET 2015\r\n...\r\nMessage received at Tue Dec 01 19:04:26 CET 2015\r\n...<\/pre>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>Why you create similar mechanism for handling scheduled tasks on your own, when you could use your message brokers and delayed messages to schedule future tasks?<\/p>\n<p>Sources are available <a href=\"https:\/\/github.com\/alien11689\/scheduled-messages\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"Introduction How to schedule your task for later execution? You often create table in database, configure job that&hellip;\n","protected":false},"author":54,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[68,186,587],"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12773"}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/54"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=12773"}],"version-history":[{"count":13,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12773\/revisions"}],"predecessor-version":[{"id":15672,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12773\/revisions\/15672"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=12773"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=12773"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=12773"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}