Rails - default render streaming - ruby-on-rails

Normally Rails streaming requires:
render stream: true
in a controller action. Is there any way to make that the default for the whole controller? RailsCasts says it's possible with a stream class method:
class ApplicationController < ActionController::Base
stream # doesn't work
...
end
but that's not in the official docs and on Rails 4.1, I get undefined local variable or methodstream' for ApplicationController:Class`. It would be nice to be able to declare streaming in one place in order to keep actions DRY.

The default webserver in Rails 3,WEBrick, doesn’t support streaming so to see it in action we’ll need to switch to another that does, such as Unicorn. The Unicorn gem is listed in the application’s Gemfile but it’s commented out by default. To use it we uncomment this line and then run bundle to install it.
gem 'unicorn'
Then
$ bundle install
Unicorn supports streaming but it needs to be configured. For this, you
need to create a config file as follow:
# unicorn.config.rb
listen 3000, tcp_nopush: false
And use it on initialization:
unicorn_rails --config-file unicorn.config.rb
You may also want to configure other parameters like tcp_nodelay.
Please check its documentation for more information:
If you are using Unicorn with NGINX, you may need to tweak NGINX.
Streaming should work out of the box on Rainbows.
Hope it will work
For more consider Rails streaming

Related

How do we run some OS command when Rails is starting?

I need to run a command after or before starting Rails. It will start a server on port 9292 so my chat app will work.
This command should preferably be executed automatically with Rails (on production and development).
How do we do that in Rails 4?
Is Capistrano the only option? Can we schedule it to be executed when Rails starts?
Use capistrano and forman or systemd to manage your chat server instance, like, for example you would do for sidekiq.
A good start would be : http://anlek.com/2015/01/using-foreman-with-upstart-capistrano/
You have 2 options that I know of if you don't want to use Capistrano. In your config/application.rb
config.after_initialize do
# ....
end
http://guides.rubyonrails.org/configuring.html
or you can write a custom initializer that is run with on_server_start event.
There's a whole section of config/ intended for startup behavior: config/initializers/. If you need to do anything as part of the startup of your app, you can create an initializer file here, and it will automatically get run as Rails starts.
To do this, simply create a new file: config/initializers/chat_app.rb:
# This file will start and establish an initial connection to the chat app
`chat-app --some-arg` # <== The chat app
We use this for various startup and system sanity checks for the application. It's independent of your deployment, so if you need it for other deployment purposes, creating a Capistrano (or even Rake) task is the better option.

How can I tell if a vendored gem is being used?

I have inherited an old project that was previously passed on by multiple developers. It's in a bad shape so I'm trying to bring it back to life. I notice there are some gems and libs that have been vendored into the project but can't tell if they are being used or what!
How can I workout if some of those gems are no longer being used by the project?
A convenient way of checking this is by using a REPL. I would recommend installing the pry-rails gem, which will simply replace the default rails console (IRB) with the arguably more powerful Pry REPL.
#Gemfile
group :development do
pry-rails
end
Run bundle install, and than start the Rails console with bundle exec rails c. Once you are within Pry, you can use its built in show-source command to look up where a specific method has been implemented. Example:
>> show-source ActiveRecord::Base.establish_connection
From: /home/andrea/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb # line 128:
Owner: #<Class:ActiveRecord::Base>
Visibility: public
Number of lines: 11
def self.establish_connection(spec = ENV["DATABASE_URL"])
resolver = ConnectionSpecification::Resolver.new spec, configurations
spec = resolver.spec
unless respond_to?(spec.adapter_method)
raise AdapterNotFound, "database configuration specifies nonexistent # {spec.config[:adapter]} adapter"
end
remove_connection
connection_handler.establish_connection name, spec
end
For more usage examples on how to use this specific built-in command, refer to Pry's inline help system:
help show-source
Or have a look at the Source browsing page, on Pry's wiki.
there are some simple tricks that help you do that. you could for example put an puts caller i the root files of the gems and see if they get called from somewhere.
you could also use tracing functionality built into ruby like: http://apidock.com/ruby/Kernel/set_trace_func
or use external tracing tools.

How to log in a Ruby worker script of a Rails app that does not have the environment?

I'm using rufus-scheduler for handling cron jobs for a Rails 3.2.x app. The root worker.rb is being fired off by foreman (actually upstart on this particular server) and therefore when it starts off it does not have the Rails context in which to operate. Obviously when I attempt to call logger or Rails.logger it will fail each time.
I'm using log4r as a replacement for the default Rails Logger, which is quite nice, but I am wondering what the proper solution for this problem would be:
1) Do I need to give the script the Rails context at startup (it is simply running rake tasks right now so it ends up getting the Rails environment when the worker script hands off to the rake task and I fear giving the script the Rails env before running the timed task would be overkill since it takes so long to fire up the env)? or
2) Should I just set up log4r as one would do in a non-Rails Ruby script that simply reads in the same log4r.yml config that the Rails app is using and therefore participate in the same log structure?
3) Or some other option I'm not thinking of?
Additionally, I would appreciate either an example or the steps that I should consider with the recommended implementation.
For reference, I followed "How to configure Log4r with Rails 3.0.x?" and I think this could be helpful when integrated with the above: "Properly using Log4r in Ruby Application?"
I think this might be what you're looking for..
Use this within the worker itself, and create a custom named log file
require 'log4r'
logger = Log4r::Logger.new('test')
logger.outputters << Log4r::Outputter.stdout
logger.outputters << Log4r::FileOutputter.new('logtest', :filename => 'logtest.log')
logger.info('started script')
## You're actual worker methods go here
logger.info('finishing')

How to detect if a rails app is running under Unicorn?

I need to setup a connection to an external service in my Rails app. I do this in an initializer. The problem is that the service library uses threaded delivery (which I need, because I can't have it bogging down requests), but the Unicorn life cycle causes the thread to be killed and the workers never see it. One solution is to invoke a new connection on every request, but that is unnecessarily wasteful.
The optimal solution is to setup the up the connection in an after_fork block in the unicorn config. The problem there is that doesn't get invoked outside of unicorn, which means we can't test it in development/testing environments.
So the question is, what is the best way to determine whether a Rails app is running under Unicorn (either master or worker process)?
There is an environment variable that is accessible in Rails (I know it exists in 3.0 and 3.1), check the value of env['SERVER_SOFTWARE']. You could just put a regex or string compare against that value to determine what server you are running under.
I have a template in my admin that goes through the env variable and spits out its content.
Unicorn 4.0.1
env['SERVER_SOFTWARE'] => "Unicorn 4.0.1"
rails server (webrick)
env['SERVER_SOFTWARE'] => "WEBrick/1.3.1 (Ruby/1.9.3/2011-10-30)"
You can check for defined?(Unicorn) and in your Gemfile set: gem :unicorn, require: false
In fact you don't need Unicorn library loaded in you rails application.
Server is started by unicorn command from shell
Checking for Unicorn constant seems a good solution, BUT it depends very much on whether require: false is provided in the Gemfile. If it isn't (which is quite probable), the check might give a false positive.
I've solved it in a very straightforward manner:
# `config/unicorn.rb` (or alike):
ENV["UNICORN"] = 1
...
# `config/environments/development.rb` (or alike):
...
# Log to stdout if Web server is Unicorn.
if ENV["UNICORN"].to_i > 0
config.logger = Logger.new(STDOUT)
end
Cheers!
You could check to see if the Unicorn module has been defined with Object.constants.include?('Unicorn').
This is very specific to Unicorn, of course. A more general approach would be to have a method which sets up your connection and remembers it's already done so. If it gets called multiple times, it just returns doing nothing on subsequent calls. Then you call the method in after_fork and in a before_filter in your application controller. If it's been run in the after_fork it does nothing in the before_filter, if it hasn't been run yet it does its thing on the first request and nothing on subsequent requests.
Inside config/unicorn.rb
Define ENV variable as
ENV['RAILS_STDOUT_LOG']='1'
worker_processes 3
timeout 90
and then this variable ENV['RAILS_STDOUT_LOG'] will be accessible anywhere in your Rails app worker thread.
my issue:
I wanted to output all the logs(SQL queries) when on the Unicorn workers and not on any other workers on Heroku, so what I did is adding env variable in the unicorn configuration file
If you use unicorn_rails, below code will help
defined?(::Unicorn::Launcher)

Ruby/JRuby and WEBrick serving requests one at a time

Does anyone knows how to force WEBrick to process more than one request at a time? I'm using some Ajax on my page for long running database-related tasks and I can clearly see the requests are being processed in a pipeline.
If you use JRuby, check out the GlassFish gem (stripped-down GlassFish server in gem form), the Trinidad gem (same thing using Tomcat), or various other options like warbler (produces .war files you can run directly or deploy to any app server). JRuby is the easiest way for sure to deploy a highly-concurrent application on Ruby, and makes the C Ruby options look rather primitive in comparison.
webrick only processes one request at a time, which is usually fine for development.
If you want things to run in parallel have a look at mongrel_cluster or the awesome unicorn or passenger of course.
You should definitely not be using WEBrick for long running requests. The best web server for the job would probably be Thin, as it's powered by EventMachine which makes it possible to write asynchronous code so that the server doesn't block.
If you are running rails 4 you can apply the following patch and webrick will start serving requests concurrently.
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index e3119ec..ef04aa8 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
## -93,14 +93,6 ## module Rails
middlewares << [Rails::Rack::Debugger] if options[:debugger]
middlewares << [::Rack::ContentLength]
- # FIXME: add Rack::Lock in the case people are using webrick.
- # This is to remain backwards compatible for those who are
- # running webrick in production. We should consider removing this
- # in development.
- if server.name == 'Rack::Handler::WEBrick'
- middlewares << [::Rack::Lock]
- end
-
Hash.new(middlewares)
end

Resources