dramatis 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/History.txt +7 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +119 -0
  4. data/README.txt +57 -0
  5. data/Rakefile +4 -0
  6. data/config/hoe.rb +70 -0
  7. data/config/requirements.rb +17 -0
  8. data/examples/README.txt +20 -0
  9. data/examples/auction.rb +90 -0
  10. data/examples/bank/bank.rb +7 -0
  11. data/examples/bank/bank_test.rb +7 -0
  12. data/examples/exception.rb +40 -0
  13. data/examples/fib/conservative.rb +50 -0
  14. data/examples/fib/future.rb +5 -0
  15. data/examples/fib/original.rb +33 -0
  16. data/examples/fib/threads.rb +51 -0
  17. data/examples/im/distributed/chat/client.rb +49 -0
  18. data/examples/im/distributed/chat/screen/fox.rb +92 -0
  19. data/examples/im/distributed/chat/screen.rb +11 -0
  20. data/examples/im/distributed/chat/server.rb +72 -0
  21. data/examples/im/distributed/chat.rb +5 -0
  22. data/examples/im/distributed/client.rb +9 -0
  23. data/examples/im/distributed/run.rb +18 -0
  24. data/examples/im/distributed/server.rb +11 -0
  25. data/examples/im/single/chat/client.rb +50 -0
  26. data/examples/im/single/chat/screen/fox.rb +96 -0
  27. data/examples/im/single/chat/screen/wxs.rb +63 -0
  28. data/examples/im/single/chat/screen.rb +11 -0
  29. data/examples/im/single/chat/server.rb +72 -0
  30. data/examples/im/single/chat.rb +5 -0
  31. data/examples/im/single/fox.rb +18 -0
  32. data/examples/im/single/wxchat.rb +19 -0
  33. data/examples/pingpong/actor.rb +33 -0
  34. data/examples/pingpong/actor_rec.rb +34 -0
  35. data/examples/pingpong/pingpong.txt +315 -0
  36. data/examples/pingpong/scala.rb +41 -0
  37. data/examples/pingpong/serial.rb +26 -0
  38. data/examples/pretty.txt +108 -0
  39. data/examples/telephone/.irbrc +2 -0
  40. data/examples/telephone/3esl.txt +21877 -0
  41. data/examples/telephone/fifth/kid.rb +36 -0
  42. data/examples/telephone/fifth/run.rb +26 -0
  43. data/examples/telephone/first/kid.rb +31 -0
  44. data/examples/telephone/first/run.rb +20 -0
  45. data/examples/telephone/fourth/kid.rb +31 -0
  46. data/examples/telephone/fourth/run.rb +26 -0
  47. data/examples/telephone/mangler.rb +53 -0
  48. data/examples/telephone/second/kid.rb +26 -0
  49. data/examples/telephone/second/run.rb +20 -0
  50. data/examples/telephone/seventh/kid.rb +40 -0
  51. data/examples/telephone/seventh/run.rb +35 -0
  52. data/examples/telephone/seventh/test.rb +28 -0
  53. data/examples/telephone/seventh/test2.rb +10 -0
  54. data/examples/telephone/sixth/kid.rb +39 -0
  55. data/examples/telephone/sixth/run.rb +26 -0
  56. data/examples/telephone/third/kid.rb +31 -0
  57. data/examples/telephone/third/run.rb +21 -0
  58. data/lib/dramatis/actor/interface.rb +118 -0
  59. data/lib/dramatis/actor/name/interface.rb +128 -0
  60. data/lib/dramatis/actor/name.rb +44 -0
  61. data/lib/dramatis/actor.rb +96 -0
  62. data/lib/dramatis/deadlock.rb +123 -0
  63. data/lib/dramatis/error/uncaught.rb +19 -0
  64. data/lib/dramatis/error.rb +125 -0
  65. data/lib/dramatis/future/interface.rb +45 -0
  66. data/lib/dramatis/future.rb +32 -0
  67. data/lib/dramatis/runtime/actor/main.rb +3 -0
  68. data/lib/dramatis/runtime/actor.rb +294 -0
  69. data/lib/dramatis/runtime/gate.rb +244 -0
  70. data/lib/dramatis/runtime/scheduler.rb +374 -0
  71. data/lib/dramatis/runtime/task.rb +390 -0
  72. data/lib/dramatis/runtime/thread_pool.rb +149 -0
  73. data/lib/dramatis/runtime/timer.rb +5 -0
  74. data/lib/dramatis/runtime.rb +129 -0
  75. data/lib/dramatis/shoes/runtime.rb +7 -0
  76. data/lib/dramatis/shoes.rb +14 -0
  77. data/lib/dramatis/version.rb +8 -0
  78. data/lib/dramatis.rb +73 -0
  79. data/log/debug.log +0 -0
  80. data/script/destroy +14 -0
  81. data/script/generate +14 -0
  82. data/script/txt2html +74 -0
  83. data/setup.rb +1585 -0
  84. data/spec/dramatis/actor/become_spec.rb +17 -0
  85. data/spec/dramatis/actor/future_spec.rb +189 -0
  86. data/spec/dramatis/actor/name_spec.rb +141 -0
  87. data/spec/dramatis/actor/task_spec.rb +75 -0
  88. data/spec/dramatis/actor_spec.rb +492 -0
  89. data/spec/dramatis/dramatis_spec.rb +23 -0
  90. data/spec/dramatis/exc_spec.rb +78 -0
  91. data/spec/dramatis/runtime/gate_spec.rb +57 -0
  92. data/spec/dramatis/runtime/thread_pool.rb +30 -0
  93. data/spec/dramatis/shoes_spec.rb +11 -0
  94. data/spec/dramatis/simple_spec.rb +32 -0
  95. data/spec/exp_spec.rb +21 -0
  96. data/spec/simple2_spec.rb +36 -0
  97. data/spec/simple_spec.rb +30 -0
  98. data/spec/spec.opts +0 -0
  99. data/spec/spec_helper.rb +26 -0
  100. data/spec/thread_spec.rb +13 -0
  101. data/tasks/deployment.rake +34 -0
  102. data/tasks/environment.rake +7 -0
  103. data/tasks/rspec.rake +21 -0
  104. data/tasks/website.rake +17 -0
  105. data/test/jruby_lm.rb +13 -0
  106. data/test/test.rb +19 -0
  107. data/test/test10.rb +43 -0
  108. data/test/test11.rb +45 -0
  109. data/test/test12.rb +60 -0
  110. data/test/test13.rb +71 -0
  111. data/test/test2.rb +12 -0
  112. data/test/test3.rb +10 -0
  113. data/test/test4.rb +29 -0
  114. data/test/test5.rb +8 -0
  115. data/test/test6.rb +32 -0
  116. data/test/test7.rb +48 -0
  117. data/test/test8.rb +133 -0
  118. data/test/test9.rb +105 -0
  119. data/test/test_exc.rb +22 -0
  120. metadata +180 -0
