# Mod\_ruby or FastCGI multiple instances single file

**URL:** <https://www.ruby-forum.com/t/mod-ruby-or-fastcgi-multiple-instances-single-file/69962>\
**Category:** Ruby\
**Created:** [September 25, 2006, 10:28pm UTC](https://www.ruby-forum.com/t/mod-ruby-or-fastcgi-multiple-instances-single-file/69962 "2006-09-25T22:28:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![frocco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a87d85/32.png) [@frocco](https://www.ruby-forum.com/u/frocco)\
**Post date:** [September 25, 2006, 10:28pm UTC](https://www.ruby-forum.com/t/mod-ruby-or-fastcgi-multiple-instances-single-file/69962/1 "2006-09-25T22:28:12Z")

</div>

Hi,

I’m in the process of moving from the J2EE to the Ruby world (+ Apache,  
Linux, MySQL, etc.), so this is likely to be a “stupid newbie” question.

I use mod\_ruby and understand that FastCGI operates along similar lines:  
there is one instance of the Ruby interpreter per Apache thread, but of  
course there may be lots of Apache threads, so lots of interpreters.

I want to log an event either to a log file or a database. Since this  
would be executed for every download from my site I think the log file  
route may be more appropriate (=faster).

My problem: “How can I write (append) to the same log file from multiple  
interpreter instances at least potentially simultaneously?”

In Java, I know that my application server has multiple threads and  
multiple classloaders, EARs, WARs and so on, but a single virtual  
machine; I’d create a singleton to open the file and synchronize the  
calls to the write method. Mission accomplished.

As I understand it Ruby will only allow me to open a file in append mode  
if nobody else currently has the file open for writing/appending. So  
when two interperters try to open the file at the same time, all but  
one will fail.

I could loop until the file is available but that would crash my app if  
the file is kept open for any reason. I could just accept that I can’t  
write to the log file and forget logging the line if I can’t open the  
file immediately but of course I’d be losing data… or I could write a  
daemon running its own single interpreter that serializes the writes…  
but surely this already exists somewhere?

This must be frequent problem and I’m sure I’m missing something? What  
is it?

Thanks for your help.

Best regards,

Frank

---

<div class="post-metadata">

**Author:** ![frocco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a87d85/32.png) [@frocco](https://www.ruby-forum.com/u/frocco)\
**Post date:** [September 26, 2006, 4:20am UTC](https://www.ruby-forum.com/t/mod-ruby-or-fastcgi-multiple-instances-single-file/69962/2 "2006-09-26T04:20:22Z")

</div>

Hello,

On Tue, 26 Sep 2006 05:28:15 +0900, Frank R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> My problem: “How can I write (append) to the same log file from multiple  
> interpreter instances at least potentially simultaneously?”

Take advantage of your operating system and use File’s flock features.  
For example this code snippet should do what you are asking for:

File.open(“foo.txt”, “w”) do |f|  
f.flock(File::LOCK\_EX)  
f.puts “Hello from #{Process.pid}”  
f.flock(File::LOCK\_UN)  
end

Try running the above code with multiple instances of ruby and loop.  
You should notice that each entry is on a new line with no data being  
clipped.

I hope that helps,  
Zev

---

<div class="post-metadata">

**Author:** ![frocco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a87d85/32.png) [@frocco](https://www.ruby-forum.com/u/frocco)\
**Post date:** [September 26, 2006, 12:46am UTC](https://www.ruby-forum.com/t/mod-ruby-or-fastcgi-multiple-instances-single-file/69962/3 "2006-09-26T00:46:11Z")

</div>

On 9/25/06, Frank R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi,
> 
> I’m in the process of moving from the J2EE to the Ruby world (+ Apache,  
> Linux, MySQL, etc.), so this is likely to be a “stupid newbie” question.
> 
> I use mod\_ruby and understand that FastCGI operates along similar lines:  
> there is one instance of the Ruby interpreter per Apache thread, but of  
> course there may be lots of Apache threads, so lots of interpreters.

No, it’s one instance of the ruby interpreter for the whole apache, as  
I recently found out. Plus ruby is not thread safe. Actually most  
interpreted languages are not thread safe. Perl is, and it’s the only  
embeddded interpreter for apache that I know of that runs under the  
worker mpm. Fastcgi is run completely outside of apache and it  
communicates with apache using it’s own protocol.

---

<div class="post-metadata">

**Author:** ![frocco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a87d85/32.png) [@frocco](https://www.ruby-forum.com/u/frocco)\
**Post date:** [September 26, 2006, 4:58am UTC](https://www.ruby-forum.com/t/mod-ruby-or-fastcgi-multiple-instances-single-file/69962/4 "2006-09-26T04:58:24Z")

</div>

On 9/25/06, Frank R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi,
> 
> I want to log an event either to a log file or a database. Since this  
> would be executed for every download from my site I think the log file  
> route may be more appropriate (=faster).
> 
> My problem: “How can I write (append) to the same log file from multiple  
> interpreter instances at least potentially simultaneously?”

Another possibility: write a single-threaded server on a localhost UDP  
port  
and have each handler in the apache process fire-and-forget a packet to  
the  
UDP server for each log line.

---

<div class="post-metadata">

**Author:** ![frocco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a87d85/32.png) [@frocco](https://www.ruby-forum.com/u/frocco)\
**Post date:** [September 26, 2006, 10:08pm UTC](https://www.ruby-forum.com/t/mod-ruby-or-fastcgi-multiple-instances-single-file/69962/5 "2006-09-26T22:08:26Z")

</div>

Thanks for all the great help.

I am fairly certain that I read somewhere that there is one interperter  
per Apache thread, but admitedly the documentation is fairly patchy 🙂  
I guess I’ll find out.

As for thread-safeness: long assignement (long i = 100;) is not  
thread-safe in Java (I’m not joking) because it is broken down into two  
byte codes, so nothing shocks me anymore 🙂

I had though of the UPD server but discarded it as too prone to  
producing down time (yet another component to worry about).

The flock solution sounds like the kind of solution I’m after. I’ll give  
it a try.

Zev B. wrote:

> Take advantage of your operating system and use File’s flock features.  
> For example this code snippet should do what you are asking for:
> 
> File.open(“foo.txt”, “w”) do |f|  
> f.flock(File::LOCK\_EX)  
> f.puts “Hello from #{Process.pid}”  
> f.flock(File::LOCK\_UN)  
> end

Thanks again for your help.

Best regards,

Frank
