Daemons written in ruby...

  • Thread starter Steve [RubyTalk]
  • Start date
S

Steve [RubyTalk]

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.
 
J

Jim Freeze

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 =3D false)
if (child_pid =3D fork)
STDERR.puts "PID #{child_pid}" if do_print
exit
end
Process.setsid
end

def run
# daemonize the process
start_daemon
end
 
R

Robert Klemme

M

Mauricio Fernández

Hugh Sasse said:
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?

It is in 1.9.
 
A

Ara.T.Howard

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.

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
--
===============================================================================
| 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
===============================================================================
 
W

W.B.Hill

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());
}
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!
 
S

SAKURAI Masashi

Hi,

W.B.Hill said:
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.
 
R

Ryan Davis

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

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,781
Messages
2,569,619
Members
45,310
Latest member
FaustoMont

Latest Threads

Top