Access to Delayed::Worker instance - ruby

I'd like to access Delayed::Worker instance to call say on it to save some messages in delayed_log file. Is there any simple way to achieve such behaviour?
class SomeDelayedJob
def perform
worker = __?__ # Delayed::Worker instance which called that perform method
worker.say('going to do x')
do_x()
end
end

Your best bet would be to use
Delayed::Worker.logger.[info|error|warn|debug] "going to do x"
with some formatting :)
because say internally uses the same logger object
Edit
Delayed::Worker.logger.[info|error|warn|debug] "#{Process.pid} at #{Time.now} => going to do x"
Hope this help

Related

Where can I store a mapping method?

I work on an app with Sinatra framework. I would know where the best place is to store a mapping method: in a controller or a decorator. In fact, I import data from a French website that has a French territory, and I want to convert the number territory from number to name.
Here is my method:
def territory_mapping(code)
{
'01' => 'Auvergne-Rhône-Alpes',
'02' => 'Hauts-de-France',
'03' => 'Auvergne-Rhône-Alpes'
}[code]
end
I want to know where I can store this method.
begin
case "my hash's use" do
when "it's for display" then
if "it's a small method"
"put it in a helper for use a controller"
else
"put it in a module and include it using via `helper`"
end
when "it's not for display" then "put it in a helper for use in a route block"
else
"it should go in the class that requires it."
end
rescue NoMethodError => e
e.message = <<~MESSAGE
If it doesn't work because the logic isn't defined
in your views or route blocks then it should go in
the class that requires it."
MESSAGE
ensure
"I get out more so I stop answering this question in Ruby ;-)"
end
In other words, put it in a helper and then you can assess later whether it should go somewhere else.
Regardless, #tadman is right about declaring that example hash as a constant, you should treat access to that as you would to any other constant - if you need it in more than one place then have it the level above in the namespace hierarchy. If it's a lot of data then #Stefan is right to say to load it from somewhere else.

Create an object from within a script Ruby

I am attemping to create an object from a class. But the objects will be created when they are needed.. Code below a bit hard to explain
incoming_message = #message sent though inter webs
class Repeater
def initialize(username, ip)
#repeat incoming message to back to ip
end
end
incoming_message = Repeater.new(user, ip)
Now I can't do that Becuase incoming_message is not a constant.
How would I get around this?
EDIT:
To clear things up a bit. I do need to use this class to create multiple objects with diffrent names. The repeater is for a chat server where an incoming message from 1 user is taken in then sent back out all of the clients connected. Each new client that connects would have a object created with that specific IP address so that messages from others can be send to the client.
It would take in messages from the other users by everyone sending to the server on the same port read the message then write to clients what it received...
I hope this helped sorry for all the confusion :)
If you want to maintain some kind of global class-level state, you should define a class-level accessor on Repeater that you can assign your repeating message to.
class Repeater
class << self
attr_accessor :incoming_message
end
def initialize(username, ip)
# repeat Repeater.incoming_message to back to ip
end
end
Repeater.incoming_message = "what"
Repeater.new(user, ip)
You need to use some parsing + serialization . Can they wire an already serialized/marshalled string?
1) convert the ruby code to yaml or json
2) use the json or yaml load method like myobj = YAML.load(new_yaml_string)
or
save it in another file called input and do a
require 'input'
create object of repeater

rails persist objects over requests in development mode

