I'm trying to implement Sneakers, but I'm having some issues. Below you can find the code which subscribers to my queue and the actual error.
require 'sneakers'
require 'jwt'
require 'redis'
require 'json'
$redis = Redis.new(url: ENV['REDIS_URL'], password: ENV['REDIS_PASSWORD'])
class Processor
include Sneakers::Worker
QUEUE_NAME = :my_queue
from_queue QUEUE_NAME
def work(msg)
message = JSON.parse(msg)
if message["type"] == "error"
$redis.incr "processor:#{err["error"]}"
end
controller = Object.const_get message['controller']
action = message['method']
controller.public_send(action, message['msg'])
ack!
end
end
Error:
[Exception error="uninitialized constant V1" error_class=NameError worker_class=Processor
The msg object
{\"controller\":\"V1::x::yController\",\"method\":\"my_method"\}
Any help is welcome, thank you!
Update
Even getting a simple Model such as my User is resulting into the same error.
[Exception error="uninitialized constant User"
I'm running the sneakers worker like so:
sneakers work UserCreate --require app/workers/user_create.rb
Related
I have a gem inside my Rails project, really simple, it translate an ip address to a real address (e.g. Gem.locate '127.0.0.1' returns { country: 'de' }
The code is like this
ip_locator/lib/service.rb
module IpLocator
class Service
include Singleton
attr_reader :db
def initialize
#db = MaxMindDB.new('db/GeoLite2-City.mmdb')
end
def locate(ip)
db.lookup ip
end
end
end
when I'm in the rails project, I can properly do this: IpLocator::Service.instance.locate '74.125.225.224' and get the information I need.
Now I'm trying add some tests to the gem (not in the rails project).
require 'spec_helper'
RSpec.describe IpLocator do
describe 'ip_locator' do
context 'when the data exists' do
let(:ip) { '74.125.225.224' }
subject do
IpLocator::Service.instance.locate ip
end
it 'return country data' do
expect(subject.found).to be_truthy
end
end
end
end
but when I run the test, I get
1) IpLocator ip_locator when the data exists return country data
Failure/Error: IpLocator::Service.instance.locate ip
NameError:
uninitialized constant IpLocator::Service
I already tried to change IpLocator::Service to Service, I tried require ip_locator inside the spec file (although it is already required inside spec_helper.rb). I'm pretty sure I'm doing something really stupid but not sure what exactly
Here is my spec_helper.rb
require 'bundler/setup'
Bundler.setup
require 'byebug'
require 'ip_locator'
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each { |file| require file }
RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = '.rspec_status'
# Disable RSpec exposing methods globally on `Module` and `main`
config.disable_monkey_patching!
config.expect_with :rspec do |c|
c.syntax = :expect
end
end
and I'm seeing the error:
NameError: uninitialized constant IpLocator::Service::Singleton
Did you mean? SignalException
then, if I try to require singleton as well in the spec_helper, I get
1) IpLocator::Service ip_locator when the data exists return country data
Failure/Error: #db = ::MaxMindDB.new('db/GeoLite2-City.mmdb')
NameError:
uninitialized constant MaxMindDB
I'm getting crazy
I have the following worker in my web app
class TweetSender
#queue = :tweets_queue
def self.perform(tweet_id)
message = Tweet.where(:status_id => 0).order(:created_at, :id).limit(1)
message.update_attribute(status_id = 1)
$client.update(message.text)
end
end
It gets schedueled by the following resque-scheduler tweet_scheduler.yml
tweet_sender:
cron: "0 20 * * * Europe/Stockholm"
class: "TweetSender"
queue: tweets_queue
args: tweet_id
description: "This job sends daily tweets from the content db"
Which gets defined by he resque.rake
require 'resque/tasks'
require 'resque/scheduler/tasks'
task 'resque:setup' => :environment
namespace :resque do
task :setup do
require 'resque'
end
task :setup_schedule => :setup do
require 'resque-scheduler'
Resque.schedule = YAML.load_file('tweet_schedule.yml')
require 'jobs'
end
task :scheduler => :setup_schedule
end
In the resque web interface I get the following error
Exception
NoMethodError
Error
undefined method `update_attribute' for #<Tweet::ActiveRecord_Relation:0x839ca814>
/home/jan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/relation/delegation.rb:136:in `method_missing'
/home/jan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/relation/delegation.rb:99:in `method_missing'
/home/jan/Documents/social/app/jobs/tweet_sender.rb:6:in `perform'
I alos tried implementing the tweet_sender.rb without the update_atttribute methods like so:
class TweetSender
#queue = :tweets_queue
def self.perform(tweet_id)
message = Tweet.where(:status_id => 0).order(:created_at, :id).limit(1)
message.status_id = 1
message.save
$client.update(message.text)
end
end
And the get the following error:
Exception
NoMethodError
Error
undefined method `status_id=' for #<Tweet::ActiveRecord_Relation:0x83195bf8>
/home/jan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/relation/delegation.rb:136:in `method_missing'
/home/jan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/relation/delegation.rb:99:in `method_missing'
/home/jan/Documents/social/app/jobs/tweet_sender.rb:6:in `perform'
Why are my methods and the standard rails emthods no available in my worker? Do I need to explicitly require them somewhere?
limit returns an instance of ActiveRecord::Relation.
What you really want to get is an instance of Tweet model.
Use first:
message = Tweet.where(status_id: 0).order(:created_at, :id).first
I've got a Rails 4 app on a Puma server with Resque/Resque-Scheduler running background jobs. What I'd like to know is how I merge the log output of my two Resque workers into my server log, or, of that is not possible, how I can view the log output of my Resque workers. Currently I have not been able to figure out how to view the log output for the workers, so I have no idea what's happening under the hood. I found this blogpost, which suggests adding the following likes to my resque.rake file:
task "resque:setup" => :environment do
Resque.before_fork = Proc.new {
ActiveRecord::Base.establish_connection
# Open the new separate log file
logfile = File.open(File.join(Rails.root, 'log', 'resque.log'), 'a')
# Activate file synchronization
logfile.sync = true
# Create a new buffered logger
Resque.logger = ActiveSupport::BufferedLogger.new(logfile)
Resque.logger.level = Logger::INFO
Resque.logger.info "Resque Logger Initialized!"
}
end
That didn't work. I also tried the suggestion in the comments, which was to replace Resque.logger = ActiveSupport::BufferedLogger.new(logfile) with Resque.logger = ActiveSupport::Logger.new(logfile), however that didn't work either. With the second option, I still get a NoMethodError: undefined method 'logger=' for Resque:Module error when I try to boot up a worker.
Here is my current resque.rake file:
require 'resque/tasks'
require 'resque_scheduler/tasks'
namespace :resque do
puts "Loading Rails environment for Resque"
task :setup => :environment do
require 'resque'
require 'resque_scheduler'
require 'resque/scheduler'
require 'postman'
end
end
I've looked at the Resque docs on logging, but am not sure how to use what's there as I admittedly don't know very much about logging in Rails. I haven't had any luck finding other useful resources on the subject.
How I fix it, it is not perfect but just works.
my environment: rails 5.0.1, resque: 1.26.0
at the first time, I set the Resque.logger and Resque.logger.level in config/initializers/resque.rb as most docs suggest:
# config/initializers/resque.rb
Resque.logger = Logger.new("#{Rails.root}/log/resque.log")
Resque.logger.level = Logger::DEBUG
then in the job, I output log by Resque.logger.info:
# update_xxx_job.rb
class UpdateXxxJob
def self.perform
Resque.logger.info 'Job starts'
...
end
end
it doesn't work, I can see nothing in log/resque.log.
then someone said should set the logfile sync always, no buffer, so I update the config/initializers/resque.rb according a question from stackoverflow:
# config/initializers/resque.rb
logfile = File.open(File.join(Rails.root, 'log', 'resque.log'), 'a')
logfile.sync = true
Resque.logger = ActiveSupport::Logger.new(logfile)
Resque.logger.level = Logger::INFO
still doesn't work.
I also tried config resque logger in lib/tasks/resque.rake:
# lib/tasks/resque.rake
require 'resque'
require 'resque/tasks'
require 'resque/scheduler/tasks'
require 'resque-scheduler'
require 'resque/scheduler/server'
namespace :resque do
task setup: :environment do
Resque.schedule = YAML.load_file(Rails.root + "config/resque_scheduler_#{Rails.env}.yml")
Resque.redis.namespace = "xxx_#{Rails.env}"
Resque.logger = Logger.new("#{Rails.root}/log/resque.log")
Resque.logger.level = Logger::INFO
end
end
doesn't work.
finally, I decide to move the logger configuration from initializer to the job, so the job now looks like:
# update_xxx_job.rb
class UpdateXxxJob
def self.perform
Resque.logger = Logger.new("#{Rails.root}/log/resque.log")
Resque.logger.level = Logger::DEBUG
Resque.logger.info 'Job starts'
...
end
end
then I can get what I want in the log/resque.log.
you can try it.
I've had the same problem while setting up mine. Here's what I did:
Resque.before_fork do
# Your code here
end
It seems before_fork accepts a block as an argument rather than assigning a block to it.
I faced the same issue so that I check the source of resque and finally I needed to do the followings at initialization process:
define log formatter.
then define logger with log-file path.
set any log level.
Here the example is at my config/initializers/resque.rb in rails case:
...
Resque.logger = Logger.new("#{Rails.root}/log/resque.log")
Resque.logger.level = Logger::DEBUG
Resque.logger.formatter = ::Logger::Formatter.new # This is important
Resque default logger formatter is set here and its definitions is here. That apparently just ignores the output...
I'm receiving a "uninitialized constant ActiveSupport::Json" error on the line where I call responseJson = ActiveSupport::Json.decode(response), in a small controller in my small Rails app.
The response variable returns a string with a response of the type {"token":"this_is_your_session_token"}.
I've added gem 'activesupport', '~> 4.2.3', to my Gemfile, tried different require statements with 'active_support/core_ext/object/json, and tried this in the IRB (with the same error). I'm not sure how to debug this further. Any help would be greatly appreciated.
require 'active_support/json'
require 'active_support'
require 'active_support/all'
require 'rest-client'
class WelcomeController < ApplicationController
def login_attempt
username = params[:u]
password = params[:p]
puts "waiting on request"
response = RestClient.post 'http://localhost:3001/v1/login', :email => username, :password => password
responseJson = ActiveSupport::Json.decode(response)
end
end
ActiveSupport::JSON (all caps). FYI, if you use pry instead of irb, you can run a command like 'ls ActiveSupport' and see the contained modules, methods, etc.
I'm trying to move a current working task (in production and in the console) to use delayed_job in a Rails 2 app but keep getting the error:
ThermalImageJob failed with NameError: uninitialized constant Barby::Code128B
I've pored through others' code searching for an answer to no avail. Here's my code:
/lib/thermal_image_job.rb
class ThermalImageJob < Struct.new(:order_id)
def perform
order = Order.find(order_id)
order.tickets.each do |ticket|
ticket.barcodes.each do |barcode|
barcode.generate_thermal_image
end
end
end
end
/app/controllers/orders_controller.rb
Delayed::Job.enqueue(ThermalImageJob.new(#order.id))
/app/models/barcode.rb
def generate_thermal_image(format=:gif)
filename = "#{barcode}_thermal.#{format}"
temp_file_path = File.join("#{RAILS_ROOT}", 'tmp', filename)
unless FileTest.exists?(temp_file_path)
barcode_file = File.new(temp_file_path, 'w')
code = Barby::Code128B.new(barcode)
....
end
Gemfile
gem "delayed_job", "2.0.7"
gem "daemons", "1.0.10"
Well, after much head banging, I figured it out, so I'm posting this to help the next person. The problem was that it couldn't find the barby libs, so I added a require at the beginning of my class:
require "barby/outputter/rmagick_outputter"
require "barby/barcode/code_128"