multithreading - Running multiple copies of Ruby script using thread/load only yields one running copy -
i working on developing server , have developed client script testing. client script works if fire several/many command processors , start in each using "ruby client.rb". make process more efficient, trying write parent script, "threads.rb", can fire many clients want using threads. start last 1 runs when using threads.rb.
client.rb access redis , use mutex there prevent collisions. have no lock on rest of client, nor have done prevent issues within it. i'd able use threads.rb, since client.rb can run in multiple command processors
threads.rb is:
threads = 4 the_threads = [] (1..threads).each |thread| puts "creating thread #{thread}" the_threads << thread.new(thread) |t| puts "running client #{thread};\n" load "./samples/client.rb" end end
client.rb
%w(rubygems bundler faye/websocket eventmachine json redis redis-classy redis-mutex).each { |m| require m } dir["./lib/*.rb", "./lib/**/*.rb"].each { |file| require file } class clientws def self.em_run em.run puts "em running." uri = 'localhost' redis_uri = uri.parse("redis://127.0.0.1:6379") redis ||= redis.new(host: redis_uri.host, port: redis_uri.port, password: redis_uri.password) redisclassy.redis = redis.new(host: redis_uri.host, port: redis_uri.port, password: redis_uri.password) mutex = redismutex.new(:device, block: 0.5, sleep: 0.5) if mutex.lock device = 0 channel = 100 type = 'reader' begin channel += 1 type = type == 'display' ? 'reader' : 'display' device += 1 if type == 'display' lockbox = "lbox_#{device}" unit = "#{lockbox}.#{type}.status" status = redis.get(unit) end until status.nil? || !status channel = type == 'reader' ? "rdr:#{channel}" : "dsp:#{channel}" result = redis.set(unit, 'offline') puts "connecting with:#{unit}; using channel:#{channel};" url = uri == 'localhost' ? "ws://#{uri}:3000/#{channel}" : "ws://#{uri}/#{channel}" puts url @ws = faye::websocket::client.new(url) start = time.now count ||= 0 mutex.unlock else puts 'redismutex failed obtain mutex lock.' exit end timer = eventmachine.add_periodic_timer(5+rand(5)) { count += 1 count.even? ? send({"echo": {"cmd": "ping"}}) : send({"cmd": "ping"}) thread.pass } @ws.on :open |event| clientws.send({"open": lockbox}) end @ws.on :message |event| @ip_address ||= addrinfo.ip(uri.parse(event.target.url).host).ip_address begin parsed = json.parse event.data rescue => e puts ">>>> [error! failed parse json]" puts ">>>> [#{e.message}]" puts ">>>> #{event.data}" end puts ">> #{@ip_address}:#{channel}:#{event.data};" #@ws.close end @ws.on :close |event| timer.cancel stop = time.now - start result = redis.del(unit) puts "#{stop} seconds;" p [:close, event.code, event.reason] ws = nil clientws.em_run end end end def self.send message payload = message.is_a?(hash) ? message : {payload: message} @ws.send(payload.to_json) end end clientws.em_run
i converted use kernel#spawn in lieu of threads.
the_pids = [] (1..pids).each |pid| puts "running client #{pid};\n" dir.chdir("d:/projects/wsserver/") the_pids << spawn(rbconfig.ruby, "./samples/client.rb") end
Comments
Post a Comment