Writing network daemon's is hard.
That's why I prefer not to do it. So for PPerl, I decided to have a go with Net::Server (after having originally written the daemon code using the stuff in the perl cookbook, and failed miserably). It worked really well, and despite being a little slower than my own custom daemon, it seemed really reliable and stable.
That was until I tried it on a real live system. I ended up with defunct processes left right and center, and finally the whole system just locked right up. Bah.
So what could I do? Well, I decided to bite the bullet and re-write it. So I grabbed code from Lincoln Stein's Network Programming with Perl book - the pre-fork web server in there, and adapted it to my needs. After much grappling it seems to be mostly working, though there are some extremely wierd things going on:
- My changing of STDERR to go to a file isn't working right for warn()'s unless I add in a $SIG{__WARN__} handler to print directly to STDERR.
- Occasionally it'll die with a "Connection reset by peer".
- Sometimes the <ARGV> magic fails for unusual reasons.
I guess I need to copy a bit more of the code from Net::Server to see where I'm going wrong (because now I don't have defunct processes any more).
Anyone got good experience with this kind of thing, or an alternate framework to Net::Server?
Note to self
autarch on 2002-06-07T16:07:34
Always hit preview;) Re:Stem
Matts on 2002-06-07T16:14:25
Asynchronous is inappropriate for PPerl - otherwise I would have used POE, and saved myself all these headaches.
Plus much as Stem looks neat, it's not CPAN installable.Re:Stem
autarch on 2002-06-07T16:45:22
you can install it by running "perl install.pl" as root.
Asynchronous isn't an issue. You can have a synchronous server with asynchronous code internally. Stem comes with a module, Stem::SockMsg that implements a socket-based listener. You use that and it feeds a message into your real server, which then replies. All the synchronous bits are managed by the Stem::SockMsg module.
Having written such a thing (to interface to a client that is _not_ Stem-based) I can tell you its pretty darn easy to do.Re:Stem
Matts on 2002-06-07T18:54:46
PPerl needs to fork. It just can't work any other way - yes I guess the socket itself could be select based and fork after the connection and multiplex in the results, but that would be slower than a prefork model.Re:Stem
autarch on 2002-06-07T19:58:10
You can do prefork with Stem too.
But you still need a single process listening on the socket that hands off the connection to the preforked processes, right?Re:Stem
Matts on 2002-06-07T20:02:58
No, you create your socket (binding it to the port), fork as many children as you hope to need, then call accept in each of the children. The OS decides which process to hand the connection to.Re:Stem
uri on 2002-06-08T00:17:13
stem has a neat module Stem::WorkQueue that makes a prefork server easier. you can prefork a bunch of processes and send all the incoming requests to the queue which first-come/first-serves them to the process farm. or you can look at the existing inetd demo which is pretty much what you want and it requires no new coding. it forks on demand but unless you need to fork massively often it should be fine. if you must have a preforking server, it should be easy to code up with the process and SockMsg modules and a manager module (that would be similar to thw queue module).Re:Stem
Matts on 2002-06-08T09:05:01
My major concern with using either Stem or POE with PPerl is that for PPerl I need access to the raw socket so that I can bind STDIN/ARGV and STDOUT directly to the socket. While I know I can do that with POE, it kind of circumvents the way POE is supposed to work. I'm not sure about Stem.
Re:Net::Server woes
rjray on 2002-06-08T01:03:25
I use Net::Server as an option in my RPC::XML package, an alternative to using the accept-loop in HTTP::Daemon. I also have a set of tests in the t/ directory for it, in which I manipulate the settings at run-time to control the log file and such. I haven't had any problems, but to be fair I probably have run anything yet that's on the scale of PPerl.
Re:non-forking
Matts on 2002-06-07T18:57:43
PPerl isn't line based - it passed the STDIN/STDOUT over the socket byte by byte. And it needs to fork (otherwise there's very little point - I would do it in POE if I didn't need it to work like this).
On the other hand, I've just "solved" or hacked around the ARGV magic stuff. Not sure why what I did worked, but that's what you get with wierd stuff like I'm trying to pull off.