backgroundrb thread_pool.defer method logger output goes to where? - ruby-on-rails

It seems like due to the threading issue logger.warn (thats what I tested) doesn't generate any output? my code is similar to this:
def deliver(args)
logger.info "delivery start"
thread_pool.defer(:deliver_deferred, args)
logger.info "delivery end"
end
def deliver_deferred(args)
logger.warn "whatsoever"
end
Any idea?

I'm not sure about the specifics, but assuming BackgrounDRb runs as a forked process, any open files would be closed for the forked child process. This would likely manifest itself as what you're seeing.
However, I would've assumed that BackgrounDRb would've been smart enough to handle that, since it ought to be a pretty obvious issue.

Related

How to run cyclic background process in Ruby-on-Rails?

I have some methods that works with API of third party app. To do it on button click is no problem, but it should be permanent process.
How to run them background? And how to pause the cycle for make some other works with same API and resume the cycle after the job is done.
Now I read about ActiveJob, but its has time dependences only...
UPDATE
I've tried to make it with whenever and sidekiq, task runs, but it do nothing. Where to look for logs I can't understand.
**schedule.rb**
every 1.minute do
runner "UpdateWorker.perform_async"
end
**update_worker.rb**
class UpdateWorker
include Sidekiq::Worker
include CommonMods
def perform
logger.info "Things are happening."
logger.debug "Here's some info: #{hash.inspect}"
myMethod
end
def myMethod
....
....
....
end
end
It's not exactly what I need, but better then nothing. Can somebody explain me with examples?
UPDATE 2 After manipulating with code it's absolutely necessary to restart sidekiq . With this problem is solved, but I'm not sure that this is the best way.
You can define a job which enqueues itself:
class MyJob < ActiveJob::Base
def perform(*args)
# Do something unless some flag is raised
ensure
self.class.set(wait: 1.hour).perform_later(*args)
end
end
There are several libraries to schedule jobs on a regular basis. For example you could use to sidekiq-cron to run a job every minute.
If you want to pause it for some time, you could set a flag somewhere (Redis/database/file) and skip execution as long it is detected.
On a somewhat related note: don't use sidetiq. It was really great but it's not maintained anymore and has incompatibilities to current Sidekiq versions.
Just enqueue next execution in ensure section after job completes after checking some flag that indicates that it should.
Also i recommend adding some delay there so that you don't end up with dead loop on some error inside job
I dont know ActiveJobs, but I can recommend the whenever gem to create cron (periodic background) jobs. Basically you end up writing a rake tasks. Like this:
desc 'send digest email'
task send_digest_email: :environment do
# ... set options if any
UserMailer.digest_email_update(options).deliver!
end
I never added a rake task to itself but for repeated processing you could do somehow like this (from answers to this specific question)
Rake::Task["send_digest_email"].execute

Handle a response code in test without polluting ApplicationController

My problem is that we're receiving mysterious 504 errors in SolanoCI, and I'm trying to find a clean way to handle them only in the test environment without adding test-specific code to our ApplicationController.
I've tried stubbing a default handler via the test setup like so:
allow(ApplicationController).to receive(:timeout).and_return {
#do a bunch of stuff to try to pull out request information
}
but I'm finding that it's lacking some important information that's accessible, like the original request url and any stacktrace information.
Any suggestions are welcome.
I think the easiest way for you in this situation would be to ask Solano to run a debugging session on their box for you (they give you ssh access to their server, so you may run tests yourself).
This is a real time saver in a black box situations like this. You may run tests multiple times and use all sorts of debugging tools there. You may have to install them first, since Solano tries not to install extra tools from your Gemfile (such as pry) to minimize test's running time.
Just write them via a contact form and they will give you an access. Don't forget to stop that session after you've done with it, since the time it runs is deducted from worker hours in your plan.
Hope it helps.
EDIT: It seems Anonymous controller feature is perfect for your case:
Use the controller method to define an anonymous controller that will
inherit from the described class. This is useful for specifying
behavior like global error handling.
So, you can do something like this:
RSpec.describe ApplicationController, :type => :controller do
controller(ApplicationController) do
rescue_from Timeout::Error, :with => :log_timeout
def log_timeout(error)
# log error as you wish
end
end
describe "handling timeout exceptions" do
it "writes some logs" do
get :index
expect(response).to have_https_status(504)
end
end
end

