[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to write a Ruby service(?)?

Randy Kramer

3/18/2006 1:20:00 PM

I need to write what might be called a Ruby service or server(?)--a Ruby
program that:
* runs only one instance even if "invoked" multiple times
* can be sent additional "commands" via CLI commands, e.g., if the name of
the program is, for example, "program" I can issue multiple CLI commands
like:

program <parameters>

If program is not running, it will start and perform appropriate actions based
on the parameters.

If program is running, the existing instance of the program will receive those
parameters and perform appropriate actions.

At the moment (and maybe permanently ;-) I'm drawing a blank as to what a
program like that is called (service, server, ...?), and where to dig to
learn how to implement such a thing (preferably in Ruby).

Hints?

Initially I plan to implement this under Linux--some day it may get ported to
Windows, etc.

Thanks!
Randy Kramer

Incidentally, if the program crashes, the next invocation of the program will
restart it and recover as much of the previous "context" as possible (which
is, of course, only what has been recorded to disk).


4 Answers

Randy Kramer

3/18/2006 6:03:00 PM

0

On Saturday 18 March 2006 08:19 am, Randy Kramer wrote:
> I need to write what might be called a Ruby service or server(?)--a Ruby
> program that:
> * runs only one instance even if "invoked" multiple times
> * can be sent additional "commands" via CLI commands, e.g., if the name
> of the program is, for example, "program" I can issue multiple CLI commands
> like:

Oops, wait--I'm starting to wake up now--that would be a daemon, wouldn't it?
Off to Google [Ruby daemon].

But, any hints appreciated!

Randy Kramer


Pat Maddox

3/18/2006 6:12:00 PM

0

On 3/18/06, Randy Kramer <rhkramer@gmail.com> wrote:
> On Saturday 18 March 2006 08:19 am, Randy Kramer wrote:
> > I need to write what might be called a Ruby service or server(?)--a Ruby
> > program that:
> > * runs only one instance even if "invoked" multiple times
> > * can be sent additional "commands" via CLI commands, e.g., if the name
> > of the program is, for example, "program" I can issue multiple CLI commands
> > like:
>
> Oops, wait--I'm starting to wake up now--that would be a daemon, wouldn't it?
> Off to Google [Ruby daemon].
>
> But, any hints appreciated!
>
> Randy Kramer
>
>

Well fwiw, usually you would write two apps - a client and a server.
The server will be invoked once and daemonized, and you use the client
to issue commands. You can connect to the client either via TCP or
unix domain sockets.

Pat


Guillaume Marcais

3/18/2006 8:21:00 PM

0

Le 18 mars 06, à 08:19, Randy Kramer a écrit :

> I need to write what might be called a Ruby service or server(?)--a
> Ruby
> program that:
> * runs only one instance even if "invoked" multiple times
> * can be sent additional "commands" via CLI commands, e.g., if the
> name of
> the program is, for example, "program" I can issue multiple CLI
> commands
> like:
>
> program <parameters>
>
> If program is not running, it will start and perform appropriate
> actions based
> on the parameters.
>
> If program is running, the existing instance of the program will
> receive those
> parameters and perform appropriate actions.
>
> At the moment (and maybe permanently ;-) I'm drawing a blank as to
> what a
> program like that is called (service, server, ...?), and where to dig
> to
> learn how to implement such a thing (preferably in Ruby).
>
> Hints?
>
> Initially I plan to implement this under Linux--some day it may get
> ported to
> Windows, etc.

I have some code that do kind of what you are describing. But I have to
admit that lately, when I run a daemon/service on my Linux box, I am
incline to manage it with something like runit
(http://smarden.sunsite...). I find it easier than to manage
than the SysV services.

On to some code. The server says:

module TelnetShellServer
def self.daemonize
return true if fork # Parent exits, child continues.
Process.setsid # Become session leader.
exit if fork # Zap session leader. See [1].
Dir.chdir "/" # Release old working directory.
File.umask 0000 # Ensure sensible umask. Adjust as
needed.
STDIN.reopen("/dev/null", "r") # Free file descriptors and
stdout_r, stdout_w = IO.pipe
stderr_r, stderr_w = IO.pipe
Thread.new { loop { $logger.info(stdout_r.gets.chomp) } }
Thread.new { loop { $logger.error(stderr_r.gets.chomp) } }
STDOUT.reopen(stdout_w)
STDERR.reopen(stderr_w)
nil
end

class Broker
[... actual useful service code ...]
end
end

[ ... read options and configuration file ...]

unless foreground
TelnetShellServer.daemonize and exit 0
end

$SAFE = 1 # disable eval() and friends
BROKER = Broker.new(login_files, auto_kill)
$logger.info("Starting DRb")
DRb.start_service(uri.to_s, BROKER)
$logger.info("Broker listening at #{uri}")
trap("TERM") { $logger.debug("TERM"); BROKER.stop }
trap("QUIT") { $logger.debug("QUIT"); BROKER.stop }
trap("INT") { $logger.debug("INT"); BROKER.stop }
trap("HUP") { $logger.debug("HUP"); BROKER.reread_logins }

DRb.thread.join


The client says:

[ ... read options and configuration file ...]
uri = URI.parse(uri)
DRb.start_service
broker = DRbObject.new_with_uri(uri.to_s)
tries = 2
host, cmd = ARGV.shift, ARGV.join(' ')
begin
res = broker.connection_do(host, cmd)
puts(res) if res
rescue DRb::DRbConnError
if auto_vivify && ((tries -= 1) > 0)
system("telnet_shell_serverd") # server not present, start it!
sleep(2)
retry
end
raise
end

HTH,
Guillaume.


>
> Thanks!
> Randy Kramer
>
> Incidentally, if the program crashes, the next invocation of the
> program will
> restart it and recover as much of the previous "context" as possible
> (which
> is, of course, only what has been recorded to disk).
>
>



Randy Kramer

3/20/2006 1:11:00 PM

0

On Saturday 18 March 2006 03:21 pm, Guillaume Marcais wrote:
> I have some code that do kind of what you are describing. But I have to
> admit that lately, when I run a daemon/service on my Linux box, I am
> incline to manage it with something like runit
> (http://smarden.sunsite...). I find it easier than to manage
> than the SysV services.

Thanks to all who replied!

I'm enough of a newbie that it will take me a little while to sort through
these responses--when I'm ready, I'll ask the next question (because I'm sure
there will be one ;-)

Randy Kramer

Aside: Someone else suggested using a fifo (starting with mkfifo)--I'll need
to do some experimenting with that as well. I suspect it won't give all the
functionality I thought I wanted, but it may be a simple approach to get
started.