Class: Whiteboard

Inherits:
Object
  • Object
show all
Defined in:
lib/appswarm/whiteboard.rb

Overview

Whiteboard is a pretty simple messaging class, that can be used for different (local) threads. It’s meant for use in storing incoming messages for later processing.

The normal usage looks like this:

w=Whiteboard.new
<spawn thread1 and thread2>
thread1: a=w.get(:myKey)
<thread1 is suspended, because myKey is not there>
thread2: w.put(:myKey,:myValue)
<thread1 is woken up and has a==:myValue>

This is NOT Possible:

Whiteboard.new.put(:myKey,:myValue)

because nobody’s listening for myKey

This is NOT possible either:

w=Whiteboard.new
thread1: w.get(:myValue) 
thread2: w.get(:myValue)

because thread1 is already waiting for this value

in practise this is not a problem, because the values are transaction-ids within node communication should not be duplicated.

Instance Method Summary collapse

Constructor Details

#initializeWhiteboard

Returns a new instance of Whiteboard.



31
32
33
34
35
# File 'lib/appswarm/whiteboard.rb', line 31

def initialize()
  @cvs={}
  @values={}
  @mutex=Mutex.new
end

Instance Method Details

#get(name, timeout = nil) ⇒ Object

waits for name to be put into the local store then returns the value



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/appswarm/whiteboard.rb', line 50

def get(name,timeout=nil)
  value=nil
  measureTime(7) {
    @mutex.synchronize {
      raise "Already value there" if @values[name]
      raise "Already listening" if @cvs[name]
      @cvs[name]=Thread.current
    }
    if timeout.nil?
      Thread.stop
    else
      # FIXME:wait until timeout
      Thread.stop
    end
    
    @mutex.synchronize {
      value=@values[name]
      @values.delete(name)
    }
  }
  value
end

#put(name, value) ⇒ Object

sends value directly to the listening thread waiting for name if there’s no waiting thread an exception is raised



39
40
41
42
43
44
45
46
47
# File 'lib/appswarm/whiteboard.rb', line 39

def put(name,value)
  @mutex.synchronize {
    raise "Conflict in put" if @values[name]
    @values[name]=value
    raise "No one listening" if @cvs[name].nil?
    @cvs[name].wakeup
    @cvs.delete(name)
  }
end