El Sábado, 12 de Diciembre de 2009, David Masover escribió: > On Saturday 12 December 2009 03:54:00 pm Iñaki Baz Castillo wrote: > > El Sábado, 12 de Diciembre de 2009, David Masover escribió: > > > I suspect you'd have a chance to at > > > least fire that unlink call with any death except a 'kill -9'. > > > > Ok, so do you say that using "upstart" this problem could be solved as > > upstart itself could manage it when detects a service crash? > > I'm saying most aspects of it can be solved within the program -- anything > except 'kill -9'. With something like upstart, even that should be > solvable. On OS X, I think launchd is similar. Basically, you have one (or > more) central process(es) which manage the launching and killing of > daemons. > > At this point, you don't even have to use pidfiles, you can just use > variables. In pseudocode: > > class Process > def start > unless running? > if @pid = fork > waitpid(@pid) do > @pid = nil > end > else > exec @cmdline > end > end > end > def stop > kill @pid > end > end > > The main reason that's pseudocode is that upstart very likely already does > this for you (so why reinvent the wheel in Ruby?), and because waitpid > doesn't actually work that way. > > But basically, the only problem with this model is that if the process > responsible for watching your process dies abnormally, either the pidfile > won't be cleaned up (if there is one), or you'll now have an unmonitored > copy of your process running (so you'll need something like killall > again). If you're using something like upstart, that's not really a > problem -- remember, upstart is init, which means the second it dies, the > kernel panics. In other words, it doesn't die. It's really great and makes lots of sense. The classic usage of pidfiles and so seems ugly and "deprecated" stuff. > > > So, that gives you the best of both worlds -- it's actually somewhat > > > like one of the crazier solutions I suggested. > > > > Great. However I'm not sure if my program would fit well as a gem. It's > > not a library or utility but a whole http server (for XCAP protocol). > > This is, it will have conf files into /etc directory and so. I've never > > seen a gem that installs a server by itself and contains files in /etc. > > The usual approach I'd suggest here is, store a configfile path, something > like the PATH variable, in which later configfiles override values set by > earlier ones. Then, set all the default values in a sample config file > inside your gem, and let the admin put a conf file in /etc/rb_app (or in > ~/.rb_app, But can a gem installation generate a default conf file/directory in /etc? I know gem installations can generate runnable files into /usr/bin (or /usr/local/bin). This is, I wouldn't like that the user has to create by himself the config fiel/directory in /etc :( > or in a place specified by the environment variable > RB_APP_CONFIG, or in a place specified by --config on the commandline) if > they want to override something. I like --config option as I already have command line options for chossing logging directory, process uid/gid, listening port and so. Command line options override values in the configuration file. > On the other hand, you might consider just building a Debian package, > depending on the interpreter you want, and hardcoding it into the shebang > and the upstart scripts. The problem is that my server requires 6-7 gems and modern version of them (for example Debian Lenny just includes Rack version 0.3 !! while current gem version is 1.0.1 !!). > Let people download the source if they want to > tweak it further. But I'd only go this route if you're content to depend > on the Ruby libraries that are already packaged in Debian -- unlike some > other package managers, apt lacks a way to depend directly on truly alien > packages. (Contrast to Gobo, in which system packages can depend directly > on gems, CPAN modules, etc -- I know Gentoo could depend on CPAN modules, > too.) This is the reason why I prefer to build a Gem rather than a deb package. Creating the former would require package all the gems withing the deb package which would make difficult to upgrade gems and so. Well, after this good thread (thanks a lot) I think I'll do the following: - A gem package depending on others gems (as usual). - Some runnable Ruby scripts (built into the gem) like: - myprogram_create_conf.rb: Creates conf files under /etc. - myprogram_create_init.rb: Creates the init script. - myprogram_create_database.rb: Creates database for the server. These scripts could have different behaviour depending on the detected Linux distribution, this is, when running "myprogram_create_init.rb" would detect the Linux distribution and offer different kinds of init scripts (and why not: a upstart script for Ubuntu/Debian !). Thanks a lot! -- Iñaki Baz Castillo <ibc / aliax.net>