When I try to send e-mails with Sidekiq (5.1.3) and Rails (5.1.6) in production using ActiveJob's deliver_later, e-mails are not being sent (deliver_now works fine). The job gets processed and Sidekiq reports it as such. The logs show a successful start & done:
2018-09-14T14:12:18.031Z 14029 TID-mncgx ActionMailer::DeliveryJob JID-665575b056e61ef84a434c97 INFO: done: 0.84 sec
The only thing missing is the delivery of the actual e-mail. I've enabled 'raise_delivery_errors', but nothing is being raised. I'm sending my email through Mailgun.
I'm inclined to think something's going wrong with Sidekiq, because I had ActiveJob configured before (with the default adapter, :async) and deliver_later worked properly. Only after adding Sidekiq it stopped working. I've tried it with many different e-mails and in the end I created an extremely simple mailer, just for debugging this issue.
Here's the code of my 'job':
SimpleMailer.test.deliver_later
And here's the code of my mailer:
class SimpleMailer < ApplicationMailer
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.simple_mailer.test.subject
#
def test
#greeting = "Hi"
mail to: xx, from: xx, subject: 'Well hello"
end
Thanks a lot in advance! I've been searching for quite some time now and have lost almost all inspiration - any help (on where to look) would be amazing. I could also provide more info, but I don't really know what's more to provide.
I have an Rails 4 application that is entirely comprised of rails runners over cron generated from the whenever gem.
I'd like to be notified if there are any exceptions that occur during the run. The exception_notification gem only runs as rack middleware (web requests only), so it doesn't handle rails runners.
Any ideas? I'm looking to get notified over email or on slack.
You can use ExceptionNotifier.notify_exception in a rescue block to send a notification.
For example:
def rescue_exception(data)
yield
rescue => e
ExceptionNotifier.notify_exception(e, data: data)
end
every :hour do
rescue_exception(runner: 'SomeModel.some_method') do
runner "SomeModel.some_method"
end
end
Please refer to https://github.com/smartinez87/exception_notification#background-notifications. Use data hash to pass additional information about the context.
I am using apartment gem in one of my projects. And I have a requirement to log one particular type of activity in each of the tenants. For this I created a excluded model, and in the action where the activity happens I added the function to log it. Due to the data I am trying to log, lot of queries are run when i run this method. Thus i decided to move it to a background worker (Sidekiq). But when the worker runs its saying that its giving errors like.
Undefined method name for nil class
Now the code which gives this error is post.author.name.
This code works properly if we call it directly but breaks when we do it through sidekiq. Has this issue happened to anyone else before? any known solutions?
Worker code is
def perform(post_id, subdomain)
LogTransaction.create_post(post_id, subdomain)
end
The LogTransaction.create_post
def self.create_post post_id, subdomain
post = Post.find(post_id)
Apartment::Tenant.switch('public')
create(post_name: post.name, subdomain: subdomain, author_name: post.author.name)
end
Use this gem in your application, this gem will store which schema from which the job was initiated and it will run in that schema.
https://github.com/influitive/apartment-sidekiq
I am new to Resque. I want to make and send an excel file with the help of a Resque worker. I I have written that code in worker class. Now I have called the worker inside the controller function as:
Resque.redis = Redis.new(:host => "#{Rails.configuration.redis_machine}", :port => Rails.configuration.redis_port)
Resque.enqueue(MakeAndSend,records,email)
Here records is rows of data that are to be printed to the excel file and email is the mail id of the user to which this excel file is to be sent.
But the problem is that my code is get stuck at this line, the following line is getting executed only when the job is over. But as far as I understood from studying resque that the following line should execute immediately.
So if anyone helps me to figure this out, I will be really grateful.
EDIT Here above records is actually collection of objects. So I don't have any option to send ids here. Also, the redis server is not getting hit.
Looking at it, I don't think it would be that line which is the problem - it will likely be something behind that line, such as the worker file or something
I can see one main issue you'll likely have, and there will be others:
-> You're passing variables (ActiveRecord objects) to the Resque queue -- it's convention to send the id's of the variables so the worker file can call the databases when it runs
Here is some live code for our Resque queues:
#app/models/message.rb (this gets called when we run "send_broadcast" function)
def broadcast!
self.subscribers.each do |subscriber|
Resque.enqueue(MailoutQueue, id, subscriber.id)
end
end
#app/workers/mailout_queue.rb
class MailoutQueue
#queue = :mailer
def self.perform(message_id, recipient_id)
MessageMailer.send_message(message_id, recipient_id).deliver
end
end
MessageMailer.rb is just a standard message sender file
If you can post your worker file code, it will help us appreciate where the real issue maybe, so we can fix appropriately!
So, i'm building a small application using Rails. I need to use XMPP proto for notification of users with a bit of commands to change user status.
Previous version was an application using plain Python(pretty ugly app) with plain SQL request into DB. There was a table "jabber_queue", so in separated script, bot was checking each second for any rows, processing it(sending message), deleting. It was simple and stupid, but it was ok.
Now i see, i need to integrate this bot functionality into Rails(at least to work with RSpec).
This is my few versions of how it can be done:
Use separated async queue solution. For example, Resque. Use separated Ruby script and push events into Resque, pop events in application(not dependent on DB, so easily fit with RSpec tests and test DB). But it makes my application a bit bloated - i need to use second DB with a lot of memory and CPU additional requirements - it will be overhead for my problem. Also, i don't want to support additional "thing" for this application, i know, it can be done a lot easier way.
Use delayed_job(queue solution using current AR DB). But i don't know how to get current AR DB of Rails application in separated script. Anyway, it's a dirty and ugly way.
Launch XMPP bot WITHIN Rails application, as background worker. So worker will get access to "current" AR(in case of testing, to test-DB). But i simply don't know how to do it. I've found a Navvy, but i need to put somewhere at Rails start a string like a "Navvy::Job.enqueue(Cow, :speak)", i don't know where will be best place for this, to start it with RSpec testing and "rails server". Also, there is a BackgrounDRb, but this project is similar to Navvy and inactive too. Using search on stackoverflow, i've found similar problem to mine, but solution leads me to background_job, which can just anything in background, but i still don't know how to get current AR DB access in separated script.
I'm so sorry for this amount of words in my problem, it's just a brainstream. I see some solutions, but i really need advices and some words from more experienced developers.
So, this was solved using yes, third way.
I've created a class for dealing with bot commands and AR models - awesomo.rb. Nothing special, really. I put this in /lib/ of Rails project. Secondly,
Created configuration file for easy setting of password and JID - config/awesomo.yml
development:
xmpp_jid: ...
xmpp_password: ...
I've created a daemon for my bot - awesomo_daemon.rb. Same, in /lib/. This is what it contains:
#preload rails environment
require File.expand_path(File.join(File.dirname(__FILE__),
'..', 'config', 'environment'))
#load xmpp bot class
require 'awesomo_daemon'
#load xmpp bot configuration file for current environment
AWESOMO_CONFIG = YAML.load_file(File.join(File.dirname(__FILE__),
'..', 'config', 'awesomo.yml'))[Rails.env]
#apply configuration before singleton will be initiated
Awesomo.setup AWESOMO_CONFIG['xmpp_jid'], AWESOMO_CONFIG['xmpp_password']
loop {
Awesomo.instance.idle
sleep 1
}
Created daemon script starter- script/awesomo.
#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
Daemons.run "lib/awesomo_daemon.rb", dir_mode: :normal,
dir: File.join(File.dirname(__FILE__), '..', 'tmp', 'pids')
Simply run it with command script/awesomo start.
And I can use any my models within awesomo.rb! Also, for queue, i'm using little model - XMPPJob with fields jtype(for example, "xmpp_message"), body("hey!"), to("john#jabber.com"). Fetching it within awesomo.rb idle function of bot class with limit(5).each do |job| case jtype ....
To post any new job for my "awesomo", i'm using function send_message:
def self.send_message to, body
xmppjob = XmppJob.new :jtype => "xmpp_message", :body => body, :to => to
xmppjob.save
end
Everything works perfectly, except XMPP library(xmpp4r-simple) itself, but I'll rewrite it soon using just xmpp4r.