sidekiq worker rails 两个工人之一的参数错误
sidekiq worker rails argument error for one of two workers
我有一个 rails 应用程序,使用 sidekiq w/redis 来发送邮件。我有 2 个工人,但其中一个我得到错误的参数数量错误(ArgumentError:错误的参数数量(5 个为 2)),我不知道为什么,因为另一个基本相同,工作完美.这是两者的 code/explanation:Contactmailer w/ Postmanworker 是在 sby 提交联系表格时发送电子邮件的工作人员;带有 Taskcreatorworker 的 Taskmailer 给出了错误,它会在创建任务时发送一封电子邮件。我已经尝试过使用不同数量的参数,因为我看到我现在有 6 个参数,但仍然给出 5 for 2 错误 => 在 sidekiq 之前,taskmailer 也能正常工作。首先,我尝试只传递 2 个参数 @task.id 和 @current_user,然后我可以调用 task_created.html.erb 中的所有 6 个变量。从那时起,我尝试了不同种类和数量的参数。正如您在下面看到的,目前我尝试在控制器和邮件程序中给出所有 6 个变量,以及它们被调用的样子。我还展示了 user.rb,因为模型有点棘手。
由于联系人邮件程序在 dev/prod 环境中都能完美运行,我可能在下面的代码中犯了错误,这不是 server/installation 问题。
tasks_controller.rb
def create
@user = current_user
@task = Task.new(task_params))
if @task.save
h = JSON.generate( {'task_assigner_first_name' => @current_user.profile.first_name,
'task_assigner_last_name' => @current_user.profile.last_name,
'task_executor_first_name' => @task.executor.profile.first_name,
'task_executor_email' => @task.executor.email,
'task_executor_id' => @task.executor_id,
'task_id' => @task.id
} )
TaskcreatorWorker.perform_async(h, 5)
#TaskMailer.task_created(current_user, @task).deliver_later
flash[:success] = "Task saved!"
redirect_to user_tasks_path(current_user)
else
render action: :new
end
end
private
def task_params
params.require(:task).permit(:executor_id, :name, :content, :deadline).merge(assigner_id: current_user.id)
end
contacts_controller.rb
def create
@contact = Contact.new(contact_params)
if @contact.save
h = JSON.generate({ 'name' => params[:contact][:name],
'email' => params[:contact][:email],
'comment' => params[:contact][:comment] })
PostmanWorker.perform_async(h, 5)
#ContactMailer.contact_email(name, email, comment).deliver_later
flash[:success] = "Message sent."
redirect_to new_contact_path
else
flash[:danger] = "Error occured."
render action: :new
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comment)
end
taskcreator_worker.rb
class TaskcreatorWorker
include Sidekiq::Worker
def perform(h, count)
h = JSON.load(h)
TaskMailer.task_created(h['task_assigner_first_name'], h['task_assigner_last_name'], h['task_executor_first_name'], h['task_executor_email'], h['task_executor_id'], h['task_id']).deliver_later
end
end
postman_worker.rb
class PostmanWorker
include Sidekiq::Worker
def perform(h, count)
h = JSON.load(h)
ContactMailer.contact_email(h['name'],h['email'],h['comment']).deliver_later
end
end
task_mailer.rb
class TaskMailer < ActionMailer::Base
def task_created(task_assigner_first_name, task_assigner_last_name, task_executor_first_name, task_executor_email, task_executor_id, task_id)
@task.assigner.profile.first_name = task_assigner_first_name
@task.assigner.profile.last_name = task_assigner_last_name
@task.executor.profile.first_name = task_executor_first_name
@task.executor.email = task_executor_email
@task.executor_id = task_executor_id
@task.id = task_id
mail(from: 'faskyn@gmail.com',
to: "#{task.executor.email}",
subject: "[Faskyn] New task/favor from #{task.assigner.profile.first_name} #{task.assigner.profile.last_name}"
)
end
end
contact_mailer.rb
class ContactMailer < ActionMailer::Base
default to: 'faskyn@gmail.com'
def contact_email(name, email, content)
@name = name
@email = email
@content = content
mail(from: email, subject: 'Contact form message')
end
end
task_created.html.erb
<p>Hi <%= @task.executor.profile.first_name%>,</p>
<p><%= @current_user.profile.first_name %> <%= @current_user.profile.last_name %> just sent you a new task/favor.</p>
<p>You can check it out <%= link_to "here", user_task_url(@task.executor_id, @task.id) %>.</p>
<p>Cheers,<br />Faskyn Team</p>
contact_email.html.erb
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>You have received a message from the site's contact form, from <%= "#{ @name }, #{ @email}." %></p>
<p><%= @comment %></p>
</body>
</html>
user.rb
has_one :profile, dependent: :destroy
has_many :assigned_tasks, class_name: "Task", foreign_key: "assigner_id", dependent: :destroy
has_many :executed_tasks, class_name: "Task", foreign_key: "executor_id", dependent: :destroy
sidekiq 日志中的错误消息:
2015-09-28T12:48:33.600Z 20264 TID-outp8berw TaskcreatorWorker JID-a0816ab8d1881e81c58569d2 INFO: start
2015-09-28T12:48:33.633Z 20264 TID-outp8berw TaskcreatorWorker JID-a0816ab8d1881e81c58569d2 INFO: fail: 0.033 sec
2015-09-28T12:48:33.635Z 20264 TID-outp8berw WARN: {"class"=>"TaskcreatorWorker", "args"=>["{\"task_assigner_first_name\":\"Szilard\",\"task_assigner_last_name\":\"Hungarian\",\"task_executor_first_name\":\"Andrew\",\"task_executor_email\":\"szilard.magyar@speaktoit.com\",\"task_executor_id\":3,\"task_id\":82}", 5], "retry"=>true, "queue"=>"default", "jid"=>"a0816ab8d1881e81c58569d2", "created_at"=>1443439028.7889678, "enqueued_at"=>1443444513.5961752, "error_message"=>"wrong number of arguments (5 for 2)", "error_class"=>"ArgumentError", "failed_at"=>1443439028.8198888, "retry_count"=>8, "retried_at"=>1443444513.632468}
2015-09-28T12:48:33.636Z 20264 TID-outp8berw WARN: ArgumentError: wrong number of arguments (5 for 2)
2015-09-28T12:48:33.636Z 20264 TID-outp8berw WARN: /Users/Silo/Desktop/ruby_on_rails/faskyn/app/mailers/task_mailer.rb:3:in `task_created'
2015-09-28T16:17:07.015Z 23136 TID-ow4vpw9ik TaskcreatorWorker JID-6cb35b9b42bebdbf128746c0 INFO: start
2015-09-28T16:17:08.178Z 23136 TID-ow4vpw9ik TaskcreatorWorker JID-6cb35b9b42bebdbf128746c0 INFO: fail: 1.163 sec
2015-09-28T16:17:08.180Z 23136 TID-ow4vpw9ik WARN: {"class"=>"TaskcreatorWorker", "args"=>["{\"task_assigner_first_name\":\"Szilard\",\"task_assigner_last_name\":\"Hungarian\",\"task_executor_first_name\":\"Peter\",\"task_executor_email\":\"szilard@api.ai\",\"task_executor_id\":2,\"task_id\":83}", 5], "retry"=>true, "queue"=>"default", "jid"=>"6cb35b9b42bebdbf128746c0", "created_at"=>1443456758.3800051, "enqueued_at"=>1443457026.97385, "error_message"=>"undefined method `assigner' for nil:NilClass", "error_class"=>"NoMethodError", "failed_at"=>1443456758.398172, "retry_count"=>3, "retried_at"=>1443457028.177601}
2015-09-28T16:17:08.180Z 23136 TID-ow4vpw9ik WARN: NoMethodError: undefined method `assigner' for nil:NilClass
2015-09-28T16:17:08.180Z 23136 TID-ow4vpw9ik WARN: /Users/Silo/Desktop/ruby_on_rails/faskyn/app/mailers/task_mailer.rb:4:in `task_created'
您正在使用来自 sidekiq 时未设置的对 @task
实例变量的引用。您需要在邮件程序方法本身中初始化 @task
变量。根据期望的结果,可以通过多种方式完成。
@task = Task.new
初始化任务及其所需的所有对象(assigner
和 executor
),然后为它们提供从您的工作人员传入的值。
@task = Task.find(task_id)
这是一个更好的解决方案,因为您不需要通过 sidekiq 传递所有参数。您的任务已经保存在数据库中,因此只需传递 id 并使用它来查找任务。它将已经拥有所有必需的数据。
tasks_controller.rb
def create
@user = current_user
@task = Task.new(task_params)
if @task.save
TaskcreatorWorker.perform_async(@task.id, @user.id)
flash[:success] = "Task saved!"
redirect_to user_tasks_path(current_user)
else
render action: :new
end
end
taskcreator_worker.rb
class TaskcreatorWorker
include Sidekiq::Worker
def perform(task_id, user_id) # Removed count since you weren't using it. Add it back if needed
TaskMailer.task_created(
Task.find(task_id),
User.find(user_id)
).deliver_now # deliver_now since we're already in a sidekiq worker
end
end
task_mailer.rb
class TaskMailer < ActionMailer::Base
def task_created(task, user)
# Initialize variables you use in your view
@task = task
@current_user = user
mail(from: 'faskyn@gmail.com',
to: "#{task.executor.email}",
subject: "[Faskyn] New task/favor from "\
"#{task.assigner.profile.first_name} "\
"#{task.assigner.profile.last_name}"
)
end
end
我有一个 rails 应用程序,使用 sidekiq w/redis 来发送邮件。我有 2 个工人,但其中一个我得到错误的参数数量错误(ArgumentError:错误的参数数量(5 个为 2)),我不知道为什么,因为另一个基本相同,工作完美.这是两者的 code/explanation:Contactmailer w/ Postmanworker 是在 sby 提交联系表格时发送电子邮件的工作人员;带有 Taskcreatorworker 的 Taskmailer 给出了错误,它会在创建任务时发送一封电子邮件。我已经尝试过使用不同数量的参数,因为我看到我现在有 6 个参数,但仍然给出 5 for 2 错误 => 在 sidekiq 之前,taskmailer 也能正常工作。首先,我尝试只传递 2 个参数 @task.id 和 @current_user,然后我可以调用 task_created.html.erb 中的所有 6 个变量。从那时起,我尝试了不同种类和数量的参数。正如您在下面看到的,目前我尝试在控制器和邮件程序中给出所有 6 个变量,以及它们被调用的样子。我还展示了 user.rb,因为模型有点棘手。
由于联系人邮件程序在 dev/prod 环境中都能完美运行,我可能在下面的代码中犯了错误,这不是 server/installation 问题。
tasks_controller.rb
def create
@user = current_user
@task = Task.new(task_params))
if @task.save
h = JSON.generate( {'task_assigner_first_name' => @current_user.profile.first_name,
'task_assigner_last_name' => @current_user.profile.last_name,
'task_executor_first_name' => @task.executor.profile.first_name,
'task_executor_email' => @task.executor.email,
'task_executor_id' => @task.executor_id,
'task_id' => @task.id
} )
TaskcreatorWorker.perform_async(h, 5)
#TaskMailer.task_created(current_user, @task).deliver_later
flash[:success] = "Task saved!"
redirect_to user_tasks_path(current_user)
else
render action: :new
end
end
private
def task_params
params.require(:task).permit(:executor_id, :name, :content, :deadline).merge(assigner_id: current_user.id)
end
contacts_controller.rb
def create
@contact = Contact.new(contact_params)
if @contact.save
h = JSON.generate({ 'name' => params[:contact][:name],
'email' => params[:contact][:email],
'comment' => params[:contact][:comment] })
PostmanWorker.perform_async(h, 5)
#ContactMailer.contact_email(name, email, comment).deliver_later
flash[:success] = "Message sent."
redirect_to new_contact_path
else
flash[:danger] = "Error occured."
render action: :new
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comment)
end
taskcreator_worker.rb
class TaskcreatorWorker
include Sidekiq::Worker
def perform(h, count)
h = JSON.load(h)
TaskMailer.task_created(h['task_assigner_first_name'], h['task_assigner_last_name'], h['task_executor_first_name'], h['task_executor_email'], h['task_executor_id'], h['task_id']).deliver_later
end
end
postman_worker.rb
class PostmanWorker
include Sidekiq::Worker
def perform(h, count)
h = JSON.load(h)
ContactMailer.contact_email(h['name'],h['email'],h['comment']).deliver_later
end
end
task_mailer.rb
class TaskMailer < ActionMailer::Base
def task_created(task_assigner_first_name, task_assigner_last_name, task_executor_first_name, task_executor_email, task_executor_id, task_id)
@task.assigner.profile.first_name = task_assigner_first_name
@task.assigner.profile.last_name = task_assigner_last_name
@task.executor.profile.first_name = task_executor_first_name
@task.executor.email = task_executor_email
@task.executor_id = task_executor_id
@task.id = task_id
mail(from: 'faskyn@gmail.com',
to: "#{task.executor.email}",
subject: "[Faskyn] New task/favor from #{task.assigner.profile.first_name} #{task.assigner.profile.last_name}"
)
end
end
contact_mailer.rb
class ContactMailer < ActionMailer::Base
default to: 'faskyn@gmail.com'
def contact_email(name, email, content)
@name = name
@email = email
@content = content
mail(from: email, subject: 'Contact form message')
end
end
task_created.html.erb
<p>Hi <%= @task.executor.profile.first_name%>,</p>
<p><%= @current_user.profile.first_name %> <%= @current_user.profile.last_name %> just sent you a new task/favor.</p>
<p>You can check it out <%= link_to "here", user_task_url(@task.executor_id, @task.id) %>.</p>
<p>Cheers,<br />Faskyn Team</p>
contact_email.html.erb
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>You have received a message from the site's contact form, from <%= "#{ @name }, #{ @email}." %></p>
<p><%= @comment %></p>
</body>
</html>
user.rb
has_one :profile, dependent: :destroy
has_many :assigned_tasks, class_name: "Task", foreign_key: "assigner_id", dependent: :destroy
has_many :executed_tasks, class_name: "Task", foreign_key: "executor_id", dependent: :destroy
sidekiq 日志中的错误消息:
2015-09-28T12:48:33.600Z 20264 TID-outp8berw TaskcreatorWorker JID-a0816ab8d1881e81c58569d2 INFO: start
2015-09-28T12:48:33.633Z 20264 TID-outp8berw TaskcreatorWorker JID-a0816ab8d1881e81c58569d2 INFO: fail: 0.033 sec
2015-09-28T12:48:33.635Z 20264 TID-outp8berw WARN: {"class"=>"TaskcreatorWorker", "args"=>["{\"task_assigner_first_name\":\"Szilard\",\"task_assigner_last_name\":\"Hungarian\",\"task_executor_first_name\":\"Andrew\",\"task_executor_email\":\"szilard.magyar@speaktoit.com\",\"task_executor_id\":3,\"task_id\":82}", 5], "retry"=>true, "queue"=>"default", "jid"=>"a0816ab8d1881e81c58569d2", "created_at"=>1443439028.7889678, "enqueued_at"=>1443444513.5961752, "error_message"=>"wrong number of arguments (5 for 2)", "error_class"=>"ArgumentError", "failed_at"=>1443439028.8198888, "retry_count"=>8, "retried_at"=>1443444513.632468}
2015-09-28T12:48:33.636Z 20264 TID-outp8berw WARN: ArgumentError: wrong number of arguments (5 for 2)
2015-09-28T12:48:33.636Z 20264 TID-outp8berw WARN: /Users/Silo/Desktop/ruby_on_rails/faskyn/app/mailers/task_mailer.rb:3:in `task_created'
2015-09-28T16:17:07.015Z 23136 TID-ow4vpw9ik TaskcreatorWorker JID-6cb35b9b42bebdbf128746c0 INFO: start
2015-09-28T16:17:08.178Z 23136 TID-ow4vpw9ik TaskcreatorWorker JID-6cb35b9b42bebdbf128746c0 INFO: fail: 1.163 sec
2015-09-28T16:17:08.180Z 23136 TID-ow4vpw9ik WARN: {"class"=>"TaskcreatorWorker", "args"=>["{\"task_assigner_first_name\":\"Szilard\",\"task_assigner_last_name\":\"Hungarian\",\"task_executor_first_name\":\"Peter\",\"task_executor_email\":\"szilard@api.ai\",\"task_executor_id\":2,\"task_id\":83}", 5], "retry"=>true, "queue"=>"default", "jid"=>"6cb35b9b42bebdbf128746c0", "created_at"=>1443456758.3800051, "enqueued_at"=>1443457026.97385, "error_message"=>"undefined method `assigner' for nil:NilClass", "error_class"=>"NoMethodError", "failed_at"=>1443456758.398172, "retry_count"=>3, "retried_at"=>1443457028.177601}
2015-09-28T16:17:08.180Z 23136 TID-ow4vpw9ik WARN: NoMethodError: undefined method `assigner' for nil:NilClass
2015-09-28T16:17:08.180Z 23136 TID-ow4vpw9ik WARN: /Users/Silo/Desktop/ruby_on_rails/faskyn/app/mailers/task_mailer.rb:4:in `task_created'
您正在使用来自 sidekiq 时未设置的对 @task
实例变量的引用。您需要在邮件程序方法本身中初始化 @task
变量。根据期望的结果,可以通过多种方式完成。
@task = Task.new
初始化任务及其所需的所有对象(
assigner
和executor
),然后为它们提供从您的工作人员传入的值。@task = Task.find(task_id)
这是一个更好的解决方案,因为您不需要通过 sidekiq 传递所有参数。您的任务已经保存在数据库中,因此只需传递 id 并使用它来查找任务。它将已经拥有所有必需的数据。
tasks_controller.rb
def create
@user = current_user
@task = Task.new(task_params)
if @task.save
TaskcreatorWorker.perform_async(@task.id, @user.id)
flash[:success] = "Task saved!"
redirect_to user_tasks_path(current_user)
else
render action: :new
end
end
taskcreator_worker.rb
class TaskcreatorWorker
include Sidekiq::Worker
def perform(task_id, user_id) # Removed count since you weren't using it. Add it back if needed
TaskMailer.task_created(
Task.find(task_id),
User.find(user_id)
).deliver_now # deliver_now since we're already in a sidekiq worker
end
end
task_mailer.rb
class TaskMailer < ActionMailer::Base
def task_created(task, user)
# Initialize variables you use in your view
@task = task
@current_user = user
mail(from: 'faskyn@gmail.com',
to: "#{task.executor.email}",
subject: "[Faskyn] New task/favor from "\
"#{task.assigner.profile.first_name} "\
"#{task.assigner.profile.last_name}"
)
end
end