Daemons written in ruby

I've written a simple daemon as a ruby script... it writes all interesting output to a log file and is intended to be a long-running process as opposed to a program which executes only while a user is logged in.

In C I'd have closed stdin, stdout and stderr; dissociate my process from its parent then called fork in order to return 0 indicate successfully starting the daemon.

What is the best way to achieve this in Ruby? I can achieve the end result I want using nohup, but I'm sure there must be a neater way.

A while back there was some discussion about daemons.
As I recall, there was a list of 5 things that one needed
to do to have a 'correct' daemon, but I never saw it in
Ruby code.

Below is what I have used, and it has worked for my needs,
but it may have problems in some environments because I
am missing 4 of the 5 requirements.

I would love to see this standardized and put in the stdlib,
or made into a gem.

  def start_daemon(do_print = false)
    if (child_pid = fork)
      STDERR.puts "PID #{child_pid}" if do_print
      exit
    end
    Process.setsid
  end

def run
    # daemonize the process
    start_daemon
end

···

On 11/7/05, Steve [RubyTalk] <steve_rubytalk@shic.co.uk> wrote:

I've written a simple daemon as a ruby script... it writes all
interesting output to a log file and is intended to be a long-running
process as opposed to a program which executes only while a user is
logged in.

In C I'd have closed stdin, stdout and stderr; dissociate my process
from its parent then called fork in order to return 0 indicate
successfully starting the daemon.

What is the best way to achieve this in Ruby? I can achieve the end
result I want using nohup, but I'm sure there must be a neater way.

--
Jim Freeze

I've written a simple daemon as a ruby script... it writes all interesting

        [...]

In C I'd have closed stdin, stdout and stderr; dissociate my process from its

        [...]

What is the best way to achieve this in Ruby? I can achieve the end result I

        [...]

Thus spake Google: http://redhanded.hobix.com/inspect/daemonize.html

        HTH
        Hugh

···

On Tue, 8 Nov 2005, Steve [RubyTalk] wrote:

runs any command line as a daemon. also sets the name that appears in top/ps.

   #! /home/ahoward/bin/ruby
   fork{
     stdin = open '/dev/null', 'r'
     stdout = open '/dev/null', 'w'
     stderr = open '/dev/null', 'w'
     STDIN.reopen stdin
     STDOUT.reopen stdout
     STDERR.reopen stderr
     $0 = ARGV.first || $0
     fork{
       command = ARGV.join ' '
       system(command) ? exit : abort
     } and exit!
   }

-a

···

On Tue, 8 Nov 2005, Steve [RubyTalk] wrote:

I've written a simple daemon as a ruby script... it writes all interesting output to a log file and is intended to be a long-running process as opposed to a program which executes only while a user is logged in.

In C I'd have closed stdin, stdout and stderr; dissociate my process from its parent then called fork in order to return 0 indicate successfully starting the daemon.

What is the best way to achieve this in Ruby? I can achieve the end result I want using nohup, but I'm sure there must be a neater way.

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
anything that contradicts experience and logic should be abandoned.
-- h.h. the 14th dalai lama

===============================================================================

There's also http://rubyforge.org/projects/daemons

Seems like this belongs into the std lib, doesn't it?

    robert

···

Hugh Sasse <hgs@dmu.ac.uk> wrote:

On Tue, 8 Nov 2005, Steve [RubyTalk] wrote:

I've written a simple daemon as a ruby script... it writes all
interesting

       [...]

In C I'd have closed stdin, stdout and stderr; dissociate my process
from its

       [...]

What is the best way to achieve this in Ruby? I can achieve the end
result I

       [...]

Thus spake Google: http://redhanded.hobix.com/inspect/daemonize.html

       HTH
       Hugh

Hi - I'm wanting to use yajb to script a fairly complex interface and I'm wondering if it's possible.

The interface is of the form:

$ cat iface.java

package org.wbh.testing;

import java.util.Vector;

public interface iface {
   public void v();
   public int i();
   public String s();
   public String[] a();
   public Vector V();
// public void p(int i);
}

$ cat aimpl.java

package org.wbh.testing;

import java.util.Vector;

public abstract class aimpl implements iface {
   public aimpl() {
     System.out.println("---> java constructor");
   }
   protected void finalize() {
     System.out.println("---> java finalizor");
   }
   public void jtest() {
     System.out.println("---> jtest() called");
     this.v();
     System.out.println("---> i() gave " + this.i());
     System.out.println("---> s() gave " + this.s());
     for(int i=0;i<this.a().length;i++) {
       System.out.println("---> a() gave " + i + " " + this.a()[i]);
     }
     System.out.println("---> V().firstElement()= "+this.V().firstElement());
// this.p(31);
     System.out.println("---> jtest() finished");
   }
}

$ cat rtest.rb

require 'yajb/jbridge'