I am trying to interact with Matlab.Application.Single win32ole objects in my rails application. The problem I am running into is that while I am developing my application, each separate request reloads my win32ole objects so I loose the connection to my matlab orignal instances and new instances are made. Is there a way to persist live objects between requests in rails? or is there a way to reconnect to my Matlab.Application.Single instances?
In production mode I use module variables to store my connection between requests, but in development mode Module variables are reloaded every request.
here is a snippet of my code
require 'win32ole'
module Calculator
#engine2 = nil
#engine3 = nil
def self.engine2
if #engine2.nil?
#engine2 = WIN32OLE.new("Matlab.Application.Single")
#engine2.execute("run('setup_path.m')")
end
#engine2
end
def self.engine3
if #engine3.nil?
#engine3 = WIN32OLE.new("Matlab.Application.Single")
#engine3.execute("run('setup_path.m')")
end
#engine3
end
def self.load_CT_image(file)
Calculator.engine2.execute("spm_image('Init','#{file}')")
end
def self.load_MR_image(file)
Calculator.engine3.execute("spm_image('Init','#{file}')")
end
end
I am then able to use my code in my controllers like this:
Calculator.load_CT_image('Post_Incident_CT.hdr')
Calculator.load_MR_image('Post_Incident_MRI.hdr')
You can keep an app-wide object in a constant that won't be reset for every request. Add this to a new file in config/initializers/:
ENGINE_2 = WIN32OLE.new("Matlab.Application.Single")
You might also need to include the .execute("run('setup_path.m')") line here as well (I'm not familiar with WIN32OLE). You can then assign that object to your instance variables in your Calculator module (just replace the WIN32OLE.new("Matlab.Application.Single") call with ENGINE_2, or simply refer to them directly.
I know this is beyond the scope of your question, but you have a lot of duplicated code here, and you might want to think about creating a class or module to manage your Matlab instances -- spinning up new ones as needed, and shutting down old ones that are no longer in use.

Different log level for Sidekiq workers - Ruby approach?

I have a running environment with a Rails application, Sidekiq and clockwork mod for scheduling purposes.
I have many different workers, filled with logger.debug and logger.info instructions, and I occasionally need to activate debug logging on some of them to know what's going on.
I like the Sidekiq logger, and I would like to utilize it because it just need a "logger.debug" instruction in the workers to do its job.
What I miss with my current setup is the possibility to activate the DEBUG level for some workers, while leaving the others in standard INFO.
Now in each of my workers I have this initialize method:
class SendMailOnStart
include Sidekiq::Worker
sidekiq_options :retry => false, :queue => :critical
def initialize
logger.level = Logger::INFO
end
.... ...
But if a change the level in one worker, this level will be overwritten by the level specified in the next one - e.g. if two workers are processed together, the second one will "win".
What's the best way to achieve this in an elegant way?
Coming from Java world, I can think only to create a custom logger and putting it in each worker, copying output format used by Sidekiq logger, adding a logger method in each worker like
def logger
logger = MyLogger.new
end
and changing the level when I neeed it in initialize method
Is this the best approach in Ruby?
I had a similar question and I found this thread more useful:
Log to different logger based on call from Sidekiq or Rails
You should be able set the log level for Sidekiq workers specifically in the block mentioned there by altering Rails.logger.
I have no clue if that’s the best approach, but I would do the following. First of all, let’s prepare the function to retrieve the caller’s filename and/or method:
def parse_caller
# magic number 7 below is the amount of calls
# on stack to unwind to get your caller
if /^(?<file>.+?):(?<line>\d+)(?::in `(?<method>.*)')?/ =~ caller(7).first
file = Regexp.last_match[:file]
line = Regexp.last_match[:line].to_i
method = Regexp.last_match[:method]
[file, line, method]
end
end
Then I would override the default formatter of Logger instance, compelling it to check the caller:
logger.formatter = lambda do |severity, datetime, progname, msg|
f,l,m = parse_caller
# HERE GOES YOUR CHECK
if f =~ /…/
…
end
end
I know it looks a weird hack, but it works fine for me.

How to check if the object was created within this month

I have a task to find out if an object is created within this month or not. I tried a lot to resolve this. I used 1.month, since(-1), etc. But still I am not on a right track to proceed with these solutions.
I don't think there is a built in way to tell the creation time of an object. You would have to explicitly record the creation time.
class TheClassYouWantToMakeObjects
def initialize
#creation_time = Time.now
...
end
def created_within_same_month?
t = Time.now
t.year == #creation_time.year and t.month == #creation_time.month
end
end
Then, whenever you have object instance of TheClassYouWantToMakeObjects, you can check:
object.created_within_same_month?
Edit:
When you do your request, you compare your creation date with 1.month.since(-1) right?
If so, use instead Time.now.beginning_of_month. Time is a ruby class http://www.ruby-doc.org/core-1.9.3/Time.html
Could you write your request please?
Reedit: Great if it worked. My first explanation was not that explicit, thanks #Andrew.

Resources