# Invoking Rails from an API

**URL:** <https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560>\
**Category:** Rails\
**Created:** [December 18, 2005, 3:40am UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560 "2005-12-18T03:40:23Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 18, 2005, 3:40am UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/1 "2005-12-18T03:40:23Z")

</div>

## 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](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

---

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 18, 2005, 2:51pm UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/2 "2005-12-18T14:51:48Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 18, 2005, 6:37pm UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/3 "2005-12-18T18:37:32Z")

</div>

run rake freeze\_gems in this rails install to cut the dependency on  
rubygems

---

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 18, 2005, 11:44pm UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/4 "2005-12-18T23:44:06Z")

</div>

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

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

```

“[http://localhost:3000/MyTest/index](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.

---

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 18, 2005, 11:40pm UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/5 "2005-12-18T23:40:21Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 19, 2005, 12:53am UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/6 "2005-12-19T00:53:49Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

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

---

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 19, 2005, 11:15pm UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/7 "2005-12-19T23:15:46Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > 
> 
> –  
> Tobi  
> [http://jadedpixel.com](http://jadedpixel.com) - modern e-commerce software  
> [http://typo.leetsoft.com](http://typo.leetsoft.com) - Open source weblog engine  
> [http://blog.leetsoft.com](http://blog.leetsoft.com) - Technical weblog

---

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 19, 2005, 1:41am UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/8 "2005-12-19T01:41:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Calling\_Rails\_using](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e19b73/32.png) [@Calling\_Rails\_using](https://www.ruby-forum.com/u/Calling_Rails_using)\
**Post date:** [December 20, 2005, 6:29am UTC](https://www.ruby-forum.com/t/invoking-rails-from-an-api/50560/9 "2005-12-20T06:29:19Z")

</div>

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](http://jadedpixel.com) - modern e-commerce software  
[http://typo.leetsoft.com](http://typo.leetsoft.com) - Open source weblog engine  
[http://blog.leetsoft.com](http://blog.leetsoft.com) - Technical weblog
