Can I determine if Ruby code is executing in a Sidekiq job? - ruby

Can I do something like the following? If yes, how do I implement in_sidekiq_job?
def method_for_anyone_to_call
if in_sidekiq_job
puts "hey! I'm running in a Sidekiq job."
end
end

You can use Sidekiq.server? for that, i.e.:
def method_for_anyone_to_call
if Sidekiq.server?
puts "hey! I'm running in a Sidekiq job."
end
end

Related

A ruby script to run other ruby scripts

If I want to run a bunch of ruby scripts (super similar, with maybe a number changed as a commandline argument) and still have them output to stdout, is there a way to do this?
i.e a script to run these:
ruby program1.rb input_1.txt
ruby program1.rb input_2.txt
ruby program1.rb input_3.txt
like
(1..3).each do |i|
ruby program1.rb input_#{i}'
end
in another script, so I can just run that script and see the output in a terminal from all 3 runs?
EDIT:
I'm struggling to implement the second highest voted suggested answer.
I don't have a main function within my program1.rb, whereas the suggested answer has one.
I've tried this, for script.rb:
require "program1.rb"
(1..6).each do |i|
driver("cmd_line_arg_#{i}","cmd_line_arg2")
end
but no luck. Is that right?
You can use load to run the script you need (the difference between load and require is that require will not run the script again if it has already been loaded).
To make each run have different arguments (given that they are read from the ARGV variable), you need to override the ARGV variable:
(1..6).each do |i|
ARGV = ["cmd_line_arg_#{i}","cmd_line_arg2"]
load 'program1.rb'
end
# script_runner.rb
require_relative 'program_1'
module ScriptRunner
class << self
def run
ARGV.each do | file |
SomeClass.new(file).process
end
end
end
end
ScriptRunner.run
.
# programe_1.rb
class SomeClass
attr_reader :file_path
def initialize(file_path)
#file_path = file_path
end
def process
puts File.open(file_path).read
end
end
Doing something like the code shown above would allow you to run:
ruby script_runner.rb input_1.txt input_2.txt input_3.txt
from the command line - useful if your input files change. Or even:
ruby script_runner.rb *.txt
if you want to run it on all text files. Or:
ruby script_runner.rb inputs/*
if you want to run it on all files in a specific dir (in this case called 'inputs').
This assumes whatever is in program_1.rb is not just a block of procedural code and instead provides some object (class) that encapsulates the logic you want to use on each file,meaning you can require program_1.rb once and then use the object it provides as many times as you like, otherwise you'll need to use #load:
# script_runner.rb
module ScriptRunner
class << self
def run
ARGV.each do | file |
load('program_1.rb', file)
end
end
end
end
ScriptRunner.run
.
# program_1.rb
puts File.open(ARGV[0]).read

log in non sidekiq class

I have a worker that delegates the work to another class like this:
class SynJob
include Sidekiq::Worker
sidekiq_options queue: :sync
def perform(user_id)
OtherClass.new(blah, blah, blah)
end
end
class OtherClass
def initialize
puts "we are in OtherClass"
end
end
My question is, how do I log to stdout from OtherClass.
My puts statements do not show up in the heroku stdout log.
The literal answer to your question is to use puts or other Ruby APIs for writing to stdout. You can call this both in your SynJob or your OtherClass code and it will execute the same, writing to the stdout of the sidekiq worker process.
However, this probably is not what you want to do. If this is a Rails app, you probably want to write to the Rails logger, which should be available both in your worker and in other code:
Rails.logger.info "I'm a debug message"
This will show up in the appropriate log both locally and when running deployed on Heroku.

How to read and process a file in Ruby with EventMachine

I am wondering if anybody figured out a way to process bigger (500Mb+) text files with EventMachine, where you actually need to access the individual lines.
I guess I found the answer, the only thing is messy is the read_chunk gets called in the after io.gets, and I am not sure why it works :)
require 'eventmachine'
def process_line(line)
puts line
end
EM.run do
io = File.open('query_profiles.csv')
read_chunk = proc do
if line = io.gets
process_line(line)
EM.next_tick(read_chunk)
else
EM.stop
end
end
EM.next_tick(read_chunk)
end

Running windows cmd using ruby rake

I'm trying to run some windows command line calls in the same system
process using a Ruby Rake task. I need to find the way to do the calls
correctly and this calls can't be dependent on each other.
I know that the 'fork' function can be a solution, but it doesn't work
in Windows. I tried with other functions, like IO.POPEN and
Process.spawn and I didn't find a real solution.
I'm working with Ruby 1.9.3 in windows XP.
task :CmdTest,:value do |t, args|
value=args.value.to_s
begin
$cmd<<("set MYVAR=#{value}")
$cmd<<("set MYVAR")
$cmd<<("exit")
rescue Exception => e
puts e.message
end
end
task :CmdTest3 do
IO.popen("cmd", "r+") do |io|
th = Thread.new(io) do |chan|
chan.each {|line| puts line}
end
$cmd.each do |f|
io.puts f
end
io.close_write
th.join
end
end
Take a look at win32utils, is that what you are after?

How do you test code that forks using rspec

I have the following code
def start_sunspot_server
unless #server
pid = fork do
STDERR.reopen("/dev/null")
STDOUT.reopen("/dev/null")
server.run
end
at_exit { Process.kill("TERM", pid) }
wait_until_solr_starts
end
end
How would I effectively go about testing it using rspec?
I thought something along
Kernel.should_receive(:fork)
STDERR.should_receive(:reopen).with("/dev/null")
STDOUT.should_receive(:reopen).with("/dev/null")
server.should_receive(:run)
etc
I'm confused by the #server instance variable and server method in your example, but here is an example that should help you get where you're trying to go:
class Runner
def run
fork do
STDERR.reopen("/dev/null")
end
end
end
describe "runner" do
it "#run reopens STDERR at /dev/null" do
runner = Runner.new
runner.should_receive(:fork) do |&block|
STDERR.should_receive(:reopen).with("/dev/null")
block.call
end
runner.run
end
end
The key is that the fork message is sent to the Runner object itself, even though its implementation is in the Kernel module.
HTH,
David
David's solution didn't work for us. Maybe it's because we're not using RSpec 2?
Here's what did work.
def run
fork do
blah
end
end
describe '#run' do
it 'should create a fork which calls #blah' do
subject.should_receive(:fork).and_yield do |block_context|
block_context.should_receive(:blah)
end
subject.run_job
end
end
I'm not sure how this would apply when calling a constant, such as STDERR, but this was the only way we were able to accomplish fork testing.

Resources