Prevent foreman to crash when typo in code - ruby-on-rails

I am using foreman gem on my Rails project to handle the different processes to be launched at startup (web, mailer, delayed job, ...).
It's working as expected but if I save a file with a typo or try to access a property on a nil object, foreman crash for all processes. I have to manually kill each ruby and node (for maildev) processes in order to run foreman start again.
Is there a way to prevent foreman to crash as the plumber plugin for gulp tasks ?
Thanks !
My project:
Rails 4.2
Ruby 2.2.0
Foreman
Server Unicorn
Mac OSX

Related

Puma stuck with message "Early termination of worker" on Rails 6 API only project at Elastic Beanstalk

I have a Rails 6 api-only application which I am failed to run at AWS Elastic Beanstalk. After deployment of that application, puma stucks with message "Early termination of worker". I don't have any custom configurations nor settings for that project. Simply created an environment and uploaded archived zip file.
After I kill puma processes with command pkill -9 -f puma my puma.log file looks like below:
=== puma startup: 2020-01-22 13:17:45 +0000 ===
=== puma startup: 2020-01-22 13:17:45 +0000 ===
[28858] Early termination of worker
[28856] Early termination of worker
[28862] Early termination of worker
[28865] Early termination of worker
[28869] Early termination of worker
I searched that error and found nothing for solve.
Ruby version: 2.6.5
Puma version 4.3.1
Rails version: 6.0.2.1
I am using Puma with Ruby 2.6 running on 64bit Amazon Linux/2.11.2 on AWS.
For the recent update from version 3.1.1 to 3.1.2 of the Ruby 2.6 running on 64bit Amazon Linux 2 platform, after checking the puma log in /var/log/puma/puma.log in my EC2 instance, it shows what you mention:
[XXXXX] Early termination of worker
[XXXXX] + Gemfile in context: /var/app/current/Gemfile
so, for checking what the actual error is, I entered my app's code folder /var/app/current and ran
pumactl start
this shows the actual error:
[XXXXX] Unable to load application: Gem::LoadError: You have already activated nio4r 2.5.3, but your Gemfile requires nio4r 2.5.2. Prepending `bundle exec` to your command may solve this.
So, since it says that there is a conflict of nio4r versions, I fixed it by forcing nio4r version to 2.5.3 adding this to my Gemfile:
gem 'nio4r', '2.5.3'
and then running bundle update, commiting and pushing changes and deploying.
Met the same error. Turns out it is a different PATCH of puma.
I was using this stack from elastic beanstalk
Ruby 2.6 AL2 version 3.0.1
64bit Amazon Linux 2 v3.0.1 running Ruby 2.6
Ruby 2.6.6-p146
RubyGems 3.1.2
Puma 4.3.3
...
My project's Gemfile included puma this way.
gem 'puma', '~> 4.3.3'
My project was a boilerplate for new projects that were coming my way, so things were working fine for "old" projects until the newer patch version, puma 4.3.5 as of now, came out.
Solution is to fix the version of the gem in the Gemfile as such:
gem 'puma', '= 4.3.3'
Lesson learnt is to always match your environment with that of your deployment tool. Keep track of the latest solution stack versions here.
Happens when Puma can't start.
Good News, you can run
bundle exec puma -p 3000 -e production
locally and then you get verbose errors.
I personally discovered a :optional tag on a has_many and some delayed_job issues that was breaking mine. So there is no one fix for this.
#Vic's answer is helpful, and you should make sure you have locked in the right Puma version, but it didn't fix my problem. For me, the issue was that a piece of my code called Rails.application.credentials[...], and the credentials weren't setup on the Elastic Beanstalk instance.
I changed that code to just use ENV variables, e.g., ENV["MY_VAR"], and set those environment variables in the Elastic Beanstalk Configuration->Software settings page.
Unfortunately, nothing in the logs I could find told me this is where my app was crashing. I had to start with a bare-bones Rails install, and slowly bring over Gems and code from my original project. Each time I added a file, I would use eb deploy to confirm it worked, and finally narrow down the problem to the one particular file that didn't work.
I forgot to tell about my project structure. I have a directory called overrides in under app/ folder.
Finally, I found at that app/overrides folder causes puma crash maybe related with this issue: How to ignore a folder in Zeitwerk for Rails 6?
After I changed my environment.rb file with ignoring app/overrides folder, my project started to run smoothly.
My puma config had an "on_worker_boot" block that was attempting a db connection. In my case I have a primary + replica setup in rails. Removing this connection statement from our puma config resolves the Early termination of worker error.
ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[ENV.fetch('RAILS_ENV')])
Ruby version: 2.6.2
Puma version 4.3.5
Rails version: 6.0.3.2

