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>