include JavaBridge

#JBRIDGE_OPTIONS={:jvm_log_level =>"debug",:bridge_log=>true}

jimport "java.util.Vector"
jimport "org.wbh.testing.*"

tclass=jextend(:aimpl)
class << tclass
   def rtest
       puts "---> rtest called"
   end
   def v
     puts "---> void method"
   end
   def i
     puts "---> int() method"
     return 42
   end
   def s
     puts "---> String() method"
     return "String??? Rope!!!"
   end
   def a
     puts "---> String[]() method"
     return [:t_string,"A001","A002"]
   end
   def V
     puts "---> V() method"
     vec=jnew(:Vector)
     vec.addElement(7)
     return vec
   end
# def p(arg)
# puts "---> Param given: " + arg
# end
end

tclass.jtest
tclass.rtest
puts "---> That's all, folks!!!"

OK - How can I pass a value *from* java to the ruby implementation of the abstract class??? If the commented out code is activated it gives:
   jbridge.RemoteRuntimeException: class=TypeError message=can't convert
   Fixnum into String

Also, this code seems to suffer from a race. *Sometimes* rtest is called before jtest has finished! Possibly related, one run can finish fine, but the next run gives:

Full thread dump Java HotSpot(TM) Client VM (1.4.2_09-b05 mixed mode):
"Thread-16" prio=1 tid=0x081c4520 nid=0x7cb8 waiting on condition [4d063000..4d0638b8]
         at java.lang.Thread.sleep(Native Method)
         at jbridge.BridgeServer$1.run(BridgeServer.java:248)
         at java.lang.Thread.run(Unknown Source)

How can I syncronize properly (I'm guessing this is an issue of the ruby end of the bridge quitting before the java's done, but I'd prefer not to have to do a wrapper on the java end of things.)

Any pointers? Thanks!
Bill

BTW, really like yajb for the integration, the way there's only jars and ruby, no JNI to mess around with!

It is in 1.9.

···

On Tue, Nov 08, 2005 at 03:07:11AM +0900, Robert Klemme wrote:

Hugh Sasse <hgs@dmu.ac.uk> wrote:
>On Tue, 8 Nov 2005, Steve [RubyTalk] wrote:
>
>>I've written a simple daemon as a ruby script... it writes all
>>interesting
> [...]
>>In C I'd have closed stdin, stdout and stderr; dissociate my process
>>from its
> [...]
>>What is the best way to achieve this in Ruby? I can achieve the end
>>result I
> [...]
>
>Thus spake Google: http://redhanded.hobix.com/inspect/daemonize.html
>
> HTH
> Hugh

There's also http://rubyforge.org/projects/daemons

Seems like this belongs into the std lib, doesn't it?

--
Mauricio Fernandez

Hi,

W.B.Hill wrote:

OK - How can I pass a value *from* java to the ruby implementation of the abstract class??? If the commented out code is activated it gives:
  jbridge.RemoteRuntimeException: class=TypeError message=can't convert
  Fixnum into String

This error is simply thrown by ruby, not yajb.
I could run your code, appending ".to_s", as follows:

> puts("---> Param given: " + arg.to_s)

Also, this code seems to suffer from a race. *Sometimes* rtest is called before jtest has finished! Possibly related, one run can finish fine, but the next run gives:

Full thread dump Java HotSpot(TM) Client VM (1.4.2_09-b05 mixed mode):
"Thread-16" prio=1 tid=0x081c4520 nid=0x7cb8 waiting on condition [4d063000..4d0638b8]
        at java.lang.Thread.sleep(Native Method)
        at jbridge.BridgeServer$1.run(BridgeServer.java:248)
        at java.lang.Thread.run(Unknown Source)

How can I syncronize properly (I'm guessing this is an issue of the ruby end of the bridge quitting before the java's done, but I'd prefer not to have to do a wrapper on the java end of things.)

Your guess is correct. When ruby finishes, the ruby side of yajb sends a shutdown message to the java side. Then the java side calls System.exit after the 0.5 second sleep due to waiting for the completion of shutdown message. I think the crush dump was caused by TERM signal during sleeping. I will reconsider the finish scheduling and improve in the next release.

BTW, really like yajb for the integration, the way there's only jars and ruby, no JNI to mess around with!

Yes. I think that yajb is useful for the application deployment under the environment that has no compiler, such as Windows. OTOH, because the performance is also important, I 'm considering writing the JNI driver.

Thanks.

···

--
SAKURAI Masashi (family given)
m.sakurai@dream.com

If you want to start a new email, do so. Do not hijack someone else's thread. It messes with any number of threaded email readers.

···

On Nov 7, 2005, at 11:44 AM, W.B.Hill wrote:

Hi - I'm wanting to use yajb to script a fairly complex interface and I'm wondering if it's possible.