caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Eric Stokes <eric.stokes@csun.edu>
To: Gerd Stolpmann <info@gerd-stolpmann.de>
Cc: caml-list@inria.fr, Mike Hamburg <hamburg@fas.harvard.edu>
Subject: Re: [Caml-list] CamlGI question [doh]
Date: Tue, 19 Apr 2005 14:11:43 -0700	[thread overview]
Message-ID: <03900e2a40e57683649cd7d76261b427@csun.edu> (raw)
In-Reply-To: <1113933973.6248.76.camel@localhost.localdomain>

I've looked into this a bit more, and I have two things to say.

1. Unfortunately, it may not get any better than write. Once I slap on 
the fastcgi header telling the server how many bytes I'm going to 
write, I've committed to write that many bytes, If I don't its an 
error. That means I'd end up having to do the same thing as write if I 
used write_single. I'd have to check the return value to be sure that I 
wrote the correct number of bytes and if I didn't then call 
write_single again. This means that if there is an error on the third 
invocation, I'd have a protocol error, because some data has already 
been written. I might mitigate this by writing data in smaller chunks, 
but this can effect performance. I'll do some thinking about this.

2. We are not specific in the documentation about how you actually 
write threaded apps with Netcgi_fastcgi. This is very likely the cause 
of your problem. You need to call a new serv function for each thread 
that you want to work on web stuff. The idea is that each thread calls 
accept on the listening socket, and clients are distributed to threads 
in this manner. If your thread is never going to send data back via the 
fastcgi sockets then it is fine if it does not call serv, however any 
thread which communicates with the web server must do so only through 
serv. eg.

(* this is how I run threaded web applications via Ocamlnet *)
let worker_thread () =
   Netcgi_fcgi.serv req_handler
     buffered_transactional_optype;;

for i = 0 to numthreads
do
	Thread.create worker_thread ()
done

On Apr 19, 2005, at 11:06 AM, Gerd Stolpmann wrote:

