Is there a "spawn" equivalent for Ruby 1.8.7? - ruby-on-rails

Is there a spawn equivalent for ruby 1.8.7?
It appears as though it was introduced in 1.9.1
http://apidock.com/ruby/Kernel/spawn
I need the following to work in ruby 1.8.7:
def run_worker(queue, count = 1)
puts "Starting #{count} worker(s) with QUEUE: #{queue}"
ops = {:pgroup => true, :err => [(Rails.root + "log/resque_err").to_s, "a"],
:out => [(Rails.root + "log/resque_stdout").to_s, "a"]}
env_vars = {"QUEUE" => queue.to_s}
count.times {
## Using Kernel.spawn and Process.detach because regular system() call would
## cause the processes to quit when capistrano finishes
pid = spawn(env_vars, "rake resque:work", ops)
Process.detach(pid)
}
end

You can achieve this in 1.8.7 using this gem - https://github.com/rtomayko/posix-spawn.
It does not support "full" 1.9's Process::spawn interface, but your example should work with it just by changing Process::spawn to POSIX::Spawn::spawn (https://github.com/rtomayko/posix-spawn#status).

Related

Ruby FrozenString error in Sidekiq Worker

I am using Ruby on Rails and trying to use a Sidekiq worker, but at some point I'm running into an issue where the worker calls a view, the view calls a concern, and then the concern isn't able to update a variable in its function because of the FrozenString error.
For example, here's how my worker looks:
class ReportGeneratorWorker
include Sidekiq::Worker, ReportHelper
sidekiq_options queue: Rails.env.to_sym
def perform
ac_base = ApplicationController.new
body_html = ac_base.render_to_string template: "common/report_templates/generate_pdf.html.erb", layout: false
end
end
Again, the view inserts text that leverages a concern, but the concern doesn't allow it to update. See below for example:
[3] pry(#<#<Class:0x00007fec8ceea400>>)> html
=> "<ul>"
[4] pry(#<#<Class:0x00007fec8ceea400>>)> html.class.name
=> "String"
[5] pry(#<#<Class:0x00007fec8ceea400>>)> html << "Hello"
FrozenError: can't modify frozen String
from (pry):5:in `replacement_text'
Any idea why this is happening? If I define the variable again from the Pry console, then it actually works:
[1] pry(#<#<Class:0x0000557f07a25130>>)> html
=> "<ul>"
[2] pry(#<#<Class:0x0000557f07a25130>>)> html << "TEST"
FrozenError: can't modify frozen String
from (pry):2:in `replacement_text'
[3] pry(#<#<Class:0x0000557f07a25130>>)> html = "<ul>"
=> "<ul>"
[4] pry(#<#<Class:0x0000557f07a25130>>)> html << "TEST"
=> "<ul>TEST"
[5] pry(#<#<Class:0x0000557f07a25130>>)>
I was able to resolve this issue by replacing << with +=.

Wice_Grid CSV export not working - Uninitialized constant CSV::Writer

I "inherited" a rails aplication running with ruby 1.8.7 in development.
I have a wice_grid table which I'm trying to export in CSV and in development all goes perfect.
When I push it to production, i get the following error:
uninitialized constant CSV::Writer
The production machine is running Ruby 1.9.1 and from what I read, I suppose the problem comes from there.
I've tried to put:
required 'csv'
In the controller or the model, but nothing happens, development works, production does not.
Here is the controller code:
def index
require 'csv'
#service_requests = initialize_grid(ServiceRequest,
:name => "solicitudes",
:order => "created_at" ,
:order_direction => 'desc',
:include => [:user, :service],
:enable_export_to_csv => true,
:csv_file_name => 'Listado de Solicitudes'
)
export_grid_if_requested('solicitudes' => 'service_requests') do
#Si se pulsa en exportar se exportan todos las celdas de la tabla seleccionada (con filtros aplicados)
end
end
Here is the part of the view, which calls a partial:
<%= render :partial => 'service_requests' %>
Here is the partial, cropped for making the question not too long:
<%= grid(#service_requests, :show_filters => :always) do |service_request|
[...]
service_request.column :column_name => 'Nombre' , :attribute_name => 'name', :model_class => User do |sr|
sr.user.name
end
service_request.column :column_name => 'Apellidos' , :attribute_name => 'lastName' , :model_class => User do |sr|
sr.user.lastName
end
[...]
end %>
I read this thread but didnt help me much: write csv in ruby 1.9 and CSV::Writer
Thank you all in advance!
Somewhere, that you haven't posted, you are referencing CSV::Writer. This works locally because you're using Ruby 1.8.7, but your production server is using Ruby 1.9.1. CSV::Writer was deprecated with Ruby 1.9.
From the the docs:
# * The old CSV's Reader and Writer classes have been dropped.
Step one is to upgrade your local Ruby to the same version as the server. This will give you the same error locally, which should go away once you find and remove that CSV::Writer.
The CSV docs give examples of how to use the current CSV class to accomplish what CSV::Writer used to do. Here's an example:
# == Writing
#
# === To a File
#
# CSV.open("path/to/file.csv", "wb") do |csv|
# csv << ["row", "of", "CSV", "data"]
# csv << ["another", "row"]
# # ...
# end
Upgrading Ruby will probably raise other errors. But Ruby 1.8.7 was retired in 2013 so these are problems you're going to want to fix now rather than later.
Good luck!

What is the best way to "put" in Rails Resque worker

I am calling puts statements like this:
puts "something"
Within my Rails Resque workers. What is the best way to read this output real time? tail development.log?
Thanks!
You could always try to use the Logger:
Logger.info "Something"
# Or
Logger.debug "Something"
# Or
Logger.error "Something"
These will definitely show up in your logs. :)
I recommend using Log4r:
In config/environments/*.rb
#format of message in logger
format = Log4r::PatternFormatter.new(:pattern => "%d - [%l]:\t%m.")
# log configuration
configlog = {
"filename" => "log/your_name.log",
"max_backups" => 28, # 7days * 4 files of 6 hours
"maxtime" => 21600, # 6 hours in sec
"maxsize" => 10485760, # 10MB in bytes
"trunc" => false
}
rolling = Log4r::RollingFileOutputter.new("rolling",configlog)
rolling.formatter = format
config.logger = Log4r::Logger.new("your_name.log")
config.logger.add(rolling)
Then in your code:
Logger.info "output"
Logger.debug "output"
In your_name.log you will see:
2013-08-07 10:00:47 - [INFO]: output
2013-08-07 10:00:47 - [DEBUG]: output

Nokogiri parsing different on server versus localhost

I'm getting some weird differences when running Nokogiri locally versus running it on my server. On my local machine the entire document seems to parse and be available but on the server I seem to get the doctype tab and some random comment tags.
To start off, to make sure it wasn't a problem with open-uri I checked it - the results are not exact but do contain the correct markup.
Local:
ruby-1.8.7-p352 :005 > s = open('http://www.pennstateind.com/store/PK2WAY.html')
=> #<File:/var/folders/G8/G8bsAGBk1o82Eyks3ZmFtq-+3Y6/-Tmp-/open-uri20120626-5891-10y2ncr-0>
ruby-1.8.7-p352 :006 > s.length
=> 88408
Server:
rb(main):008:0> s = open('http://www.pennstateind.com/store/PK2WAY.html')
=> #<File:/tmp/open-uri20120626-22167-1td2l72-0>
irb(main):009:0> s.length
=> 98184
When I run this on my local machine I get this:
ruby-1.8.7-p352 :003 > d = Nokogiri::HTML(open('http://www.pennstateind.com/store/PK2WAY.html'))
=> [ OUTPUT OMITTED FOR BREVITY - CAN SUPPLY ON REQUEST ]
ruby-1.8.7-p352 :004 > d.to_s.length
=> 85212
But when I run this on the server I get this:
rb(main):006:0> d = Nokogiri::HTML(open('http://www.pennstateind.com/store/PK2WAY.html'))
=> #<Nokogiri::HTML::Document:0x36620e14b580 name="document" children= [#<Nokogiri::XML::DTD:0x36620e14b1c0 name="html">, #<Nokogiri::XML::Comment:0x36620e14b170 " Open Graph Tags ">, #<Nokogiri::XML::Comment:0x36620e14a98c " Customer_Session_Verified: 0 ">]>
irb(main):007:0> d.to_s.length
=> 172
The only apparent gem difference is for the JS compiler - all other gems are the exact version between local and server:
Local => libv8 (3.3.10.4 x86-darwin-10)
Server => libv8 (3.3.10.4 x86_64-linux)
Any ideas how to figure out what is going on and/or fix this?
Update - to isolate where the problem actually was I pulled a file from the server and from localhost then ran them on each. The results below show that the problem definitely lies in Nokogiri - what the problem is I am still perplexed by...
Running locally:
# FILE ORIGINALLY PULLED FROM SERVER
ruby-1.8.7-p352 :015 > server_file = File.open("/Users/jmcdonald/Desktop/files/SERVER.txt", "r")
=> #<File:/Users/jmcdonald/Desktop/files/SERVER.txt>
ruby-1.8.7-p352 :016 > server_file.read.length
=> 93071
ruby-1.8.7-p352 :022 > Nokogiri::HTML(server_file).to_s.length
=> 98793
# FILE ORIGINALLY PULLED FROM LOCALHOST
=> #<File:/Users/jmcdonald/Desktop/files/LOCAL.txt>
ruby-1.8.7-p352 :018 > local_file.read.length
=> 89622
ruby-1.8.7-p352 :026 > Nokogiri::HTML(local_file).to_html.length
=> 94632
Running on server:
# FILE ORIGINALLY PULLED FROM SERVER
irb(main):001:0> sf = File.open('/home/charlest/public_html/files/nokogiri_issue/SERVER.txt', 'r')
=> #<File:/home/charlest/public_html/files/nokogiri_issue/SERVER.txt>
irb(main):002:0> sf.read.length
=> 93071
irb(main):004:0> Nokogiri::HTML(sf).to_s.length
=> 896 # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< WRONG
# FILE ORIGINALLY PULLED FROM LOCALHOST
irb(main):008:0> lf = File.open('/home/charlest/public_html/files/nokogiri_issue/LOCAL.txt', 'r')
=> #<File:/home/charlest/public_html/files/nokogiri_issue/LOCAL.txt>
irb(main):009:0> lf.read.length
=> 89622
irb(main):011:0> Nokogiri::HTML(lf).to_s.length
=> 896 # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< WRONG
It looks like your server and local environment are using different versions of libxml2. Older versions are known to have strange parsing bugs, so updating your server to the latest version you possibly can (or at least to the same version you're using for development) should fix you up.
There was also a bug with a shipped version of Nokogiri (I believe it affected 1.5.1) which affected the parsing in a some limited situations. I would suggest making sure your gems are updated. (gem update)
Try using File#read rather than File#open or make sure you're running lf.rewind before you try to parse w/ Nokogiri. The behavior you're seeing is most likely the result of your lf file handle being at the end of the file, which means Nokogiri is parsing an empty document.
> remote = File.open('./PK2WAY.html')
# => #<File:./PK2WAY.html>
> remote.read.length
# => 92978
> remote.read.length
# => 0
> Nokogiri::HTML(remote).to_s.length
# => 108
> remote.rewind
# => 0
> Nokogiri::HTML(remote).to_s.length
# => 93847

Encoding in Ruby 1.8.7 or 1.9.2

I have been trying to use the gem 'character-encodings' which doesn't build in 1.9.2 however it does in 1.8.7 but even when I require 'encoding/character/utf-8' I still cant do the simplest of encoding.
require 'encoding/character/utf-8'
str = u"hëllö"
str.length
#=> 5
str.reverse.length
#=> 5
str[/ël/]
#=> "ël"
I get
ruby-1.8.7-p302 > # encoding: utf-8
ruby-1.8.7-p302 > require 'encoding/character/utf-8'
=> nil
ruby-1.8.7-p302 > str = u"hll"
=> u"hll"
ruby-1.8.7-p302 > str.length
=> 3
ruby-1.8.7-p302 > #=> 5
ruby-1.8.7-p302 > str.reverse.length
=> 3
ruby-1.8.7-p302 > #=> 5
ruby-1.8.7-p302 > str[/l/]
=> "l"
My question is, is there a really nice encoding library that can accept allot or possibly all the different characters out there. Or maybe use utf-16? I have tried the magic code "# encoding: utf-8" which didn't seem to do it either.
Thank you
I'm afraid I don't understand your question. Are you having issues with the source code file? I've tried it both in console and a ruby script (1.8.7), and it does work.
require 'rubygems'
require 'encoding/character/utf-8'
str = u'hëllö'
puts str.length
puts str.reverse.length
puts str[/ël/]
and the output works as expected
5
5
ël
In Ruby 1.9+ (I tested in 1.9.2 preview) you don't need a library, as encoding is supported by the standard library. See this post for more information about it.
http://yehudakatz.com/2010/05/05/ruby-1-9-encodings-a-primer-and-the-solution-for-rails/
this works without c extensions and on 1.8/1.9, not all string methods work(but they are easy to add)
https://github.com/grosser/string19
require 'rubygems'
require 'string19'
String19('hëllö').length == 5

Resources