A helper to use workers and topics with Ruby on Rails
Add this line to your application's Gemfile:
gem'turtle',github: 'petlove/turtle'Turtle.shoryuken_queues_priorities# => [["macaw_linquetab_enqueue_triggered_send_credit_earned", 2],# ["macaw_linquetab_enqueue_triggered_send_question_answer", 2],# ["macaw_linquetab_enqueue_triggered_send_product_back_in_stock", 2],# ["macaw_linquetab_perform_order_events", 3],# ["macaw_linquetab_perform_order_payment_pending_events", 3],# ["macaw_linquetab_perform_shipment_events", 3],# ["macaw_linquetab_update_data_extension_reviews", 1],# ["macaw_linquetab_update_data_extension_products", 1],# ["macaw_linquetab_update_data_extension_animal_pets", 1],# ["macaw_linquetab_update_data_extension_orders_carts", 1],# ["macaw_linquetab_update_data_extension_customers", 1],# ["macaw_linquetab_update_data_extension_customer_coupons", 1],# ["macaw_linquetab_update_list_subscribers", 1],# ["macaw_linquetab_perform_subscription_events", 3],# ["macaw_linquetab_update_data_extension_subscriptions", 1]]# Filter by queue metadata fieldsTurtle.shoryuken_queues_priorities(priority: 3)# => [["macaw_linquetab_perform_order_events", 3],# ["macaw_linquetab_perform_order_payment_pending_events", 3],# ["macaw_linquetab_perform_shipment_events", 3],# ["macaw_linquetab_perform_subscription_events", 3]]To use Processing Groups, add groups: to your aws-sqs-configurator config:
queues:
- name: 'orders_queue'metadata:
priority: 2
- name: 'payments_queue'metadata:
priority: 1groups:
critical:
concurrency: 1queues:
- orders_queue
- payments_queueTurtle.shoryuken_groups# => "{\"critical\":{\"concurrency\":1,\"queues\":[[\"app_production_orders_queue\",2],[\"app_production_payments_queue\",1]]}}"In config/shoryuken.yml:
queues: <%= Turtle.shoryuken_queues_priorities %>groups: <%= Turtle.shoryuken_groups %># Turtle.name_for(type, name, options)Turtle.name_for(:queue,'order_sync')# => beagle_production_order_syncTurtle.name_for(:topic,'order_created')# => beagle_production_order_created| Key | Default |
|---|---|
region | ENV['AWS_REGION'] |
prefix | ENV['APP_NAME'] |
environment | ENV['APP_ENV'] |
suffix | nil |
Turtle.retry_intervals# => [5.minutes, 15.minutes, 30.minutes, 1.hour, 3.hours, 12.hours]You should follow this steps:
- Add
gem 'delayed_job_active_record'in your Gemfile - Run
rails generate delayed_job:active_record - Run
rails db:migrate - Set in the file config/application.rb this code:
config.active_job.queue_adapter=:delayed_job- Set the file config/initializers/delayed_job.rb with this code:
Delayed::Worker.queue_attributes=Turtle.delayed_job_queue_attributes- Set the supervisor to run DelayedJob with this code:
[program:delayed_job]
command=bundle exec rake jobs:work
user = root
autostart=true
autorestart=true
redirect_stderr=falseSee more about DelayedJob here.
The worker should include Shoryuken::Worker and have the option :queue defined.
# Turtle.enqueue!(worker, data, options = {})Turtle.enqueue!(SomeWorker,{hello: 'world'})| Key | Default | What's it? |
|---|---|---|
delay | false | Enqueue the data through DelayedJob process. Pass true to use it. |
seconds | 0 | Use AWS SQS delay. Pass an integer between 0 and 900. |
model | nil | Envolope the data with the field model. It should be like Spree::Order, Subscription or any model name |
event | nil | Envolope the data with the field event. It should be like :created, :completed or any event name |
Important: If the fields model or event exists, the data will be enveloped like this code:
{event: 'order_created',model: 'spree_order',data: {hello: 'world'}}# Turtle.publish!(name, data, options = {})Turtle.publish!('product_event_created',{hello: 'world'})| Key | Default | What's it? |
|---|---|---|
delay | false | Enqueue the data through DelayedJob process. Pass true to use it. |
model | nil | Envolope the data with the field model. It should be like Spree::Order, Subscription or any model name |
event | nil | Envolope the data with the field event. It should be like :created, :completed or any event name |
Important: If the fields model or event exists, the data will be enveloped like this code:
{event: 'order_created',model: 'spree_order',data: {hello: 'world'}}includeTurtle::EventNotificatoract_as_notificationmodel: 'order',enveloped: true,serializer: OrderEventSerializer,serializer_options: {root: false},serializer_root: :data,states: %i(pendingcompleted),state_column: :state,actions: %i(createdupdateddestroyed),delayed: %i(createdupdatedcompleted)The topic name that will be publicated follows the structure:
"#{ENV['APP_NAME']}_#{ENV['APP_ENV']}_#{model}_event_#{event_raised}"# => kangaroo_production_order_event_createdAnd the content will be:
# Enveloped{event: event,model: model,data: OrderEventSerializer.new(self)}.to_json# => {# "event": "created",# "model": "order",# "data": {# "hello": "world"# }# }# Not envelopedOrderEventSerializer.new(self).to_json# => {# "hello": "world"# }| Key | Default | Required | What's it? |
|---|---|---|---|
model | nil | true | The model name. |
serializer | nil | true | The serializer used in the payload. |
serializer_options | {} | false | The serializer options. |
serializer_root | nil | false | The serializer root field. If nil will be returned the original root. |
enveloped | true | false | If true it allows to envelope the payload. |
states | [] | false | The states name list. It will publish in a topic if the state was changed. |
state_column | :state | false | The state column name. |
actions | [] | false | The actions name list. It will publish in a topic all times that the event happens. It allows the values %i(created updated destroyed). |
delayed | [] | false | The events that you would like performing with delay. It requires DelayedJob. E.g: %i(created updated completed) |
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create new Pull Request
The gem is available as open source under the terms of the MIT License.