> Am Dienstag, den 19.04.2005, 11:28 -0400 schrieb Mike Hamburg:
>> I'll try to help work out this bug in either Apache/FastCGI or Netcgi,
>> and if that doesn't work, I'll go to AJP.  I compiled 
>> mod_fastcgi-2.4.0
>> on Apache 2.0.53.  It successfully serves FastCGI pages written with
>> CamlGI, except that it sometimes pauses after 8k of data, and 
>> sometimes
>> breaks the pipe to the CGI.
>
> Just to make sure Netcgi works also for multi-threaded programs, I made
> a test for myself. I added a second thread to the example 
> add_fastcgi.ml
> (of Ocamlnet), such that it reads now
>
> let a = ref ["Z"; "X"; "A"; "P"; "B" ];;
>
> Thread.create
>   (fun () ->
>      while true do
>        a := List.sort compare !a
>      done
>   )
>   ()
> ;;
>
> (* start the fastcgi server *)
> serv process buffered_transactional_optype;;
>
> at the end. So there is now a thread sorting this list over and over
> again.
>
> I tried it with Apache 2.0.50 and mod_fastcgi 2.4.2 (those versions
> coming with Ubuntu Warty). The first test failed, I had to comment out
> the FastCgiWrapper which is part of the default configuration. After
> that, the program just worked.
>
> I also looked at the sources. There might be problems because the 
> O'Caml
> thread implementation uses signals to wake up threads in some
> situations. This may cause that the Unix.read/write (one should better
> use Unix.single_write, btw.) fail with EINTR. This is not caught.
>
>> Under Netcgi 1.0, the CGI version works but the FastCGI version does 
>> not
>> work at all.  The difference between the CGI and FastCGI versions is 
>> only:
>>
>> let () = Netcgi_fcgi.serv main (`Direct "<br><hr><br>");
>> (* let cgi = new Netcgi.std_activation ()
>> let () =  main cgi *)
>>
>> The application reads files from the outside world, and may launch
>> processes with fork+execv to thumbnail images.  It is multithreaded,
>> with at least 4 threads at all times: the main thread, a thumbnail 
>> cache
>> manager, a thread which handles signals (this cannot be done in a 
>> signal
>> handler, as it may block, so I wake up the handler thread instead), 
>> and
>> a thread which rereads the configuration files periodically, so that 
>> the
>> user does not have to send HUP.
>>
>> The application usually raises Unix.Unix_error (EPIPE, "write", "") on
>> the line Netcgi_fcgi.serv main (`Direct "<br><hr><br>") or rather,
>> inside Netcgi_fcgi.serv at some point; I believe this occurs before 
>> main
>> is called.
>
> You can figure this out exactly when you byte-compile the program with
> -g, and set OCAMLRUNPARAM=b=1, e.g. using a wrapper script and
> redirecting stderr to a file.
>
> The EPIPE error is quite surprising, because Netcgi wraps all its
> exceptions into FCGI_Error.
>
>>  The webserver also receives EPIPE and returns error 500.
>> Sometimes, I get other errors: sometimes main gets called, and I get
>> Failure("send_output_header").
>
> This is very strange, too. Failure("send_output_header") can only 
> happen
> when the HTTP header is printed at the wrong moment (i.e. too late).
>
>>  If this happens, then rollback_output
>> successfully prints "<br><hr><br>" but no more (i.e. no further
>> diagnostics).  Sometimes, the webserver times out waiting for the 
>> first
>> read, in which case the application still raises EPIPE.
>>
>> Is there any more information that would help to debug the problem?
>
> I suspect a part of the program prints something to stdout at the wrong
> moment, maybe because of a race condition. This is only my intuition,
> but this is the first thing I would try to look for. This would explain
> why the fcgi protocol is violated, and EPIPE is the logical consequence
> (the web server sees wrong data and shuts down the socket).
>
> Maybe an strace of the process can show what is really going on.
>
> Gerd
>
>>
>> Mike
>>
>> Alex Baretta wrote:
>>
>>> If at all possible, rather than AJP I'd stick to FastCGI.  The code 
>>> in
>>> Ocamlnet reportedly works fine, but I don't have experience with it.
>>> Are you sure that the broken pipe is caused by a bug in Ocamlnet and
>>> not in the web server?
>>>
>>> Alex
>>
>>
>>
>> Gerd Stolpmann wrote:
>>
>>> Am Montag, den 18.04.2005, 23:26 -0400 schrieb Mike Hamburg:
>>>
>>>
>>>> I'm obviously too tired to be programming.  That should, of course, 
>>>> read
>>>> (1) fix a broken pipe error in Netcgi_fast or
>>>>
>>>>
>>>
>>> Well, we would need more details to help you.
>>>
>>>
>>>
>>>> (2) port the application to (and configure the webserver for) AJP
>>>>
>>>>
>>>
>>> Porting the application is quite simple, just follow the examples 
>>> coming
>>> with Ocamlnet (in examples/jserv). For the webserver, you need mod_jk
>>> (jk=Jakarta). The configuration reference is here:
>>>
>>> http://jakarta.apache.org/tomcat/connectors-doc/config/apache.html
>>>
>>> Note that Ocamlnet only supports AJP-1.2, not 1.3 which is the 
>>> current
>>> default for Tomcat.
>>>
>>> Gerd
>>>
>>>
>>
>>
> -- 
> ------------------------------------------------------------
> Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany
> gerd@gerd-stolpmann.de          http://www.gerd-stolpmann.de
> ------------------------------------------------------------
>
>


  parent reply	other threads:[~2005-04-19 21:12 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-18  6:15 CamlGI question Mike Hamburg
2005-04-18  7:29 ` [Caml-list] " Robert Roessler
2005-04-18 13:49   ` Alex Baretta
2005-04-18 14:31     ` Gerd Stolpmann
2005-04-18 16:04       ` Michael Alexander Hamburg
2005-04-18 16:28         ` Alex Baretta
2005-04-19  3:23           ` Mike Hamburg
2005-04-19  3:26             ` [Caml-list] CamlGI question [doh] Mike Hamburg
2005-04-19  9:18               ` Gerd Stolpmann
2005-04-19 15:28                 ` Mike Hamburg
     [not found]                   ` <1113933973.6248.76.camel@localhost.localdomain>
2005-04-19 18:44                     ` Eric Stokes
2005-04-19 19:18                       ` Christophe TROESTLER
2005-04-19 21:11                     ` Eric Stokes [this message]
2005-04-19  9:31               ` Alex Baretta
2005-04-19 11:33 ` [Caml-list] CamlGI question Christophe TROESTLER
2005-04-19 12:51   ` Christopher Alexander Stein
2005-04-19 19:03     ` Common CGI interface (was: [Caml-list] CamlGI question) Christophe TROESTLER
2005-04-19 19:54       ` Gerd Stolpmann
2005-04-20  6:55         ` Jean-Christophe Filliatre
2005-04-20  7:22         ` Common XML interface (was: Common CGI interface) Alain Frisch
2005-04-20 11:15           ` [Caml-list] " Gerd Stolpmann
2005-04-20 11:38             ` Nicolas Cannasse
2005-04-20 13:23           ` Stefano Zacchiroli
2005-04-21  6:59             ` [Caml-list] Common XML interface Alain Frisch
2005-04-21 11:34               ` Gerd Stolpmann
2005-04-20 20:00         ` Common CGI interface Christophe TROESTLER
2005-04-20 21:06           ` [Caml-list] " Gerd Stolpmann
2005-04-21  7:36             ` [Ocamlnet-devel] " Florian Hars
2005-04-21 10:41               ` Gerd Stolpmann
2005-04-25 10:38             ` Christophe TROESTLER
2005-04-26 11:08               ` Gerd Stolpmann
2005-05-06 20:14                 ` Christophe TROESTLER
2005-05-10  0:07                   ` [Caml-list] " Christophe TROESTLER
2005-05-10  0:10                   ` Christophe TROESTLER
2005-04-26 16:24               ` [Caml-list] " Eric Stokes
2005-05-06 20:14                 ` Christophe TROESTLER
2005-04-19 20:13   ` [Caml-list] CamlGI question Michael Alexander Hamburg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=03900e2a40e57683649cd7d76261b427@csun.edu \
    --to=eric.stokes@csun.edu \
    --cc=caml-list@inria.fr \
    --cc=hamburg@fas.harvard.edu \
    --cc=info@gerd-stolpmann.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).