Redis publish in rails 4 stops server thread - ruby-on-rails

Sorry for english, i'm newbie.
Trying to use redis.publish feature with rails 4 and redis gem to push messages with SSE.
I have this block in my controller
logger.info "test1"
$redis.publish "user", "test"
logger.info "test2"
where $redis -
$redis = Redis.new(:host => '127.0.0.1', :port => 6379, :db => 1,:timeout => 0)
in initializer.
Server console in production print
I, [2013-08-07T22:34:50.138232 #4679] INFO -- : test1
And then nothing. Another request working, but this thread stops.
By the way, this $redis.publish "user", "test" at RAILS_ENV=production rails console run perfectly and message successfully appear at client.
Can you help me?
UPD: Ruby 2.0-p247, Rails 4, Redis 3.0.4

Don't use one connection in initializer to subscribe and publish both.
I created 2 connections, 1 for subscribe in sse writer, 1 in controllers to publish, and everything working normally.

Related

Foreman terminates after the whole process and doesn't run accordingly as defined in Procfile

I am working on importing data from web based CSV into database, so I created a rake task that imports data into database. However I tried to make running my rails app a little seamless and I integrated the import rake task and running rails server into foreman.
However, when I run foreman start, the processes start but terminates after the rake task finishes. I also will like that rake task to start first before running rails s
Here is what I have done below:
lib/tasks/web_import.rake
require 'open-uri'
require 'csv'
namespace :web_import do
desc 'Import users from csv'
task users: :environment do
url = 'http://blablabla.com/content/people.csv'
# I forced encoding so avoid UndefinedConversionError "\xC3" from ASCII-8BIT to UTF-8
csv_string = open(url).read.force_encoding('UTF-8')
counter = 0
duplicate_counter = 0
user = []
CSV.parse(csv_string, headers: true, header_converters: :symbol) do |row|
next unless row[:name].present? && row[:email_address].present?
user = CsvImporter::User.create row.to_h
if user.persisted?
counter += 1
else
duplicate_counter += 1
end
end
p "Email duplicate record: #{user.email_address} - #{user.errors.full_messages.join(',')}" if user.errors.any?
p "Imported #{counter} users, #{duplicate_counter} duplicate rows ain't added in total"
end
end
Procfile
rake: rake web_import:users
server: rails s
when I run forman start, the image below shows the process
I will like the rake task in the foreman to run first before running rails s command. I also don't want it to terminate by itself. I don't know what am doing wrong.
Any help is appreciated.
I solved this by refactoring the Procfile. Instead of having two tasks, I merged it to just one command using && so I can determine which command takes the prefix and which one takes the suffix.
So I changed the profile to:
tasks: rake web_import:users && rails s -p 3000
With this I have my import run first and server command being the last.
If you noticed, I added port with -p flap so as not make sure server is listening on port 3000. Note adding port is optional.
I hope this helps someone as well.

Redis keeps calling out to localhost:6379 even though deployed to Heroku

I have a Rails app deployed to Heroku and I cant for the life of me figure out why it keeps wanting to deploy to the local. I do not even have localhost:6379 anywhere in my code for the front end (react native) or the back end which is my Rails API.
This is the error I get any time I have a new broadcast:
Completed 500 Internal Server Error in 111ms (ActiveRecord: 47.1ms)
Redis::CannotConnectError (Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)):
Application.yaml:
`gmail_username: "<email_address>"
gmail_password: "<password>"
AWS_ACCESS_KEY: "<access_key>"
AWS_SECRET_KEY: "<secret_key>"
AWS_BUCKET: "<my_s3_app_bucket>"
REDIS_URL: "<redis_url>"`
Cable.yaml
production:
adapter: redis
url: <long_url_address>
host: <host_from_url>
port: <port_from_url>
password: <password_from_url>
Production.rb:
config.action_cable.allowed_request_origins = ["https://lynx-v1.herokuapp.com/"]
config.action_cable.url = "wss://lynx-v1.herokuapp.com/cable"
config.web_socket_server_url = "wss://lynx-v1.herokuapp.com/cable"
(i set both action cable and web socket just to test which worked, no matter which i go with i still get the error)
/config/initializers/redis.rb
require "redis"
uri = URI.parse(ENV["REDIS_URL"])
$redis = Redis.new(
:url => ENV["REDIS_URL"],
)
I dont know what is going on. Is it some kind of default that makes Redis look for local host 6379? I follow the steps step by step and I keep getting this error.
It started working again. There was an add-on gem in the rails app that was not fully configured. After finishing the setup for the side gem it started working again.

PG::UnableToSend: no connection to the server in Rails

