Pergunta

I am working with delayed_job_active_record gem. I want to delay requests to an external API. Even though my job is added to database, and rake jobs:work runs it and removes it from the database, the actual delayed code from my messages_controller.rb is never executed.

If I if I drop the .delay from the controller methods, the code executes as expected and my tests all pass.

# 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

* UPDATE * I tried launching my rails server without a worker running, and when invoking the job manually via Delayed::Job.last.invoke_job, I see this error:

Delayed::DeserializationError: Job failed to load: undefined class/module MyApp::. 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/api/v2\n      username: REDACTED\n      password: REDACTED      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: ben\n  email: myemail@aol.com\n  reason: General\n  message: test\n"
        from /vendor/bundler/gems/delayed_job-4.0.0/lib/delayed/backend/base.rb:97:in `rescue in payload_object'

I tried adding require 'zendesk' to a config/initializers/custom.rb, but the error persists.

Foi útil?

Solução

I suppose your create_client method is instantiating the Api object. Its quite possible that the Api instance is not valid since the process in which delayed jobs runs is asynchronous.

That said, you should create a new Zendesk Api instance in create_support_ticket. Such as

def create_support_ticket(params={})
  @client = create_client
  unless params.blank? || @client.blank?
  ...
end
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top