summaryrefslogtreecommitdiff
path: root/lib/rinda/rinda.rb
blob: 72b0e45cdfbbdb2807f2c4cdcbdafc47f1612a77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
require 'thread'

module Rinda
  class RequestCanceledError < ThreadError; end
  class RequestExpiredError < ThreadError; end

  class Tuple
    def initialize(ary_or_hash)
      if Hash === ary_or_hash
	init_with_hash(ary_or_hash)
      else
	init_with_ary(ary_or_hash)
      end
    end

    def size
      @tuple.size
    end

    def [](k)
      @tuple[k]
    end

    def each # FIXME
      if Hash === @tuple
	@tuple.each { |k, v| yield(k, v) }
      else
	@tuple.each_with_index { |v, k| yield(k, v) }
      end
    end

    def value
      @tuple
    end

    private
    def init_with_ary(ary)
      @tuple_size = ary.size
      @tuple = Array.new(@tuple_size)
      @tuple.size.times do |i|
	@tuple[i] = ary[i]
      end
    end

    def init_with_hash(hash)
      @tuple_size = hash[:size]
      @tuple = Hash.new
      hash.each do |k, v|
	next unless String === k
	@tuple[k] = v
      end
    end
  end

  class Template < Tuple
    def match(tuple)
      return false unless tuple.respond_to?(:size)
      return false unless tuple.respond_to?(:[])
      return false if @tuple_size && (@tuple_size != tuple.size)
      each do |k, v|
	next if v.nil?
	return false unless (v === tuple[k] rescue false)
      end
      return true
    end
    
    def ===(tuple)
      match(tuple)
    end
  end
  
  class DRbObjectTemplate
    def initialize(uri=nil, ref=nil)
      @drb_uri = uri
      @drb_ref = ref
    end
    
    def ===(ro)
      return true if super(ro)
      unless @drb_uri.nil?
	return false unless (@drb_uri === ro.__drburi rescue false)
      end
      unless @drb_ref.nil?
	return false unless (@drb_ref === ro.__drbref rescue false)
      end
      true
    end
  end

  class TupleSpaceProxy
    def initialize(ts)
      @ts = ts
    end
    
    def write(tuple, sec=nil)
      @ts.write(tuple, sec)
    end
    
    def take(tuple, sec=nil, &block)
      port = []
      @ts.move(DRbObject.new(port), tuple, sec, &block)
      port[0]
    end
    
    def read(tuple, sec=nil)
      @ts.read(tuple, sec)
    end
    
    def read_all(tuple)
      @ts.read_all
    end
    
    def notify(ev, tuple, sec=nil)
      @ts.notify(ev, tuple, sec)
    end
  end

  class SimpleRenewer
    include DRbUndumped
    def initialize(sec=180)
      @sec = sec
    end

    def renew
      @sec
    end
  end
end