How do I start a Rails server programatically from a Ruby script - ruby

I want to start my Rails server in a background thread from within a Ruby script. I could use Kernel#system but I want to be able to kill the Rails server when the thread is stopped. Is there a way to execute the Rails server using some Rails API call instead? I'm thinking something it would be nice to be able to put something like Rails.run_server(:port => 3000, ...)
I'm on Windows Server 2008.

Check out the file gems/rails.x.x.x/lib/commands/server.rb. It looks like that's the starting point that script/server uses.
Since script/server is itself a ruby script, it stands to reason that you ought to be able to start a server by doing something similar to what's in server.rb. But I imagine you might have some difficulty getting your ruby environment right...
Note that I'm looking at rails 2.3.8 here, so if you're on 3.whatever your results will probably be different.

I eventually decided to avoid any ickiness and start the rails server in its own process, as detailed in this post. (Being able to kill it plus its child processes consistently was the main blocker and the original reason I'd considered starting it in a thread instead.)

Related

Start Phusion Passenger from Ruby code

I'd like to start the server from inside my gem code, the way Rails starts Unicorn, Puma, Webrick or whatever with "rails server". I'd like to have a binary like "mygem server" and that would start Passenger.
I tried with backticks but I'd like to avoid spawning another process if it's at all possible. (Also, I lost the stdout from Passenger when I did that.)
Is the command line the only way to start Passenger?
Passanger is a C++ "gem" that actually runs the Ruby layer separated from the root server process.
The developers consider this approach to protect the server from Ruby related issues (I think this isn't necessary, but it's definitely interesting).
This leaves you with a couple of options:
You could use Kernel.exec which replaces the current process with the command line you provide.
You could use another server, such as Puma, Iodine, Agoo or whatever you fancy.
Each server has their advantages and their disadvantages so test and pick and choose.
I know from experience that you can start all of them from within a block of code (or so I recall).

How to stop Event Machine in setup like this?

I have a Sinatra app, overall configured like described here sinatra docs.
It basically starts an event machine loop.
Now, If I want to write a RSpec test, how do I start server like this and shutdown it after?
I can do this from console by ruby server.rb, I may execute this command from spec file in test suit setup (however, I'm not sure if it is right). But then, even if I do so, how I stop it after? (and do I need or it will be stopped after test is finished?)
I think, in any case, you can use Rack::Test to test your Sinatra app. In order to run the specs, you don't need to run the server from the terminal.
Take a look at the documentation, you can find different examples:
http://www.sinatrarb.com/testing.html

Sinatra - Register startup and shutdown operations

I'm designing a web service using Sinatra and I need to perform certain operations when the service is started and some other operations when the server is stopped.
How can I register those operations to be fully integrated with sinatra?
Thanks.
The answer depends on how you need to perform your operations. Does they need to be ran for each ruby process or do they need to be ran just once for the service. I suppose it's once for all the service and in the case of the latest :
You might be tempted to run some code before your Sinatra app is starting but this is not really the behavior you might expect. I'll explain why just after. The workaround would be adding code before your sinatra class like
require "sinatra"
puts "Starting"
get "/" do
...
end
You could add some code to your config.ru too btw, would have the same effect but I don't which one is uglier.
Why is this wrong ? Because when you host your web service, many web server instances will be fired and each one will execute the puts method or your "starting" code. This is correct when you want to initialize things that are local to your app instance, like a database connection but not to initialize things which are shared by all of them.
And about the code firing at its end, well you can't (or maybe you could with some really ugly workaround, but you'll end with the same issue you get with the start).
So the best way to handle on and off operations would be to wrap it within your tasks firing your service.
Run some rake task or ruby script that do your initalization stuff
Start your web server
And to stop it
Run a rake task or ruby script that stops the server
Run your rake task or ruby script that does the cleaning operations.
You can wrap those into a single rake task, by starting your app server directly from ruby, like I did there https://github.com/TactilizeTeam/photograph/blob/master/bin/photograph.
This way you can easily add some code to get ran before starting the service, still keeping it into a single task. With some plumbing, I guess you can fire multiple thin instances and then allow you to start your cluster of thin (or whatever you use) instances and have still one task to rely on.
I'd say that adding a handler to the SIGINT signal could allow you to run some code before exiting. See http://www.ruby-doc.org/core-1.9.3/Signal.html for how to do that. You might want to check if Thin isn't already registering a trap for that signal, I'm not sure if this is handled in the library or in the script used to launch thin ( the "thin" executable that gets in your $PATH).
Another way to handle the exit, would be to have a watchdog process, that check if your cluster is running and could ensure the stop code is being ran if no more instances are running.

Can two different .rb files access the same variable?

I have scripts web.rb (sinatra) and rufus.rb (cron using rufus gem) running on the same computer (Win XP). Both are using functions.rb where I have all the functions. I have an array variable $webserver_status where I store history of commands web server performed/is performing. The web server runs some dos commands and php scripts and I want to be sure that only one runs at a time and also give the user some overview what is happening.
I used to run cron jobs (rufus.rb) over http so in fact I access the web server as from the browser. So the status variable was updated correctly. Now I started to call the same code from functions.rb so the variable doesn't show correct server status any more.
Is there any way cron can access the $webserver_status variable directly?
Or I have to update the variable over http? Or some kind of status file on the disk?
ruby 1.8.7 (2010-08-16 patchlevel 302) [i386-mingw32]
web server runs at all times
I have production and testing version of cron code
See the suggestions I made in this answer. The question was essentially the same unless I'm missing something in your scenario. There are many possible solutions depending on your needs.
Edit:
Based on your comment, I'm guessing that you want to share memory across two ruby processes or otherwise communicate between processes. Read about IPC in ruby to see how you could make UNIX sockets suit your needs.
It doesn't really make sense to talk about the same variable being accessed in two processes - you have to go via some kind of intermediary whether it's sockets, a database or a file. If this isn't what you want then I suggest you clarify the situation and why you need shared access to the memory rather than something like this.
I think something like this is what you're looking for:
#web.rb
require './functions'
print_value("apple")
and
#rufus.rb
require './functions'
print_value("not apple")
and
#functions.rb
def print_value(value)
puts value
end
Calling web.rb returns the string Apple.

ROR + Detect how many ports are running for ruby application

In my ruby on rails project, I have to take pull from sql-server to my mysql database.
When I run my project on port 3000, it makes system busy when I want to take pull.
I want such method or way which system can detect, how many ports are running for ruby application and how to close if it is not in use ?
Thanks in advance.
Hard to understand exactly what you're asking for, but I'm assuming that when you are synchronizing databases, the system becomes busy and you can't serve any pages. This is a perfect example for the use of a background job that allows you to do tasks like this without affecting the rails application. The two gems that come to mind that will allow you to do this is Delayed_job and Resque. An outstanding screencast for doing this type of stuff is listed below as well.
http://github.com/collectiveidea/delayed_job
https://github.com/defunkt/resque/
http://railscasts.com/episodes/171-delayed-job
http://railscasts.com/episodes/271-resque

Resources