I have a production server running ubuntu 14.04, Rails 4.2.0, postgresql 9.6.1 with gem pg 0.21.0/0.20.0. In last few days, there is constantly error with accessing to a table customer_input_datax_records in psql server.
D, [2017-07-20T18:08:39.166897 #1244] DEBUG -- : CustomerInputDatax::Record Load (0.1ms) SELECT "customer_input_datax_records".* FROM "customer_input_datax_records" WHERE ("customer_input_datax_records"."status" != $1) [["status", "email_sent"]]
E, [2017-07-20T18:08:39.166990 #1244] ERROR -- : PG::UnableToSend: no connection to the server
: SELECT "customer_input_datax_records".* FROM "customer_input_datax_records" WHERE ("customer_input_datax_records"."status" != $1)
The code which call to access the db server is with Rufus scheduler 3.4.2 loop:
s = Rufus::Scheduler.singleton
s.every '2m' do
new_signups = CustomerInputDatax::Record.where.not(:status => 'email_sent').all
.......
end
After restart the server, usually there is with first request (or a few). But after some time (ex, 1 or 2 hours), the issue starts to show up. But the app seems running fine (accessing records with read/write & creating new). There are some online posts about the error. However the problem seems not the one I am having. Before I re-install the psql server, I would like to get some ideas about what causes the no connection.
UPDATE: database.yml
production:
adapter: postgresql
encoding: unicode
host: localhost
database: wb_production
pool: 5
username: postgres
password: xxxxxxx
So, the error is "RAILS: PG::UnableToSend: no connection to the server".
That reminds me of Connection pool issue with ActiveRecord objects in rufus-scheduler
You could do
s = Rufus::Scheduler.singleton
s.every '2m' do
ActiveRecord::Base.connection_pool.with_connection do
new_signups = CustomerInputDatax::Record
.where.not(status: 'email_sent')
.all
# ...
end
end
digging
It would be great to know more about the problem.
I'd suggest trying this code:
s = Rufus::Scheduler.singleton
def s.on_error(job, error)
Rails.logger.error(
"err#{error.object_id} rufus-scheduler intercepted #{error.inspect}" +
" in job #{job.inspect}")
error.backtrace.each_with_index do |line, i|
Rails.logger.error(
"err#{error.object_id} #{i}: #{line}")
end
end
s.every '2m' do
new_signups = CustomerInputDatax::Record.where.not(:status => 'email_sent').all
# .......
end
As soon as the problem manifests itself, I'd look for the on_error full output in the Rails log.
This on_error comes from https://github.com/jmettraux/rufus-scheduler#rufusscheduleron_errorjob-error
As we discuss in the comments, the problem seems related to your rufus version.
I would suggest you to check out whenever gem and to invoke a rake task instead of calling directly the activerecord model.
It could be a good idea, however, to open an issue with the traceback of your error in the rufus-scheduler repo on github (just to let then know...)

Nginx+Passenger: rufus-scheduler not started

I want to do background processing by using rufus-scheduler. It works fine on my local machine with the Webrick server but it is not working on the production server. My production server uses Nginx + Passenger.
My code is as below
scheduler = Rufus::Scheduler.new
scheduler.in '20s' do
loop do
Rails.logger.error "+++++++++++started+++++++++++"
requests = QrCodeRequestStatus.where(:status => "pending").first(5)
requests.each do |request|
Rails.logger.error "+++++++++++++++++++processing request #{request.client_id} of client #{request.client_id}"
AuthenticationCode.save_qr_codes(Client.find(request.client_id),request,request.quantity.to_i)
end
Rails.logger.error "+++++++++++++++sleeping+++++++++++++++++"
sleep 5
end
end
scheduler.join
I have set "PassengerSpawnMethod direct" in my Passenger config file but still, rufus-scheduler is not working.

discrepancy between requiring a path in rails console vs. rails s (WeBRICK)

I'm using Machinist blueprints in development.
from development.rb:
config.after_initialize do
require 'spec/support/blueprints'
puts "********* blueprints loaded! *********"
end
it works fine in the console.
michael-schwabs-macbook-pro:medtext mschwab$ rails c
********* blueprints loaded! *********
Loading development environment (Rails 3.0.7)
irb(main):001:0> d = Doctor.make
=> #<Doctor id: 101, first_name: nil, ....
When I run the server, my controllers know that my models respond to #make, but they don't know that the blueprints are defined.
(rdb:70) Doctor.respond_to?(:make)
true
(rdb:70) Doctor.make
RuntimeError Exception: No blueprint for class Doctor
This is odd because the statement
require 'machinist/active_record'
is in the blueprints.rb file. Also, the "loaded!" statement gets printed out in my server log.
=> Ctrl-C to shutdown server
********* blueprints loaded! *********
=> Debugger enabled

Resources