From: BENI Date: 2007-01-20T16:45:11+09:00 Subject: problem in win32-service ... or ... what ? I am trying to build an windows service ( WIN XP SP-2) using the Win32-service package for ruby. This service is supposed to pull some stock data from yahoo site every minute and print to screen. For this objective to be accomplished i have the following three files 1> yahootickerpull.rb This has a class Yahooticker and a method called refresh. 2> datasrc_ctl.rb This has code for controlling the service like install,start,stop,delete etc..... Here i utilize the win32/service 3>yahootickerservice.rb Here i require the yahootickerpull and win32/service ... and override the "Daemon" class onto "YDaemon" class . In the "service_init" method i create a Yahooticker object .... and in the service_main method i call the refresh method of this object. This is the blue print. =============================== problem is i get an error: C:\mooney.com\historicalqoute\yahooticker>ruby datasrc_ctl.rb start VERSION: 0.5.2 datasrc_ctl.rb:61:in `start': The service did not respond to the start or control request in a timely fashion. (Win32::ServiceError) from datasrc_ctl.rb:61 ================================== I suspected the win32/service .... but the example code that comes with the package tdaemon.rb and tdaemon_ctl.rb...... works perfectly .... So i suppose i am doing some fundamental mistakes.... 1>1>1>1>1>=======yahootickerpull.rb ============================================ require 'open-uri' require 'ostruct' require 'csv' require 'yaml' require 'mysql' include Enumerable class Yahooticker SOURCE_URL = "http://finance.yahoo.com/d/quotes.csv" #These are the symbols I understand, which are limited OPTIONS = { :symbol=>"s", :name=>"n", :last_trade=>"l1", :last_trade_date=>"d1", :last_trade_time=>"t1", :open=>"o", :high=>"h", :low=>"g", :high_52_week=>"k", :low_52_week=>"j" } def initialize(symbols, options = [:symbol, :name, :last_trade, :last_trade_date, :last_trade_time]) @symbols = symbols @options = options @data = nil end def each data.each do |row| struct = OpenStruct.new(Hash[*(@options.zip(row).flatten)]) yield struct end end def each_hash data.each do |row| hash = Hash[*(@options.zip(row).flatten)] yield hash end end def refresh #p @symbols.to_s symbol_fragment = @symbols.to_s.gsub(/\n/,'+') #p "THE symbol: #{symbol_fragment}" puts "============================" option_fragment = @options.map{|s| OPTIONS[s] }.join "" url = SOURCE_URL + "?s=#{symbol_fragment}&f=#{option_fragment}" #puts "THE URL: #{url}" @data = [] CSV.parse open(url,:proxy=>"http://127.0.0.1:8080").read do |row| # this is where we will modify and put it in mysql database p row end end #def data #refresh unless @data #@data #end end 1>1>1>1>1>1>================================== 2>2>2>2>2>2>======datasrc_ctl.rb================== #require 'yahootickerpull' require 'win32/service' include Win32 puts 'VERSION: ' + Service::VERSION # I start the service name with an 'A' so that it appears at the top SERVICE_NAME = 'AbbaSvc' SERVICE_DISPLAYNAME = 'Abba' cmd = 'c:\ruby\bin\ruby ' cmd += '"' + File.dirname(File.expand_path($0)).tr('/', '\\') + '\yahootickerservice.rb' + '"' raise ArgumentError, 'No argument provided' unless ARGV[0] case ARGV[0].downcase when 'install' svc = Service.new svc.create_service{ |s| s.service_name = SERVICE_NAME s.display_name = SERVICE_DISPLAYNAME s.binary_path_name = cmd } svc.close puts 'Service ' + SERVICE_NAME + ' installed' when 'start' if Service.status(SERVICE_NAME).current_state != 'running' #@portfolio=[] #@portfolio=IO.readlines('c:\mooney.com\teststock.txt') #options=[:symbol, :name, :open, :high , :low] #@tick = Yahooticker.new(@portfolio,options) #@tick.refresh Service.start(SERVICE_NAME) while Service.status(SERVICE_NAME).current_state != 'running' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end puts 'Service ' + SERVICE_NAME + ' started' else puts 'Already running' end when 'stop' if Service.status(SERVICE_NAME).current_state != 'stopped' Service.stop(SERVICE_NAME) while Service.status(SERVICE_NAME).current_state != 'stopped' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end puts 'Service ' + SERVICE_NAME + ' stopped' else puts 'Already stopped' end when 'uninstall', 'delete' if Service.status(SERVICE_NAME).current_state != 'stopped' Service.stop(SERVICE_NAME) end while Service.status(SERVICE_NAME).current_state != 'stopped' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end Service.delete(SERVICE_NAME) puts 'Service ' + SERVICE_NAME + ' deleted' when 'pause' if Service.status(SERVICE_NAME).current_state != 'paused' Service.pause(SERVICE_NAME) while Service.status(SERVICE_NAME).current_state != 'paused' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end puts 'Service ' + SERVICE_NAME + ' paused' else puts 'Already paused' end when 'resume' if Service.status(SERVICE_NAME).current_state != 'running' Service.resume(SERVICE_NAME) while Service.status(SERVICE_NAME).current_state != 'running' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end puts 'Service ' + SERVICE_NAME + ' resumed' else puts 'Already running' end else raise ArgumentError, 'unknown option: ' + ARGV[0] end 2>2>2>2>2>2>========================================================= 3>3>3>3>3>3>===========yahootickerservice.rb==================================== require 'yahootickerpull' require 'win32/service' include Win32 LOG_FILE = "C:\\test.log" begin class YDaemon < Daemon def service_init @portfolio=[] @portfolio=IO.readlines('c:\mooney.com\teststock.txt') options=[:symbol, :name, :open, :high , :low] @tick=Yahooticker.new(@portfolio,options) sleep 2 end def service_main msg = 'service_main entered at: ' + Time.now.to_s File.open(LOG_FILE, "a+"){ |f| f.puts msg } while running? if state == RUNNING @tick.refresh sleep 60 else sleep 0.5 end end File.open(LOG_FILE, "a+"){ |f| f.puts "STATE: #{state}" } msg = 'service_main left at: ' + Time.now.to_s File.open(LOG_FILE, "a+"){ |f| f.puts msg } end def service_stop msg = "Received stop signal at: " + Time.now.to_s File.open(LOG_FILE, "a+"){ |f| f.puts msg } end def service_pause msg = "Received pause signal at: " + Time.now.to_s File.open(LOG_FILE, "a+"){ |f| f.puts msg } end def service_resume msg = "Received resume signal at: " + Time.now.to_s File.open(LOG_FILE, "a+"){ |f| f.puts msg } end end YDaemon.new.mainloop rescue Exception => err File.open(LOG_FILE, "a+"){ |fh| fh.puts 'Daemon failure: ' + err } raise end 3>3>3>3>3>3>============================================= sorry for a long post. Thanks rajib