Force start Rails application through foreman only

I am using foreman in my Rails application and all works fine when I run foreman start but sometime I forget it and run only Rails application as rails s. Then I spend some time trying to investigate problems related to not working services (like sidekiq).
So, can somebody recommend a way how to force starting my application through foreman only? In other cases I want to see error message.
You could add an environment variable to .env, which is read when Foreman starts, and then check for its presence in a Rails initializer.

Unicorn hot restart with ruby 2.0.0 and Rails 3.2.14

I am running e-commerce ruby on rails application using Unicorn app server. The ruby version is 2.0.0 and the rails version is 3.2.14. I am running Nginx as web server. When ever I push the code to the server, I need to restart the unicorn app server, which is causing a blup/bleep in the website, I googled around for the solution but nothing seem to be working. I was using passenger before which was fine.
Is there any way to avoid blup's during restarting hence maintain zero downtime.
If you send USR2 to the unicorn master, it will cause the unicorn workers to restart, and should cause a zero downtime restart. Send the USR2 signal with:
kill -s USR2 process-id-of-master-process
Replace the process-id-of-master-process with the numeric process id of the unicorn master (find it with ps agx | grep unicorn, or look in the pids folder for unicorn.pid
Note that if unicorn is running under Bundler, you will still need to do a cold restart whenever you change the Gemfile, in order for the new Gemfile to be picked up.

Using JRuby and MRI for a common app

I need to use both JRuby and MRI for my rails app.
Here's the scenario -
My app uses a background server which handles a lot of threads. I'm having performance
issue with running it on MRI. The background server is started with a rake task and needs
to use the Rails environment.
I'm using Passenger for the Web Server. Since JRuby support for Passenger is quite recent,
I would like to go with using MRI.
Here's something I want -
This uses Ruby 1.9 to start the server :
sudo passenger start -p 80 -e production --user=deploy
and within the same app, this runs the background server -
jruby -S rake background_server:start_daemon RAILS_ENV=production
The problem is, the second command jruby -S rake asks for rebundling the app.
Is there any way I can get this in place?
Not in the same app. you'll need separate applications that run under different rubies if you want this to happen. in SOA architecture, you'd send a message to your background server for it to process a job.
So, in heroku you'd create one application for your web running in MRI; then you'd create an application in JRuby for your background processes. They'd communicate via a shared Redis or shared database.
I would recommend using Trinidad or Puma and keeping it all in JRuby though (as opposed to keep running passenger); it'll be a much simpler architecture.

Running nginx in rails automatically

I am using rails 2.3.9, rubygems 1.8.24, ruby 1.9.3 and Windows 7 ultimate 64-bit
I just installed nginx as my web server through passenger. Now I want to run nginx as my default server such that when i run ruby script/server, it runs instead of the default WeBrick. Is there any way to do this? Thanks a million.
Nginx doesn't work the way you described. Once it is started, you won't need to run script/server, the rails app will be run at the same time when the Nginx/Apache started.
So, just deploy your rails app following the 'Passenger' manual( in development mode), and you will get your app always running.
so, as conclusion, we can tell that, when deploying a Rails app, Nginx and Apache is in the same group( work together with Passenger), and Mongrel/Webrick/Thin is another group(script/server approach).
You may want to take a look at Foreman.

Resources