From: Norman Makoto Su Date: 2002-03-27T11:18:58+09:00 Subject: FastCGI and threading Hello, I'm currently developing a web application server with fastcgi. I want to be able to handle multiple logins simultaneously. I noticed that in an approx year old post [ruby-talk:11922] matz mentions that fastcgi is not thread safe and that a thread-safe version will be released (by him or someone else). I'm wondering, is the current version of fcgi (C or pure ruby version) thread safe? From the official FastCGI web site, I notice that there are two versions-- a pure ruby version and a C version. I've played around with Eli's excellent ruby version but it seems that it will block all requests until the current request has been fully handled. I've written a simple toy server, client: ---server side: I added this line to my httpd.conf (among other fcgi configuration options) FastCgiExternalServer /usr/local/apache/fcgi-bin/test.rb -host localhost:9000 ruby script: z = 0 server = FastCGI::TCP.new('localhost', 9000) begin arr = [] server.each_request do |request| arr[arr.length] = Thread.new { puts "Connection received!" request.out << "Content-type: text/plain\r\n\r\n" request.out << "Z = #{z}" sleep 5 if (arr.length % 2) == 0 z = z + 1 request.finish } end arr.each { |aThread| aThread.join } # not needed? ensure server.close end ---and then this on the client: h = Net::HTTP.new('some web server') resp, data = h.get('/fcgi-bin/test.rb', nil) puts data I expect that if I run two instances of the client at once, the server app would print out "Connection received!" followed immediately by another "Connection received!". Instead, it always waits for one of the requests to fully handle before going on to the next one. This is exactly what I don't want-- rather, I want the threads to immediately go off and do their stuff. Right now, its just _fully_ executing each request sequentially, one after another. Also, I expected both instances of the client to perhaps print out Z=0 (but it is always Z=0, Z=1). I've tried various things like moving request.finish: out = request.out request.finish out << "Content-type: text/plain\r\n\r\n" out << "Z = #{z}" But that seems to mess things up and the client returns: /usr/local/lib/ruby/1.6/net/protocol.rb:221:in `error!': 500 "Internal Server Error" (Net::ProtoFatalError) from /usr/local/lib/ruby/1.6/net/http.rb:1217:in `value' from /usr/local/lib/ruby/1.6/net/http.rb:605:in `get' from test_client2.rb:5 My environment setup is linux Apache 1.3.12 using mod_fastcgi 2.2.12 and ruby 1.6.7 (client-cygwin). On a side note, I have noticed several multi-threading versions of fastcgi for python (sz_fcgi.py (a wrapper for a nonthreaded version), thfcgi.py) on the fastcgi official page. I'm wondering if an explicit threading version/wrapper is needed for ruby's fastcgi? Or perhaps, I'm just using threads incorrectly? Any help would be greatly appreciated, fastcgi will just make things a lot easier for my development. I've corresponded with Eli regarding this matter, but, understandably, he seems quite busy and I'd like any other opinions or suggestions as to how to proceed. Thanks, -- Norman Makoto Su