Skip to content

Instantly share code, notes, and snippets.

@seki
Created May 12, 2024 14:46
Show Gist options
  • Save seki/4c45c83c3995266bbc39491ea96fbc1d to your computer and use it in GitHub Desktop.
Save seki/4c45c83c3995266bbc39491ea96fbc1d to your computer and use it in GitHub Desktop.
Rdv for CSP study
require 'rinda/tuplespace'
class Rdv
def initialize(ts=nil)
@ts = ts || Rinda::TupleSpace.new
end
def select?(*chan)
template = Template.new(*chan)
t, k = @ts.take([template, nil])
c = template.chan(t)
@ts.write(['chan', k, c])
value = @ts.take(['value', k, c, nil]).last
return c, value
end
def select!(*chan)
template = Template.new(*chan)
key = Object.new
@ts.write([template, key])
_, _, c = @ts.take(['chan', key, nil])
value = yield(c)
@ts.write(['value', key, c, value])
key
end
end
class Template
def initialize(*chan)
@ary = chan
end
def to_a
@ary
end
def chan(other)
@ary.intersection(other.to_a).sample
end
def ===(other)
chan(other)
end
end
if __FILE__ == $0
RDV = Rdv.new
5.times do |n|
Thread.new(n) do
sleep(rand n)
pp RDV.select?('a', 'b', 'c')
end
end
5.times do |n|
Thread.new(n) do
sleep(rand n)
pp RDV.select?('b')
end
end
10.times do |n|
Thread.new(n) do
pp RDV.select!('a', 'b', 'c') {|c| [n, c]}
end
end
sleep 10
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment