Invoking Rails from an API

Hi,
I am trying to use ruby int an embedded web server. The environment
does not have the luxury of CGI or WebBrick. I find limited
documentation on how to get this to work. As a test program on windows,
I tried the code in the section below.
I have the issues.
1. Is public/dispatch.rb the right script to invoke a rails app? If
so, what is the right way to invoke dispatch.rb?
2. How can we clean up after the invocation, assuming multiple rails
app are running on the same server?
3. I understand ruby is unsafe for multithreaded invocation. Is
there a distribution that can handle multiple ruby VMs?
TIA.

SS

==SAMPLE CODE==

int main(int argc, char* argv[])
{

#if defined(NT)
NtInitialize(&argc, &argv);
#endif

ruby_init();
ruby_init_loadpath();


//chdir( "" );

::SetEnvironmentVariable( "SCRIPT_NAME", "/MyTest" );
::SetEnvironmentVariable( "REQUEST_URI", 

http://localhost:3000/MyTest#index” );
::SetEnvironmentVariable( “QUERY_STRING”, “” );
::SetEnvironmentVariable( “REQUEST_METHOD”, “GET” );
::SetEnvironmentVariable( “CONTENT_LENGTH”, “0” );

//ruby_script("embed" );
//rb_load_file( "public\\dispatch.rb" );
rb_load_file( "public\\dispatch.rb" );

//ruby_exec();
ruby_run();

ruby_finalize();

return 0;

}

==OUTPUT==
./public/…/config/boot.rb:15:in `require’: no such file to load –
rubygems (Lo
adError)
from ./public/…/config/boot.rb:15
from ./public/…/config/environment.rb:8
from public\dispatch.rb:3
Press any key to continue

I can’t answer all 3 questions, but I can get you past the error
you have listed. You just need a couple of envars set. This is what
I use on my system; you’ll need to change to compensate for Windows
and your path structure:

export RUBYLIB=/lib/ruby/site_ruby/1.8
export GEM_PATH=/lib/ruby/gems/1.8
export GEM_HOME=/lib/ruby/gems/1.8

As far as question 3, instead of spawning multiple threads, why not
create multiple processes? For low-volume sites this should be
sufficient. Solves question 2, too, as soon as the process terminates.

run rake freeze_gems in this rails install to cut the dependency on
rubygems

For future reference, this is what I ended up doing.

::SetEnvironmentVariable( "SCRIPT_NAME", "/MyTest" );
::SetEnvironmentVariable( "REQUEST_URI", 

http://localhost:3000/MyTest/index” );
::SetEnvironmentVariable( “QUERY_STRING”, “index” );
::SetEnvironmentVariable( “REQUEST_METHOD”, “GET” );
::SetEnvironmentVariable( “CONTENT_LENGTH”, “0” );

::WinExec( "c:\\ruby\\bin\\ruby.exe public\\dispatch.rb", SW_SHOW );

Note that you have to set the current directory to the root of the rails
app. We can improve by using CreateProcess() etc… but this is a start.

Lou,
Thanks! I tried your second suggestion and started a process. This
seems to work fairly well. I ended up emulating a CGI environment with
all the variables. It seems that the startup is the cost I pay in most
cases.
I studied the ruby codebase quiet a bit and it seems the api has to
be worked to support multiple threads. I hope the maintaner for the
codebase reviews the API to put in place holders for enabling threads in
the future. If not, we may end up with a kludge work-aroud as in perl.

On a different note, is it true that rails gets confused when 

multiple applications are running? What can be done to make rails handle
multiple apps in the same VM?

Lou V. wrote:

I can’t answer all 3 questions, but I can get you past the error
you have listed. You just need a couple of envars set. This is what
I use on my system; you’ll need to change to compensate for Windows
and your path structure:

export RUBYLIB=/lib/ruby/site_ruby/1.8
export GEM_PATH=/lib/ruby/gems/1.8
export GEM_HOME=/lib/ruby/gems/1.8

As far as question 3, instead of spawning multiple threads, why not
create multiple processes? For low-volume sites this should be
sufficient. Solves question 2, too, as soon as the process terminates.

What you really want to do is to get the C source for SCGI and add
scgi support to your c based webserver. Its a very simple protocol and
very performant. This will allow you to use rails, php and everything
else.

On 12/18/05, Sreekant S. [email protected] wrote:


Tobi
http://jadedpixel.com - modern e-commerce software
http://typo.leetsoft.com - Open source weblog engine
http://blog.leetsoft.com - Technical weblog

I plan to extend it to support SCGI. What I am trying to do is to
develop an embedded application server that hosts various scripting
environment, and I am constrained by a memory limitation on the server
to about 20MB. (This is an embedded environment). For me, RoR is a great
find. I like the agile capabilities on this platform. And I want to
bring it to the embedded space. For now, CGI is a workaround.

Thus, What I would like to do however is run ruby within the server
and thread it. Ruby startup takes upto 2 seconds on my machine. I don’t
think that is going away easily. The server itself is fast, and so is
the startup of the CGI process (relatively speaking).

There are a few optimizations in the interpreter also, that I found…
for example, the symbol lookup could benifit from lookup caching. But
these are minor tweaks compared to the benefit from the startup process.

Tobi, could you explain… how does ‘run rake freeze_gems’ help?

A question for you guys, I understand that there are multiple VMs out
there. YARV for example… do you know of Rails working on other VMs?
Has anyone done a compatibility matrix on all the VMs and its fit to
RoR?

Tobias L. wrote:

What you really want to do is to get the C source for SCGI and add
scgi support to your c based webserver. Its a very simple protocol and
very performant. This will allow you to use rails, php and everything
else.

On 12/18/05, Sreekant S. [email protected] wrote:


Tobi
http://jadedpixel.com - modern e-commerce software
http://typo.leetsoft.com - Open source weblog engine
http://blog.leetsoft.com - Technical weblog

Yeah, now that you mention it, I guess you are in essence writing a CGI
server.

I haven’t experienced or read about any innate Rails instability, but
some
http servers work better than others. [Hint: which server does
script/server
try to start by default?] The http server and judicious caching seems to
have
more of an affect on a stable app than any Rails or Ruby tweaking. There
have been reports of problems, but it’s hard to say just yet where the
root
of the problem lies. The platform is still evolving, even the drivers
and
interface protocols btn Rails and the http/cgi server.

I don’t know the answer to your last question. As long as all
non-immutable
shared resources (e.g. global vars, db connection pool) are accessed
atomically
there shouldn’t be cross-thread instability issues.

Sorry i should have been more specific.

the rake task freeze_gems is part of a standard rails 1.0 project. it
will copy all of rails into your projects directory ( vendor/rails/ to
be specific ). When the rails app notices that vendor/rails exists
during bootup it will load rails from there instead of trying to get
it from rubygems. This should also improve startup times slightly.

Tobi, could you explain… how does ‘run rake freeze_gems’ help?

A question for you guys, I understand that there are multiple VMs out
there. YARV for example… do you know of Rails working on other VMs?
Has anyone done a compatibility matrix on all the VMs and its fit to
RoR?

As far as i know the only VM which is close to implementing the full
ruby syntax is yarv and its not quite there yet. During rubyconf
earlier this year it was still missing some of the odder pieces of
ruby syntax like: { |*params| … }
I expect that we will be able to run rails on yarv after modifications
by the middle of next year. Yarv will be the VM which ships with ruby
2.0.


Tobi
http://jadedpixel.com - modern e-commerce software
http://typo.leetsoft.com - Open source weblog engine
http://blog.leetsoft.com - Technical weblog