Module: MasterSlaveSynchroniserMixin

Included in:
MasterSlaveSynchroniser
Defined in:
lib/buzzcore/extra/thread_utils.rb

Overview

This module decouples multiple master threads from multiple slave (worker) threads It provides two main methods : + master_attempt_command to be called by multiple clients with a command, returning a result or rasing an exception + slave_do_command to be called by worker threads with a block which processes the command.

see ProviderWorker in pay_server/app/pay_server.rb

Instance Method Summary collapse

Instance Method Details

#loggerObject



327
328
329
# File 'lib/buzzcore/extra/thread_utils.rb', line 327

def logger
  @logger || (@logger = Logger.new(STDERR))
end

#master_attempt_command(aCommand) ⇒ Object



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/buzzcore/extra/thread_utils.rb', line 339

def master_attempt_command(aCommand)
  @semaphore.exclusive do
    command_sent = false
    begin
      before = Time.now
      logger.debug { "master sending aCommand:"+aCommand.inspect }
      @mvCommand.value = aCommand
      command_sent = true
      logger.debug { "master waiting for result" }
      result = @mvResponse.value
      logger.debug { "master received result:"+result.inspect }
    rescue Exception => e
      # exception causes thread critical status to be lost
      logger.debug { "master exception:"+e.inspect }
      if command_sent
        logger.debug { "rejecting" }
        @mvResponse.reject_value    #!!! this doesn't seem to return
      end
      raise e
    ensure
      logger.debug { "master_attempt_command: command_sent=#{command_sent.to_s} elapsed:"+(Time.now-before).to_s }
    end
    result
  end
end

#ms_synchronizer_initialize(aTimeout = nil, aLogger = nil) ⇒ Object



331
332
333
334
335
336
337
# File 'lib/buzzcore/extra/thread_utils.rb', line 331

def ms_synchronizer_initialize(aTimeout=nil,aLogger=nil)
  @logger = aLogger
  @semaphore = CountingSemaphore.new(1)
  timeout = aTimeout && aTimeout/2.0
  @mvCommand = MultiThreadVariable.new(nil,timeout)
  @mvResponse = MultiThreadVariable.new(timeout,nil)
end

#shutdownObject



378
379
380
381
# File 'lib/buzzcore/extra/thread_utils.rb', line 378

def shutdown
  @mvCommand.unblock()
  @mvResponse.unblock()
end

#slave_do_command(&block) ⇒ Object



365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/buzzcore/extra/thread_utils.rb', line 365

def slave_do_command(&block)
  Thread.exclusive do
    logger.debug { "slave waiting for command" }
    command = @mvCommand.value
    logger.debug { "slave received command:"+command.inspect }
    result = yield(command)
    logger.debug { "slave sending result:"+result.inspect }
    @mvResponse.value = result
    logger.debug { "slave finished" }
    result
  end
end