Delayed Jobs Hooks do not work?

I'm trying to make my delayed jobs hooks work, but they don't seem to be. Are they outdated? If they are not, can you show me an example of yours?
Here's mine:
class PhotoJob < Struct.new(:image_id)
def perform
Photo.find(self.image_id).regenerate_styles!
end
def error(job, exception)
if Photo.exists?(self.image_id)
Photo.find(self.image_id).regenerate_styles!
else
Delayed::Job.find(self).destroy
end
end
end
The reason I say they do not work is because if I upload a hundred images, half of them will fail with an error. If the error is raised, then the hook should be run, right?
Here's the catch, if I find the photo that's failing, and run Photo.find(n).regenerate_styles! , then the photo regenerates appropriately and works.
So I'm guessing that Delayed Jobs' hooks are not working.
They've been working ok for me:
class BaseProcessorJob
def perform
raise NotImplementedError
end
def error(job, exception)
Rails.logger.error "Job failed #{exception}"
end
end
I originally had a similar problem with hooks not getting called because of an outdated delayed_job gem (it was actually installed as a plugin, which caused my problems). Not sure if any of that helps you though.

Debugging - logging in development mode

NEWBIE logger question here:
What's the best way to log output to a development log for debugging purposes? How do you do it in a way that's quick, simple, effective?
To log in log/development.log:
Rails.logger.debug "Hello!"
Or, if you want to create a separate log, you could create a new logger in an initializer (config/initializers):
MyLogger = Logger.new(Rails.root.join("log", "custom.log"))
Then, in your app you can call:
MyLogger.debug "Hello!"
One option that I prefer over logging is using ruby debug. It allows you to put a break point anywhere in your code and inspect all local variables at that point in time. I find it more useful for tracking down bugs in cases where you have no friggin' idea what's going on and just want to look at everything.
Say you had a method like this and the behavior was not what you expected:
def my_method(arg)
# do something with argument
end
You could stick a debugger line in there:
def my_method(arg)
debugger
# do something with argument
end
You'll be able to then do things like this to get a better idea of what is going on:
p arg
p arg.method
p arg.another_method
p local_var
p local_var.method

How do I use a custom log for my rake tasks in Ruby on Rails?

I have a rake task that calls functions like this:
namespace :blah do
task :hello_world => :environment do
logger.info("Hello World")
helloworld2
end
end
def helloworld2
logger.info("Hello Again, World")
end
I want the log output to a custom log, and I really don't want to have to pass a log reference every time I make a function call. I found this somewhere (can't find it again):
def logger
##logger ||= Logger.new("#{RAILS_HOME}/log/blah.log")
end
But this does not work for me and I am not sure what it even does because I grabbed the code a long time ago and haven't used it until now. I can't search for ## on google (tried +"##" rails) to see what it does. Any help on this issue would be great. I am hoping for a quick solution and not having to install a gem or plugin (unless there is a really really good reason to.
Thanks!
rake disables logging in production mode. make sure you're running in development mode if you want it to log
What do you mean by "does not work for me"? I just tried this same code and it worked - created a new log file and put some text in it.
##logger is a class variable, it's a language issue, not Rails' one. I believe there's no need in further explanations :)
You've probably mistaken typing "function helloworld2" :)
Advanced Rails Recipes Recipe 84 from #topfunky shows how to define a custom logger. He has some code in the environment config file (production would look like this): RAILS_ROOT/config/environments/production.rb:
config.logger = RAILS_DEFAULT_LOGGER = Logger.new(config.log_path)
I'd test that out instead of redefining the class variable as you have. He might have something on http://nubyonrails.com to check as well.

Resources