对于delayed_job_active_record
gem的第4版,我想将请求延迟到外部API。我的工作被添加到数据库中,rake jobs:work
运行它并将其从数据库中删除。但是,我messages_controller.rb
的实际延迟代码永远不会被执行。
如果我在rails控制台中尝试Delayed::Job.last.invoke_job
,则会收到以下错误:
Delayed::DeserializationError: Job failed to load: allocator undefined for Proc. Handler: "--- !ruby/object:Delayed::PerformableMethod\nobject: !ruby/object:MyApp::Zendesk\n client: !ruby/object:ZendeskAPI::Client\n config: !ruby/object:ZendeskAPI::Configuration\n client_options: {}\n cache: !ruby/object:ZendeskAPI::LRUCache\n size: 1000\n store: {}\n lru: []\n url: https://redacted.zendesk.com/api/v2\n username: redacted\n password: redacted\n retry: true\n logger: !ruby/object:Logger\n progname: \n level: 0\n default_formatter: !ruby/object:Logger::Formatter\n datetime_format: \n formatter: \n logdev: !ruby/object:Logger::LogDevice\n shift_size: \n shift_age: \n filename: \n dev: !ruby/object:IO {}\n mutex: !ruby/object:Logger::LogDevice::LogDeviceMutex\n mon_owner: \n mon_count: 0\n mon_mutex: !ruby/object:Mutex {}\n callbacks:\n - !ruby/object:Proc {}\n resource_cache: {}\nmethod_name: :create_support_ticket\nargs:\n- !ruby/hash:ActionController::Parameters\n name: redacted\n email: redacted\n reason: General\n message: test\n"
尝试运行的代码是create_support_ticket
方法:
# messages_controller.rb
require 'zendesk'
class MessagesController < ApplicationController
layout "application"
# /suport/contact-us
def contact_us
zendesk = MyApp::Zendesk.new
zendesk.delay.create_support_ticket(params[:message])
# render page
respond_to do |format|
flash[:notice] = "Email sent successfully!" if @sent
format.html { render "pages/support/contact-us" }
end
end
end
# zendesk.rb
require 'zendesk_api'
module MyApp
class Zendesk
attr_accessor :client
def initialize(*args)
@client = create_client
end
# contact-us ticket methods
def create_support_ticket(params={})
unless params.blank? || @client.blank?
# get or create user_id for submitter
params[:requester_id] = check_user_exists(params)
begin
ticket = @client.tickets.create(
subject: "Support Ticket",
comment: { value: params[:message] },
submitter_id: params[:requester_id],
requester_id: params[:requester_id],
assignee_id: 201578811,
status: "new",
fields: [
{id: 20887016, value: "Support"},
{id: 20966436, value: "New"}])
return ticket
rescue => e
Airbrake.notify e
end
else
return false
end
end
end
end
答案 0 :(得分:3)
DelayedJob尝试序列化您正在调用该方法的对象。
在您的情况下,该对象具有IO和Proc对象。它们都与序列化不兼容。你能做的最好的事情就是编写一个没有依赖关系的简单包装器,并初始化方法调用中的所有东西。
答案 1 :(得分:0)
我碰巧遇到了与上述相同的问题。我有一个 Oauth::Client 对象,它无法被 delay_job Gem 反序列化。
为了解决这个问题,我改变了我的方法,这样当我向延迟的作业添加方法时,Ouath::Client 对象不会被序列化/反序列化。