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