Created
July 1, 2015 18:56
-
-
Save glurp/fd64b20b2f68c7e97121 to your computer and use it in GitHub Desktop.
A ruby scipt which auto-config himself as service, and as service , run a process
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##################################################################### | |
# runneur.rb : service which run (continuously) a process | |
# 'do only one simple thing, but do it well' | |
##################################################################### | |
# Usage: | |
# .... duplicate this file : it will be the core-service.... | |
# .... modify constantes in beginning of this script.... | |
# .... modify stop_sub_process() at end of this script for clean stop of sub-application.. | |
# | |
# > ruby runneur.rb install foo ; foo==name of service, | |
# > ruby runneur.rb uninstall foo | |
# > type d:\deamon.log" ; runneur traces | |
# > type d:\d.log ; service traces | |
# | |
##################################################################### | |
class String; def to_dos() self.tr('/','\\') end end | |
class String; def from_dos() self.tr('\\','/') end end | |
rubyexe=%x{where ruby}.to_dos | |
# example with spawn of a ruby process... | |
SERVICE_SCRIPT="D:/usr/Ruby/local/text.rb" | |
SERVICE_DIR="D:/usr/Ruby/local".to_dos | |
SERVICE_LOG="d:/d.log".to_dos # log of stdout/stderr of sub-process | |
RUNNEUR_LOG="d:/deamon.log" # log of runneur | |
LCMD=[rubyexe,SERVICE_SCRIPT] # service will do system('ruby text.rb') | |
SLEEP_INTER_RUN=4 # at each dead of sub-process, wait n seconds before rerun | |
################### Installation / Desintallation ################### | |
if ARGV[0] | |
require 'win32/service' | |
include Win32 | |
name= ""+(ARGV[1] || $0.split('.')[0]) | |
if ARGV[0]=="install" | |
path = "#{File.dirname(File.expand_path($0))}/#{$0}".tr('/', '\\') | |
cmd = rubyexe + " " + path | |
print "Service #{name} installed with\n cmd=#{cmd} ? " ; rep=$stdin.gets.chomp | |
exit! if rep !~ /[yo]/i | |
Service.new( | |
:service_name => name, | |
:display_name => "Ruby-#{name}", | |
:description => "Run of #{File.basename(SERVICE_SCRIPT.from_dos)} at #{SERVICE_DIR}", | |
:binary_path_name => cmd, | |
:start_type => Service::AUTO_START, | |
:service_type => Service::WIN32_OWN_PROCESS | Service::INTERACTIVE_PROCESS | |
) | |
puts "Service #{name} installed" | |
Service.start(name, nil) | |
puts "Service #{name} is started...?" | |
sleep(3) | |
while Service.status(name).current_state != 'running' | |
puts 'One moment...' + Service.status(name).current_state | |
sleep 1 | |
end | |
while Service.status(name).current_state != 'running' | |
puts ' One moment...' + Service.status(name).current_state | |
sleep 1 | |
end | |
puts 'Service ' + name+ ' started' | |
elsif ARGV[0]=="desinstall" || ARGV[0]=="uninstall" | |
if Service.status(name).current_state != 'stopped' | |
Service.stop(name) | |
while Service.status(name).current_state != 'stopped' | |
puts 'One moment...' + Service.status(name).current_state | |
sleep 1 | |
end | |
end | |
Service.delete(name) | |
puts "Service #{name} stopped and uninstalled" | |
else | |
puts "Usage:\n > ruby #{$0} install|desinstall [service-name]" | |
end | |
exit! | |
end | |
################################################################# | |
# service runneur : service code | |
################################################################# | |
require 'win32/daemon' | |
include Win32 | |
Thread.abort_on_exception=true | |
class Daemon | |
def initialize | |
@state='stopped' | |
super | |
log("******************** Runneur #{File.basename(SERVICE_SCRIPT)} Service start ***********************") | |
end | |
def log(*t) | |
txt= block_given?() ? (yield() rescue '?') : t.join(" ") | |
File.open(RUNNEUR_LOG, "a"){ |f| f.puts "%26s | %s" % [Time.now,txt] } rescue nil | |
end | |
def service_pause | |
#put activity in pause | |
@state='pause' | |
stop_sub_process | |
log { "service is paused" } | |
end | |
def service_resume | |
#quit activity from pause | |
@state='run' | |
log { "service is resumes" } | |
end | |
def service_interrogate | |
# respond to quistion status | |
log { "service is interogate" } | |
end | |
def service_shutdown | |
# stop activities before shutdown | |
log { "service is stoped for shutdown" } | |
end | |
def service_init | |
log { "service is starting" } | |
end | |
def service_main | |
@state='run' | |
while running? | |
begin | |
if @state=='run' | |
log { "starting subprocess #{LCMD.join(' ')} in #{SERVICE_DIR}" } | |
@pid=::Process.spawn(*LCMD,{ | |
chdir: SERVICE_DIR, | |
out: SERVICE_LOG, err: :out | |
}) | |
log { "sub-process is running : #{@pid}" } | |
a=::Process.waitpid(@pid) | |
@pid=nil | |
log { "sub-process is dead (#{a.inspect})" } | |
sleep(SLEEP_INTER_RUN) if @state=='run' | |
else | |
sleep 3 | |
log { "service is sleeping" } if @state!='run' | |
end | |
rescue Exception => e | |
log { e.to_s + " " + e.backtrace.join("\n ")} | |
sleep 4 | |
end | |
end | |
end | |
def service_stop | |
@state='stopped' | |
stop_sub_process | |
log { "service is stoped" } | |
exit! | |
end | |
def stop_sub_process | |
::Process.kill("KILL",@pid) if @pid | |
@pid=nil | |
end | |
end | |
Daemon.mainloop |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment