run Ruby/EventMachine script as a system service - ruby

I've written a simple UDP server in Ruby using EventMachine. I'd like to keep it always running on my Linux box. Suggestions on how to wrap it up as a system service or in some other form that launches at start-up, stays running, can be monitored?

As you are on linux you can use daemons gem
http://daemons.rubyforge.org/
http://railscasts.com/episodes/129-custom-daemon

The Thin webserver, which is built on top of EventMachine, uses the daemons gem: https://github.com/macournoyer/thin/blob/master/lib/thin/daemonizing.rb
To keep it running, use Monit, which can be configured to check that the process is running, restart it if it's not, or restart if it starts using too much system resources, or an endless array of other possible conditions.

I would use Cron with [#restart][1]. A well behaved daemon should check if its already running before running again.
[1]: https://help.ubuntu.com/community/CronHowto#Advanced Crontab

All these answers are outdated. Ruby has perfect Process.daemon method: http://www.ruby-doc.org/core-2.1.0/Process.html#method-c-daemon
Just add Process.daemon in your application before EM.run and all should work.

Related

Queued jobs are somehow being cached with Laravel Horizon using Supervisor

I have a really strange thing happening with my application that I am really struggling to debug and was wondering if anyone had any ideas or similar experiences.
I have an application running on Laravel v5.8 which is using Horizon to run the queued jobs on a Ubuntu 16.04 server. I have a feature that archives an account which is passed off to the queue.
I noticed that it didn't seem to be working, despite working locally and having had the tests passing for the feature.
My last attempt to debug was me commenting out the entire handle method and added Log::info('wtf?!'); to see if even that would work which it didn't, in fact, it was still trying to run the commented out code. I decided to restart supervisor and tried again. At last, I managed to get 'wtf?!' written to my logs.
I have since been unable to deploy my code without having to restart supervisor in order for it to recognise the 'new' code.
Does Horizon cache the jobs in any way? I can't see anything in the documentation.
Has anyone experienced anything like this?
Any ideas on how I can stop having to restart supervisor every time?
Thanks
As stated in the documentation here
Remember, queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers.
Alternatively, you may run the queue:listen command. When using the queue:listen command, you don't have to manually restart the worker after your code is changed; however, this command is not as efficient as queue:work:
And as stated here in the Horizon documentation.
If you are deploying Horizon to a live server, you should configure a process monitor to monitor the php artisan horizon command and restart it if it quits unexpectedly. When deploying fresh code to your server, you will need to instruct the master Horizon process to terminate so it can be restarted by your process monitor and receive your code changes
When you restart supervisor, you are basically restarting the command and loading the new code, your behaviour is exactly as expected to be.

Is it possible to use both of pm2 and forever command for aws node server starting?

I am going to stop current aws node server but I don't know which command is used for server starting.
So I can't stop current node server.
If I use forever or pm2 for server starting without stopping current instance , what happens?
Is it possible to use this?
Is old instance stopped after starting new server using pm2 or forever command?
Thanks in advance.
For forever you can use
forever list
to see if there are any instances running and then use
forever stop <instance uid> to stop it
You probably will not be able to run the script again since it will try to use the same port as the running instance, but if you wish, you can always run another instance on a different port like:
forever start app.js --port=5000
So, yes, you can run many instances, but on different ports.
pm2 should be working the same way, I haven't used it though, you should read the help.

Deploy Java executable in EC2

I have written a little java tool to benchmark NoSQL databases. Because I dont have enough computers I want to run the benchmark tool and some database nodes in the Amazon EC2.
Is that possible?
-> Can I deploy a java app in the EC2 without any further config.?
Thank you
Can I deploy a java app in the EC2 without any further config
Yes. If you were running a typical web app, you might investigate Elastic BeanStalk. But that wouldn't work for benchmarking.
EC2 computers are just computers, except instead of installing the OS manually, you get to select a pre-installed OS to boot from, called an AMI. You could look around for an image with Java pre-installed, but it's fairly easy to boot your favorite Ubuntu/Fedora/Centos/AmazonLinux and do "apt-get install java" or "yum install java".
At first, you'll upload your program to the box and SSH in to test it. But when you get a workflow going, it's better to upload your program to S3, then have the box download it at boot. (S3 is usually faster than your upload speed, and more reliable.)
If you have just a "tiny" bit of config to do at boot, you can use cloud-init. This will run a pre-defined script at boot. (Just put the commands in the EC2 user-data config at boot.) It could be as simple as 3 commands: install java, download my app, run my app.
For more sophisticated operations, you'll want to use Chef, Puppet, or Ansible to orchestrate multiple servers.
But for something simple like your benchmarking idea, you can easily "roll your own" using the AWS API. Use a library (Boto for Python, Fog for ruby. I'm sure there are several for Java) to write a program that does the following:
1) launch an instance with a cloud-init script that installs a NoSQL DB
2) wait for it to get an IP.
3) launch another instance with a cloud-init script that configures your java test program, and passes in the IP from step 2.
4) waits for it all to run, then collects the run info (or maybe the info is stored in S3 so you can collect it later)
5) cleans up by terminating the instances (It helps to tag them so you can clean up easier)
You could do all this manually, but when you find a bug, you'll want to re-run everything, and automation will make that a breeze. Plus, you'll want to repeat your findings on various instance sizes.
Once you get things working, you can switch to spot instances when running your actual benchmarks: They take longer to launch, but can save a ton of money. So spot instances are annoying for development, but perfect for running bulk tests where you don't care about the launch time.
You can think of EC2 as just a set of computers that you can rent time on. You have total control over the EC2 VMs, and can install and run almost any software you want on them, including database servers and your java app.
You'll probably find the practical limitation is the amount of time you want to spend setting them up. You'll need to sign up for an Amazon account, set up your instances, install an OS, install DB servers, install your java app, etc...
See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html to get going.

Ruby. Run a script in the background like in Node with Forever

Using Daemons right now, but I don't want to code the daemon, just want a script that restarts the server when it's killed and that storages logs.
Thank you :)
I'd try God gem.
Other information that may be useful for you:
God en Github:
Railscast

Resque + Sinatra + Heroku how to run the jobs continuously

I have already setup Redis + Resque and deploy on heroku already. Everything works fine, and the jobs are added to the queue correctly. But it won't be run until I run command
heroku run rake jobs:work
How do I tell heroku to run the jobs in the queue automatically in background?
I'm using Sinatra and not Rails.
Thank you very much.
You need to add a worker process to your application that will automatically run the rake jobs:work process for you continuously.
You can do this via the UI on Heroku.
There is a much better (IMHO) way to do this using IronWorker. Iron.io will basically always be cheaper, and I find the approach easier to set up and use. http://www.iron.io/

Resources