@@ -0,0 +1,128 @@
1
+ module Dramatis; end
2
+ module Dramatis::Actor; end
3
+ class Dramatis::Actor::Name; end
4
+
5
+ # An Dramatis::Actor::Name::Interface object provides the ability to
6
+ # modify the semantics of actor name and preform other actor-level operations on an
7
+ # actor. It is typically created via Dramatis.interface.
8
+
9
+ class Dramatis::Actor::Name::Interface
10
+
11
+ # call-seq:
12
+ # continue nil -> a_name
13
+ # continue { |retval| ... } -> a_name
14
+ # continue( :exception => lambda { |exception| ... } ) { |retval| ... } -> a_name
15
+ #
16
+ # In call cases, returns a new name with the specified continuation semantics.
17
+ #
18
+ # When passed a nil argument, returns a new actor name with a nil
19
+ # continuation such that when used in an actor method call, the call
20
+ # will return nil immediately. The return value from such a call is
21
+ # lost. Equivalent to and usually called as Dramatis.release.
22
+ #
23
+ # The second form sets up the block passed to the function as the
24
+ # continuation of the call. When the continuation task is received from the
25
+ # target actor, the block will be executed. From senders point of
26
+ # view, the block is an unnamed method: it will only be
27
+ # scheduled when the actor is not executing any other task.
28
+ #
29
+ # Currently it is not possible to gate off block continuations.
30
+ #
31
+ # The third example is a variant on the second and is used to
32
+ # provide a second block to receive an exception object if the actor
33
+ # method call results in an exception being thrown. Otherwise, the
34
+ # runtime will try to deliver exceptions to a dramatis_exception
35
+ # actor method if defined. Otherwise it will be recored by the
36
+ # runtime.
37
+ #
38
+ #--
39
+ # this stuff is either tricky or evil; i need to lookup
40
+ # variable look ordering for instance_eval
41
+ # i'm assuming lexical scope over object scope
42
+ #++
43
+
44
+ def continue options = {}, &continuation
45
+ raise "contradictory options passed to continue" \
46
+ if ( options == nil and continuation ) or
47
+ ( options and !continuation )
48
+ a, o = @name.instance_eval { [ @actor, @options ] }
49
+ @name = Dramatis::Actor::Name.new a
50
+ @name.instance_eval do
51
+ @options = o.dup
52
+ @options[:continuation] = options == nil ? :none : continuation
53
+ options and @options[:exception] = options[:exception]
54
+ end
55
+ @name
56
+ end
57
+
58
+
59
+ # call-seq:
60
+ # future -> a_name
61
+ #
62
+ # Returns a new actor name that when used in an actor method call will return a Dramatis::Future. Usually
63
+ # called via Dramatis.future rather than directly.
64
+
65
+ def future
66
+ a, o = @name.instance_eval { [ @actor, @options ] }
67
+ @name = Dramatis::Actor::Name.new a
68
+ @name.instance_eval do
69
+ @options = o.dup
70
+ @options[:continuation] = :future
71
+ end
72
+ @name
73
+ end
74
+
75
+ # Binds the actor identified by this name to supplied behavior,
76
+ # which should be a native ruby object. Can only be called on
77
+ # unbound actors, typically created with Dramatis::Actor.new(). The
78
+ # result of the call is the actor name of the actor. The
79
+ # continuation semantics of the call depend on the name like a
80
+ # normal actor method call.
81
+
82
+ def bind behavior
83
+ actor_send :bind, behavior
84
+ end
85
+
86
+ def url #:nodoc: not done
87
+ "http://something"
88
+ end
89
+
90
+ def exception exception #:nodoc: this should be private/protected
91
+ actor_send :exception, exception
92
+ end
93
+
94
+ private
95
+
96
+ def continuation c, options
97
+ a, o = @name.instance_eval { [ @actor, @options ] }
98
+ @name = Dramatis::Actor::Name.new a
99
+ @name.instance_eval do
100
+ @actor.register_continuation c
101
+ @options = o.dup
102
+ @options[:continuation_send] = c.to_s
103
+ @options[:continuation] = :none
104
+ # FIX merge options, rather than cherry-pck
105
+ options[:call_thread] and @options[:call_thread] = options[:call_thread]
106
+ end
107
+ @name
108
+ end
109
+
110
+ def actor_send *args, &block
111
+ @name.instance_eval do
112
+ options = @options
113
+ if block
114
+ options = options.dup
115
+ options[:block] = block
116
+ end
117
+ @actor.actor_send args, options
118
+ end
119
+ end
120
+
121
+ def initialize name #:nodoc:
122
+ raise "hell: " + name.inspect \
123
+ if !name or !name.kind_of? Dramatis::Actor::Name
124
+ @name = name
125
+ end
126
+
127
+ end
128
+
@@ -0,0 +1,44 @@
1
+ module Dramatis; end
2
+ module Dramatis::Actor; end
3
+ class Dramatis::Actor::Name; end
4
+
5
+ require 'dramatis/actor'
6
+
7
+ # Dramatis::Actor::Names are proxy objects for actors. When a method
8
+ # is called on an actor name, the dramatis runtime creates and
9
+ # schedules an actor task to be run on the actors (virtual) thread.
10
+
11
+ # Dramatis::Actor::Name has no user-callable methods (except for the
12
+ # implicit method_missing). Other actor name operations are available
13
+ # through the Dramatis::Actor::Name::Interface object, accessible via
14
+ # Dramatis.interface.
15
+
16
+ class Dramatis::Actor::Name
17
+
18
+ def to_s_off #:nodoc:
19
+ method_missing :to_s
20
+ end
21
+
22
+ def dup #:nodoc:
23
+ raise "hell again"
24
+ end
25
+
26
+ def method_missing *args, &block #:nodoc:
27
+ options = @options
28
+ if block
29
+ options = options.clone
30
+ options[:block] = block
31
+ end
32
+ @actor.object_send args, options
33
+ end
34
+
35
+ private
36
+
37
+ def initialize actor #:nodoc:
38
+ raise "hell" if !actor or !actor.kind_of? Dramatis::Runtime::Actor
39
+ @actor = actor
40
+ @options = { :continuation => :rpc }
41
+ self
42
+ end
43
+
44
+ end
@@ -0,0 +1,96 @@
1
+ module Dramatis; end
2
+ module Dramatis::Actor; end
3
+
4
+ require 'dramatis/runtime/actor'
5
+
6
+ # The Dramatis::Actor module is used to create actor classes and
7
+ # objects. An actor class can be created by mixing Dramatis::Actor, e.g.,
8
+ # class MyClass
9
+ # include Dramatis::Actor
10
+ # ...
11
+ # end
12
+ # or can be used to create so called _naked_ _actors_, e.g.,
13
+ # my_hash_actor = Dramatis::Actor.new Hash.new
14
+ #
15
+ # When mixed in to a class, Dramatis::Actor has two effects:
16
+ # 1. It causes new to return a Dramatis::Actor::Name rather than an object reference
17
+ # 1. It defines an actor method which can be used by the class to access its actor name and
18
+ # otherwise affect its actor semantics
19
+
20
+ module Dramatis::Actor
21
+
22
+ def self.included cls #:nodoc:
23
+ cls.instance_eval do
24
+ include Dramatis
25
+ end
26
+ class << cls
27
+ def new *args
28
+ new_actor = Dramatis::Runtime::Actor.new
29
+ object = allocate
30
+ eigenclass = ( class << object; self; end )
31
+ eigenclass.send :define_method, :actor,
32
+ ( lambda { new_actor.object_interface } )
33
+ new_actor.bind object
34
+ new_actor.instance_eval { @gate.refuse :object }
35
+ new_actor.actor_send [ :object_initialize, *args ],
36
+ :continuation => :rpc
37
+ new_actor.name
38
+ end
39
+ end
40
+ end
41
+
42
+ if false # for docs only ...
43
+
44
+ # call-seq:
45
+ # actor -> an_interface
46
+ #
47
+ # actor provides classes that have mixed in Dramatis::Actor access
48
+ # to a Dramatis::Actor::Interface object by which they can access
49
+ # their actor name and other actor operations.
50
+
51
+ def actor; end
52
+
53
+ end
54
+
55
+ # call-seq:
56
+ # new( *args, &block ) -> an_actor_name
57
+ # new( behavior = nil ) -> an_actor_name
58
+ #
59
+ # The first case is used when a class has mixed in
60
+ # Dramatis::Actor. In this case, the arguments are passed to the
61
+ # initialize of method of the including class like normal.
62
+ #
63
+ # The second case is used when creating so called <em>naked
64
+ # actors</em>, e.g.,
65
+ # my_hash = Dramatis::Actor.new Hash.new
66
+ # If no
67
+ # behavior is provided, the actor can be later bound to a behavior
68
+ # by calling Dramatis::Actor::Name::Interface.bind
69
+ #
70
+ # In all cases, new returns a Dramatis::Actor::Name proxy
71
+ # object.
72
+
73
+ def self.new behavior = nil
74
+ ( Dramatis::Runtime::Actor.new behavior ).name
75
+ end
76
+
77
+ if false
78
+ def self.included cls #:nodoc:
79
+ pp caller(0)
80
+ warn "Dramatis::Actor included by #{cls}"
81
+ end
82
+
83
+ def self.derived cls #:nodoc:
84
+ warn "Dramatis::Actor included by #{cls}"
85
+ end
86
+
87
+ def self.extended cls #:nodoc:
88
+ warn "Dramatis::Actor included by #{cls}"
89
+ end
90
+
91
+ def self.inherited cls #:nodoc:
92
+ warn "Dramatis::Actor included by #{cls}"
93
+ end
94
+ end
95
+
96
+ end
@@ -0,0 +1,123 @@
1
+ module Dramatis; end
2
+
3
+ class Dramatis::Error < StandardError; end
4
+
5
+ # Exception raised when the runtime determines that deadlock has
6
+ # occurred: that is, there are no executing actors and that while
7
+ # there are one or more tasks queued for one or more actors, all are
8
+ # gated off. Note that case where there are no tasks at all signals
9
+ # normal termination.
10
+ #
11
+ # Inherits most methods from Exception.
12
+ #
13
+ # Dramatis::Deadlock (and eventually all Dramatis::Error subclasses)
14
+ # modify the backtrace generated by native language exceptions in
15
+ # order to put them in a more useful context:
16
+ # 1. They chain exceptions across threads using continuation information
17
+ # 1. They remove dramatis runtime internal information
18
+ # See raw_backtrace.
19
+
20
+ class Dramatis::Deadlock < Dramatis::Error; end
21
+
22
+ class Dramatis::Deadlock_ < Dramatis::Error
23
+
24
+ # call-seq:
25
+ # raw_backtrace -> array of strings
26
+ #
27
+ # raw_backtrace returns the unfiltered but still chained backtrace
28
+ # information. It is the concatenation of the backtrace from each
29
+ # actor call site as an exception propagates back the continuation
30
+ # chain.
31
+ def raw_backtrace
32
+ @raw_backtrace
33
+ end
34
+
35
+ def initialize string = nil, opts = {} #:nodoc:
36
+ super string
37
+ @next = opts[:next]
38
+ @raw_backtrace = []
39
+ end
40
+
41
+ # how things stand:
42
+ # r18 and r19 call set_backtrace at the raise
43
+ # jr never calls it; instead the base class synthesizes it
44
+ # at the first backtrace call
45
+ # as far as frames go, it seems lke jr elides sends sometimes
46
+
47
+ def set_backtrace *args #:nodoc:
48
+ # p "sbt!"
49
+ # pp args[0]
50
+ array = @raw_backtrace = args[0]
51
+ if @next
52
+ @raw_backtrace = @next.raw_backtrace + @raw_backtrace
53
+ array = @next.backtrace + array
54
+ end
55
+
56
+ # pp "raw", @raw_backtrace
57
+
58
+ # remove the scheduler
59
+
60
+ filtered = []
61
+ array.each do |v|
62
+ file, line, func = v.split ':'
63
+ file =~ %r{/lib/dramatis/} or ( filtered << v and next )
64
+ func =~ %r{\Wmaybe_deadlock\W} and next
65
+ file =~ %r{/runtime/scheduler} and func =~ %r{\Wrun\W} and break
66
+ filtered << v
67
+ end
68
+
69
+ # remove queueing delivery
70
+
71
+ array = filtered
72
+ filtered = []
73
+ skipping = false
74
+ array.each do |v|
75
+
76
+ # p v
77
+
78
+ file, line, func = v.split ':'
79
+
80
+ if file !~ %r{/lib/dramatis/}
81
+ # p "not skipping x"
82
+ skipping = false
83
+ filtered << v
84
+ next
85
+ end
86
+
87
+ if !skipping and
88
+ ( ( file =~ %r{/runtime/task} and func =~ %r{\Wqueued\W} ) or
89
+ ( file =~ %r{/runtime/actor} and func =~ %r{\Wsend\W} ) or # r18, r19
90
+ ( file =~ %r{/runtime/actor} and func =~ %r{\Wdeliver\W} ) ) # jr
91
+ # p "skipping"
92
+ skipping = true
93
+ next
94
+ end
95
+
96
+ if file =~ %r{/dramatis/actor/name} and func =~ %r{\Wmethod_missing\W}
97
+ # p "not skipping"
98
+ skipping = false
99
+ next
100
+ end
101
+
102
+ skipping or filtered << v
103
+
104
+ end
105
+
106
+ # pp "filt", filtered
107
+ # pp args[0]
108
+ super filtered
109
+ # super args[0]
110
+ end
111
+
112
+ def backtrace #:nodoc:
113
+ if @raw_backtrace.empty?
114
+ bt = super
115
+ if bt
116
+ set_backtrace bt
117
+ end
118
+ end
119
+ # p "d"
120
+ super
121
+ end
122
+
123
+ end
@@ -0,0 +1,19 @@
1
+ module Dramatis; end
2
+
3
+ class Dramatis::Error < StandardError; end
4
+
5
+ # Exception raised when the runtime exits with uncaught exceptions.
6
+
7
+ class Dramatis::Error::Uncaught < Dramatis::Error
8
+
9
+ # combines the name of all uncaught exceptions.
10
+
11
+ def to_s
12
+ super + ": " + @exceptions.join( " " )
13
+ end
14
+
15
+ def initialize exceptions #:nodoc:
16
+ @exceptions = exceptions
17
+ end
18
+
19
+ end
@@ -0,0 +1,125 @@
1
+ module Dramatis; end
2
+
3
+ # The base class of all non-internal dramatis exceptions.
4
+
5
+ class Dramatis::Error < StandardError; end
6
+
7
+ # Raised when an attempt is made to create an interface object on an
8
+ # object that does not define an interface class.
9
+
10
+ class Dramatis::Error::Interface < StandardError; end
11
+
12
+ # Raised when an attempt is made to bind an already-bound actor.
13
+
14
+ class Dramatis::Error::Bind < Dramatis::Error; end
15
+
16
+ require 'dramatis/error/uncaught'
17
+
18
+ class Dramatis::Error < StandardError
19
+
20
+ def self._traceback exception, _next = nil
21
+ tb = exception.instance_variable_get :@_dramatis_traceback
22
+ if !tb
23
+ tb = exception.instance_variable_set( :@_dramatis_traceback,
24
+ Traceback.new( _next ) )
25
+ end
26
+ tb
27
+ end
28
+
29
+ end
30
+
31
+ class Dramatis::Error::Traceback_
32
+
33
+ def initialize _next
34
+ end
35
+
36
+ end
37
+
38
+ class Exception
39
+
40
+ alias _dramatis_set_backtrace set_backtrace
41
+ alias _dramatis_backtrace backtrace
42
+
43
+ def set_backtrace arg
44
+ # p "set back #{self}"
45
+ _dramatis_set_backtrace arg
46
+ end
47
+
48
+ def backtrace
49
+ # p "back #{self}"
50
+ if instance_variable_defined? :@_dramatis_raw_backtrace
51
+ filter @_dramatis_raw_backtrace
52
+ else
53
+ _dramatis_backtrace
54
+ end
55
+ end
56
+
57
+ def _dramatis_reraise
58
+ # return
59
+ # p "reraise"
60
+ if @_dramatis_raw_backtrace
61
+ @_dramatis_raw_backtrace = backtrace + filter( caller )
62
+ else
63
+ @_dramatis_raw_backtrace = filter( backtrace ) + filter( caller )
64
+ end
65
+ end
66
+
67
+ def filter array
68
+
69
+ # pp "_", array
70
+
71
+ filtered = []
72
+ array.each do |v|
73
+ file, line, func = v.split ':'
74
+ file =~ %r{/lib/dramatis/} or ( filtered << v and next )
75
+ func =~ %r{\Wmaybe_deadlock\W} and next
76
+ file =~ %r{/runtime/scheduler} and func =~ %r{\Wrun\W} and break
77
+ filtered << v
78
+ end
79
+
80
+ # pp "0", filtered
81
+
82
+ # remove queueing delivery
83
+
84
+ array = filtered
85
+ filtered = []
86
+ skipping = false
87
+ array.each do |v|
88
+
89
+ # p v
90
+
91
+ file, line, func = v.split ':'
92
+
93
+ if file !~ %r{/lib/dramatis/}
94
+ # p "not skipping x"
95
+ skipping = false
96
+ filtered << v
97
+ next
98
+ end
99
+
100
+ if !skipping and
101
+ ( ( file =~ %r{/runtime/task} and func =~ %r{\Wqueued\W} ) or
102
+ ( file =~ %r{/runtime/actor} and func =~ %r{\Wsend\W} ) or # r18, r19
103
+ ( file =~ %r{/runtime/actor} and func =~ %r{\Wdeliver\W} ) ) # jr
104
+ # p "skipping"
105
+ skipping = true
106
+ next
107
+ end
108
+
109
+ if file =~ %r{/dramatis/actor/name} and func =~ %r{\Wmethod_missing\W}
110
+ # p "not skipping"
111
+ skipping = false
112
+ next
113
+ end
114
+
115
+ skipping or filtered << v
116
+
117
+ end
118
+
119
+ # pp "filt", filtered
120
+ # pp args[0]
121
+ filtered
122
+ # super args[0]
123
+ end
124
+
125
+ end
@@ -0,0 +1,45 @@
1
+ module Dramatis; end
2
+ class Dramatis::Future; end
3
+
4
+ # A Dramatis::Future::Interface object provides the ability to
5
+ # observe and access the semantics of a future. It is typically
6
+ # created via Dramatis.interface.
7
+
8
+ class Dramatis::Future::Interface
9
+
10
+ # Returns the native value of the future. If the value of the future
11
+ # is not yet available, the method blocks (with rpc gating
12
+ # semantics) until it is.
13
+ #
14
+ # In many cases, this method is not necessary since the
15
+ # method_missing method on the future will catch most attempts to
16
+ # accesses the value. This method may be necessary in corner cases,
17
+ # for example when usingconditionals, conversions, and
18
+ # metaprogramming.
19
+
20
+ def value
21
+ @future.instance_eval do
22
+ @continuation.value
23
+ end
24
+ end
25
+
26
+ # Returns true if the future may be evaluated without
27
+ # blocking. Returns false if the value is not yet available.
28
+ #
29
+ # Once a future is ready it cannot become unready, so once ready? returns
30
+ # true, it will always be true and value access will never block.
31
+
32
+ def ready?
33
+ @future.instance_eval do
34
+ @continuation.ready?
35
+ end
36
+ end
37
+
38
+ def initialize *args, &block #:nodoc:
39
+ @future = args.shift
40
+ @args = args
41
+ @block = block
42
+ end
43
+
44
+ end
45
+
@@ -0,0 +1,32 @@
1
+ module Dramatis; end
2
+
3
+ # Dramatis::Futures are proxy objects for the values returned from
4
+ # actor method calls made with future continuations. When a method is
5
+ # called on a future, the runtime checks to see if the future has been
6
+ # evaluated and returned from the actor that executed the task. If it
7
+ # has, the method is executed on the returned value as if the proxy
8
+ # object was not there.
9
+ #
10
+ # If the task with the future continuation has not yet completed or
11
+ # the continuation task has not yet been run, the method called on
12
+ # the proxy is suspended until the reply is received. Thus, methods on
13
+ # futures sometimes but not always block. If they block, they have
14
+ # normal continuation gating semantics.
15
+ #
16
+ # Dramatis::Future has no user-callable methods (except for the
17
+ # implicit method_missing). Other future operations are available
18
+ # through the Dramatis::Future::Interface object, accessible via
19
+ # Dramatis.interface.
20
+
21
+ class Dramatis::Future
22
+
23
+ def method_missing *args #:nodoc:
24
+ @continuation.value.send( *args )
25
+ end
26
+
27
+ def initialize continuation #:nodoc:
28
+ @continuation = continuation
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1,3 @@
1
+ module Dramatis; end
2
+ class Dramatis::Runtime; end
3
+