rx_ruby 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +22 -0
  3. data/.gitignore +173 -0
  4. data/.travis.yml +10 -0
  5. data/Gemfile +4 -0
  6. data/Rakefile +11 -0
  7. data/examples/aggregate.rb +39 -0
  8. data/examples/amb.rb +25 -0
  9. data/examples/ambproto.rb +24 -0
  10. data/examples/and.rb +26 -0
  11. data/examples/as_observable.rb +25 -0
  12. data/examples/average.rb +43 -0
  13. data/examples/buffer_with_count.rb +44 -0
  14. data/examples/buffer_with_time.rb +51 -0
  15. data/examples/case.rb +29 -0
  16. data/examples/catch.rb +20 -0
  17. data/examples/catchproto.rb +39 -0
  18. data/examples/combine_latest.rb +35 -0
  19. data/examples/combine_latestproto.rb +33 -0
  20. data/examples/concat.rb +22 -0
  21. data/examples/concat_all.rb +27 -0
  22. data/examples/concat_map.rb +61 -0
  23. data/examples/concat_map_observer.rb +29 -0
  24. data/examples/concatproto.rb +25 -0
  25. data/examples/connect.rb +41 -0
  26. data/examples/contains.rb +37 -0
  27. data/examples/count.rb +36 -0
  28. data/examples/create.rb +55 -0
  29. data/examples/debounce.rb +35 -0
  30. data/examples/default_if_empty.rb +35 -0
  31. data/examples/defer.rb +20 -0
  32. data/examples/delay.rb +49 -0
  33. data/examples/delay_with_selector.rb +63 -0
  34. data/examples/dematerialize.rb +22 -0
  35. data/examples/disposable.rb +12 -0
  36. data/examples/distinct.rb +43 -0
  37. data/examples/distinct_until_changed.rb +43 -0
  38. data/examples/do.rb +59 -0
  39. data/examples/empty.rb +16 -0
  40. data/examples/for.rb +26 -0
  41. data/examples/fork_join.rb +23 -0
  42. data/examples/from.rb +106 -0
  43. data/examples/from_array.rb +21 -0
  44. data/examples/from_callback.rb +21 -0
  45. data/examples/generate.rb +24 -0
  46. data/examples/group_join.rb +39 -0
  47. data/examples/if.rb +46 -0
  48. data/examples/intervals.rb +26 -0
  49. data/examples/merge.rb +36 -0
  50. data/examples/merge_all.rb +27 -0
  51. data/examples/multicast.rb +32 -0
  52. data/examples/never.rb +15 -0
  53. data/examples/of.rb +19 -0
  54. data/examples/on_error_resume_next.rb +21 -0
  55. data/examples/pairs.rb +26 -0
  56. data/examples/publish.rb +79 -0
  57. data/examples/range.rb +19 -0
  58. data/examples/reduce.rb +18 -0
  59. data/examples/repeat.rb +19 -0
  60. data/examples/return.rb +17 -0
  61. data/examples/scan.rb +41 -0
  62. data/examples/start.rb +29 -0
  63. data/examples/throw.rb +17 -0
  64. data/examples/time_intervals.rb +28 -0
  65. data/examples/timer.rb +26 -0
  66. data/examples/timestamp.rb +28 -0
  67. data/examples/to_a.rb +23 -0
  68. data/examples/to_async.rb +26 -0
  69. data/examples/using.rb +52 -0
  70. data/examples/when.rb +26 -0
  71. data/examples/while.rb +25 -0
  72. data/examples/window_with_time.rb +78 -0
  73. data/examples/zip.rb +27 -0
  74. data/examples/zip_array.rb +25 -0
  75. data/lib/core_ext/enumerable.rb +22 -0
  76. data/lib/rx_ruby.rb +27 -0
  77. data/lib/rx_ruby/concurrency/async_lock.rb +57 -0
  78. data/lib/rx_ruby/concurrency/current_thread_scheduler.rb +75 -0
  79. data/lib/rx_ruby/concurrency/default_scheduler.rb +51 -0
  80. data/lib/rx_ruby/concurrency/historical_scheduler.rb +16 -0
  81. data/lib/rx_ruby/concurrency/immediate_scheduler.rb +68 -0
  82. data/lib/rx_ruby/concurrency/local_scheduler.rb +39 -0
  83. data/lib/rx_ruby/concurrency/periodic_scheduler.rb +74 -0
  84. data/lib/rx_ruby/concurrency/scheduled_item.rb +42 -0
  85. data/lib/rx_ruby/concurrency/scheduler.rb +150 -0
  86. data/lib/rx_ruby/concurrency/virtual_time_scheduler.rb +170 -0
  87. data/lib/rx_ruby/core/async_lock_observer.rb +46 -0
  88. data/lib/rx_ruby/core/auto_detach_observer.rb +59 -0
  89. data/lib/rx_ruby/core/checked_observer.rb +66 -0
  90. data/lib/rx_ruby/core/notification.rb +161 -0
  91. data/lib/rx_ruby/core/observable.rb +104 -0
  92. data/lib/rx_ruby/core/observe_on_observer.rb +50 -0
  93. data/lib/rx_ruby/core/observer.rb +119 -0
  94. data/lib/rx_ruby/core/scheduled_observer.rb +83 -0
  95. data/lib/rx_ruby/core/synchronized_observer.rb +47 -0
  96. data/lib/rx_ruby/core/time_interval.rb +17 -0
  97. data/lib/rx_ruby/internal/priority_queue.rb +122 -0
  98. data/lib/rx_ruby/internal/util.rb +9 -0
  99. data/lib/rx_ruby/joins/active_plan.rb +45 -0
  100. data/lib/rx_ruby/joins/join_observer.rb +51 -0
  101. data/lib/rx_ruby/joins/pattern.rb +14 -0
  102. data/lib/rx_ruby/joins/plan.rb +44 -0
  103. data/lib/rx_ruby/linq/connectable_observable.rb +34 -0
  104. data/lib/rx_ruby/linq/observable/_observable_timer_date_and_period.rb +22 -0
  105. data/lib/rx_ruby/linq/observable/_observable_timer_time_span.rb +14 -0
  106. data/lib/rx_ruby/linq/observable/_observable_timer_time_span_and_period.rb +20 -0
  107. data/lib/rx_ruby/linq/observable/aggregate.rb +7 -0
  108. data/lib/rx_ruby/linq/observable/and.rb +7 -0
  109. data/lib/rx_ruby/linq/observable/case.rb +15 -0
  110. data/lib/rx_ruby/linq/observable/concat_all.rb +7 -0
  111. data/lib/rx_ruby/linq/observable/concat_map.rb +35 -0
  112. data/lib/rx_ruby/linq/observable/concat_map_observer.rb +43 -0
  113. data/lib/rx_ruby/linq/observable/contains.rb +28 -0
  114. data/lib/rx_ruby/linq/observable/debounce.rb +41 -0
  115. data/lib/rx_ruby/linq/observable/delay.rb +81 -0
  116. data/lib/rx_ruby/linq/observable/delay_with_selector.rb +64 -0
  117. data/lib/rx_ruby/linq/observable/do.rb +42 -0
  118. data/lib/rx_ruby/linq/observable/for.rb +13 -0
  119. data/lib/rx_ruby/linq/observable/fork_join.rb +55 -0
  120. data/lib/rx_ruby/linq/observable/from.rb +34 -0
  121. data/lib/rx_ruby/linq/observable/group_join.rb +108 -0
  122. data/lib/rx_ruby/linq/observable/if.rb +17 -0
  123. data/lib/rx_ruby/linq/observable/interval.rb +5 -0
  124. data/lib/rx_ruby/linq/observable/multicast.rb +14 -0
  125. data/lib/rx_ruby/linq/observable/of.rb +11 -0
  126. data/lib/rx_ruby/linq/observable/pairs.rb +7 -0
  127. data/lib/rx_ruby/linq/observable/pluck.rb +7 -0
  128. data/lib/rx_ruby/linq/observable/publish.rb +11 -0
  129. data/lib/rx_ruby/linq/observable/start.rb +7 -0
  130. data/lib/rx_ruby/linq/observable/time_interval.rb +15 -0
  131. data/lib/rx_ruby/linq/observable/timer.rb +26 -0
  132. data/lib/rx_ruby/linq/observable/timestamp.rb +9 -0
  133. data/lib/rx_ruby/linq/observable/to_async.rb +40 -0
  134. data/lib/rx_ruby/linq/observable/when.rb +36 -0
  135. data/lib/rx_ruby/linq/observable/while.rb +41 -0
  136. data/lib/rx_ruby/operators/aggregates.rb +611 -0
  137. data/lib/rx_ruby/operators/creation.rb +220 -0
  138. data/lib/rx_ruby/operators/multiple.rb +735 -0
  139. data/lib/rx_ruby/operators/single.rb +399 -0
  140. data/lib/rx_ruby/operators/standard_query_operators.rb +279 -0
  141. data/lib/rx_ruby/operators/synchronization.rb +47 -0
  142. data/lib/rx_ruby/operators/time.rb +120 -0
  143. data/lib/rx_ruby/subjects/async_subject.rb +161 -0
  144. data/lib/rx_ruby/subjects/behavior_subject.rb +149 -0
  145. data/lib/rx_ruby/subjects/replay_subject.rb +39 -0
  146. data/lib/rx_ruby/subjects/subject.rb +131 -0
  147. data/lib/rx_ruby/subjects/subject_extensions.rb +45 -0
  148. data/lib/rx_ruby/subscriptions/composite_subscription.rb +91 -0
  149. data/lib/rx_ruby/subscriptions/ref_count_subscription.rb +88 -0
  150. data/lib/rx_ruby/subscriptions/scheduled_subscription.rb +32 -0
  151. data/lib/rx_ruby/subscriptions/serial_subscription.rb +60 -0
  152. data/lib/rx_ruby/subscriptions/single_assignment_subscription.rb +64 -0
  153. data/lib/rx_ruby/subscriptions/subscription.rb +56 -0
  154. data/lib/rx_ruby/testing/cold_observable.rb +45 -0
  155. data/lib/rx_ruby/testing/hot_observable.rb +47 -0
  156. data/lib/rx_ruby/testing/mock_observer.rb +33 -0
  157. data/lib/rx_ruby/testing/reactive_test.rb +94 -0
  158. data/lib/rx_ruby/testing/recorded.rb +17 -0
  159. data/lib/rx_ruby/testing/test_scheduler.rb +96 -0
  160. data/lib/rx_ruby/testing/test_subscription.rb +22 -0
  161. data/lib/rx_ruby/version.rb +3 -0
  162. data/license.txt +13 -0
  163. data/readme.md +152 -0
  164. data/rx_ruby.gemspec +22 -0
  165. data/test/rx_ruby/concurrency/helpers/historical_virtual_scheduler_helper.rb +135 -0
  166. data/test/rx_ruby/concurrency/helpers/immediate_local_scheduler_helper.rb +51 -0
  167. data/test/rx_ruby/concurrency/test_async_lock.rb +56 -0
  168. data/test/rx_ruby/concurrency/test_current_thread_scheduler.rb +44 -0
  169. data/test/rx_ruby/concurrency/test_default_scheduler.rb +44 -0
  170. data/test/rx_ruby/concurrency/test_historical_scheduler.rb +18 -0
  171. data/test/rx_ruby/concurrency/test_immediate_scheduler.rb +53 -0
  172. data/test/rx_ruby/concurrency/test_local_scheduler.rb +12 -0
  173. data/test/rx_ruby/concurrency/test_periodic_scheduler.rb +53 -0
  174. data/test/rx_ruby/concurrency/test_scheduled_item.rb +50 -0
  175. data/test/rx_ruby/concurrency/test_scheduler.rb +128 -0
  176. data/test/rx_ruby/concurrency/test_virtual_time_scheduler.rb +14 -0
  177. data/test/rx_ruby/core/test_notification.rb +129 -0
  178. data/test/rx_ruby/core/test_observable_creation.rb +483 -0
  179. data/test/rx_ruby/core/test_observer.rb +634 -0
  180. data/test/rx_ruby/internal/test_priority_queue.rb +71 -0
  181. data/test/rx_ruby/subscriptions/test_composite_subscription.rb +116 -0
  182. data/test/rx_ruby/subscriptions/test_serial_subscription.rb +62 -0
  183. data/test/rx_ruby/subscriptions/test_singleassignment_subscription.rb +61 -0
  184. data/test/rx_ruby/subscriptions/test_subscription.rb +27 -0
  185. data/test/test_helper.rb +11 -0
  186. metadata +291 -0
@@ -0,0 +1,9 @@
1
+ module RxRuby
2
+ module Observable
3
+ def add_ref(r)
4
+ AnonymousObservable.new do |observer|
5
+ CompositeSubscription.new [r.subscription, self.subscribe(observer)]
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,45 @@
1
+ module RxRuby
2
+ class ActivePlan
3
+ def initialize(join_observer_array, on_next, on_completed)
4
+ @join_observer_array = join_observer_array
5
+ @on_next = on_next
6
+ @on_completed = on_completed
7
+ @join_observers = {}
8
+ @join_observer_array.each {|x|
9
+ @join_observers[x] = x
10
+ }
11
+ end
12
+
13
+ def dequeue
14
+ @join_observers.each {|_, v| v.queue.shift }
15
+ end
16
+
17
+ def match
18
+ has_values = true
19
+ @join_observer_array.each {|v|
20
+ if v.queue.length == 0
21
+ has_values = false
22
+ break
23
+ end
24
+ }
25
+ if has_values
26
+ first_values = []
27
+ is_completed = false
28
+ @join_observer_array.each {|v|
29
+ first_values.push v.queue[0]
30
+ is_completed = true if v.queue[0].on_completed?
31
+ }
32
+ if is_completed
33
+ @on_completed.call
34
+ else
35
+ dequeue
36
+ values = []
37
+ first_values.each {|v|
38
+ values.push v.value
39
+ }
40
+ @on_next.call(*values)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,51 @@
1
+ module RxRuby
2
+ class JoinObserver < ObserverBase
3
+
4
+ attr_reader :queue
5
+ def initialize(source, on_error)
6
+ super Observer.configure {|o|
7
+ o.on_next {|notification|
8
+ if !@is_disposed
9
+ if notification.on_error?
10
+ @on_error.call(notification.exception)
11
+ next
12
+ end
13
+ @queue.push notification
14
+ @active_plans.dup.each {|v|
15
+ v.match
16
+ }
17
+ end
18
+ }
19
+ }
20
+ @source = source
21
+ @on_error = on_error
22
+ @queue = []
23
+ @active_plans = []
24
+ @subscription = SingleAssignmentSubscription.new
25
+ @is_disposed = false
26
+ end
27
+
28
+ def add_active_plan(active_plan)
29
+ @active_plans.push active_plan
30
+ end
31
+
32
+ def subscribe
33
+ @subscription.subscription = @source.materialize.subscribe(@config)
34
+ end
35
+
36
+ def remove_active_plan(active_plan)
37
+ if idx = @active_plans.index(active_plan)
38
+ @active_plans.delete_at idx
39
+ end
40
+ self.unsubscribe if @active_plans.length == 0
41
+ end
42
+
43
+ def unsubscribe
44
+ super
45
+ if !@is_disposed
46
+ @is_disposed = true
47
+ @subscription.unsubscribe
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,14 @@
1
+ module RxRuby
2
+ class Pattern
3
+ attr_reader :patterns
4
+ def initialize(patterns)
5
+ @patterns = patterns
6
+ end
7
+ def and(other)
8
+ Pattern.new(@patterns.concat(other))
9
+ end
10
+ def then_do(selector = Proc.new)
11
+ Plan.new(self, selector)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,44 @@
1
+ module RxRuby
2
+ class Plan
3
+ def initialize(expression, selector)
4
+ @expression = expression
5
+ @selector = selector
6
+ end
7
+
8
+ def activate(external_subscriptions, observer, deactivate)
9
+ join_observers = []
10
+ @expression.patterns.each {|pat|
11
+ join_observers.push plan_create_observer(external_subscriptions, pat, observer.method(:on_error))
12
+ }
13
+
14
+ active_plan = ActivePlan.new(join_observers, lambda {|*args|
15
+ begin
16
+ result = @selector.call(*args)
17
+ rescue => e
18
+ observer.on_error e
19
+ end
20
+ observer.on_next result
21
+ },
22
+ lambda {
23
+ join_observers.each {|v|
24
+ v.remove_active_plan(active_plan)
25
+ }
26
+ deactivate.call(active_plan)
27
+ })
28
+ join_observers.each {|v|
29
+ v.add_active_plan(active_plan)
30
+ }
31
+ return active_plan
32
+ end
33
+
34
+ def plan_create_observer(external_subscriptions, observable, on_error)
35
+ entry = external_subscriptions[observable]
36
+ if !entry
37
+ observer = JoinObserver.new(observable, on_error)
38
+ external_subscriptions[observable] = observer
39
+ return observer
40
+ end
41
+ entry
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ module RxRuby
2
+ class ConnectableObservable < AnonymousObservable
3
+ def initialize(source, subject)
4
+ @has_subscription = false
5
+ @subscription = nil
6
+ @source_observable = source.as_observable
7
+ @subject = subject
8
+
9
+ super(&subject.method(:subscribe))
10
+ end
11
+
12
+ def connect
13
+ unless @has_subscription
14
+ @has_subscription = true
15
+ @subscription = CompositeSubscription.new [@source_observable.subscribe(@subject), Subscription.create { @has_subscription = false }]
16
+ end
17
+ @subscription
18
+ end
19
+
20
+ def ref_count
21
+ count = 0
22
+ AnonymousObservable.new do |observer|
23
+ count += 1
24
+ should_connect = true if count == 1
25
+ connectable_subscription = self.connect if should_connect
26
+ Subscription.create {
27
+ @subscription.unsubscribe
28
+ count -= 1
29
+ connectable_subscription.unsubscribe if count == 0
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,22 @@
1
+ module RxRuby
2
+ class << Observable
3
+ private
4
+ def observable_timer_date_and_period(due_time, period, scheduler)
5
+ AnonymousObservable.new do |observer|
6
+ count = 0
7
+ d = due_time
8
+ p = Scheduler.normalize(period)
9
+ scheduler.schedule_recursive_absolute(d, lambda {|this|
10
+ if p > 0
11
+ now = scheduler.now()
12
+ d = d + p
13
+ d <= now && (d = now + p)
14
+ end
15
+ observer.on_next(count)
16
+ count += 1
17
+ this.call(d)
18
+ })
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module RxRuby
2
+ class << Observable
3
+ private
4
+ def observable_timer_time_span(due_time, scheduler)
5
+ AnonymousObservable.new do |observer|
6
+ scheduler.schedule_relative(Scheduler.normalize(due_time),
7
+ lambda {
8
+ observer.on_next(0)
9
+ observer.on_completed
10
+ })
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ module RxRuby
2
+ class << Observable
3
+ private
4
+ def observable_timer_time_span_and_period(due_time, period, scheduler)
5
+ if due_time == period
6
+ AnonymousObservable.new do |observer|
7
+ scheduler.schedule_periodic_with_state(0, period,
8
+ lambda {|count|
9
+ observer.on_next(count)
10
+ count + 1
11
+ })
12
+ end
13
+ else
14
+ Observable.defer {
15
+ observable_timer_date_and_period(scheduler.now() + due_time, period, scheduler)
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ require 'rx_ruby/operators/aggregates.rb'
2
+
3
+ module RxRuby
4
+ module Observable
5
+ alias :aggregate :reduce
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module RxRuby
2
+ module Observable
3
+ def and(right)
4
+ Pattern.new([self, right]);
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module RxRuby
2
+ class << Observable
3
+ def case(selector, sources, defaultSourceOrScheduler = Observable.empty)
4
+ defer {
5
+ if Scheduler === defaultSourceOrScheduler
6
+ defaultSourceOrScheduler = Observable.empty(defaultSourceOrScheduler)
7
+ end
8
+
9
+ result = sources[selector.call]
10
+ result || defaultSourceOrScheduler
11
+ }
12
+ end
13
+ alias :switchCase :case
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module RxRuby
2
+ module Observable
3
+ def concat_all
4
+ merge_concurrent(1)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ module RxRuby
2
+ module Observable
3
+ def concat_map(selector, result_selector = nil)
4
+ if Proc === result_selector
5
+ return concat_map(lambda {|x, i|
6
+ selector_result = selector.call(x, i)
7
+ if selector_result.respond_to?(:each)
8
+ selector_result = Observable.from(selector_result)
9
+ end
10
+ selector_result.map_with_index {|y, i2|
11
+ result_selector.call(x, y, i, i2)
12
+ }
13
+ })
14
+ end
15
+
16
+ if Proc === selector
17
+ _concat_map(selector)
18
+ else
19
+ _concat_map(lambda {|*_| selector })
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def _concat_map(selector)
26
+ map_with_index {|x, i|
27
+ result = selector.call(x, i)
28
+ if result.respond_to?(:each)
29
+ result = Observable.from(result)
30
+ end
31
+ result
32
+ }.concat_all
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,43 @@
1
+ module RxRuby
2
+ module Observable
3
+ def concat_map_observer(on_next, on_error, on_completed)
4
+ AnonymousObservable.new do |observer|
5
+ index = 0
6
+
7
+ subscribe(
8
+ lambda {|x|
9
+ begin
10
+ result = on_next.call(x, index)
11
+ index += 1
12
+ rescue => e
13
+ observer.on_error e
14
+ return
15
+ end
16
+ observer.on_next result
17
+ },
18
+ lambda {|err|
19
+ begin
20
+ result = on_error.call(err)
21
+ rescue => e
22
+ observer.on_error e
23
+ return
24
+ end
25
+
26
+ observer.on_next result
27
+ observer.on_completed
28
+ },
29
+ lambda {
30
+ begin
31
+ result = on_completed.call
32
+ rescue => e
33
+ observer.on_error e
34
+ return
35
+ end
36
+
37
+ observer.on_next result
38
+ observer.on_completed
39
+ })
40
+ end.concat_all
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ module RxRuby
2
+ module Observable
3
+ def contains(search_element, from_index = 0)
4
+ AnonymousObservable.new do |observer|
5
+ i = 0
6
+ n = from_index
7
+ if n < 0
8
+ observer.on_next false
9
+ observer.on_completed
10
+ return Subscription.empty
11
+ end
12
+
13
+ subscribe(
14
+ lambda {|x|
15
+ if i.tap { i += 1 } >= n && x == search_element
16
+ observer.on_next true
17
+ observer.on_completed
18
+ end
19
+ },
20
+ observer.method(:on_error),
21
+ lambda {
22
+ observer.on_next false
23
+ observer.on_completed
24
+ })
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,41 @@
1
+ module RxRuby
2
+ module Observable
3
+ def debounce(due_time, scheduler = DefaultScheduler.instance)
4
+ AnonymousObservable.new do |observer|
5
+ cancelable = SerialSubscription.new
6
+ hasvalue = false
7
+ value = nil
8
+ id = 0
9
+
10
+ subscription = subscribe(
11
+ lambda {|x|
12
+ hasvalue = true
13
+ value = x
14
+ id += 1
15
+ current_id = id
16
+ d = SingleAssignmentSubscription.new
17
+ cancelable.subscription = d
18
+ d.subscription = scheduler.schedule_relative(due_time, lambda {
19
+ observer.on_next value if hasvalue && id == current_id
20
+ hasvalue = false
21
+ })
22
+ },
23
+ lambda {|e|
24
+ cancelable.dispose
25
+ observer.on_error e
26
+ hasvalue = false
27
+ id += 1
28
+ },
29
+ lambda {
30
+ cancelable.dispose
31
+ observer.on_next value if hasvalue
32
+ observer.on_completed
33
+ hasvalue = false
34
+ id += 1
35
+ })
36
+
37
+ CompositeSubscription.new [subscription, cancelable]
38
+ end
39
+ end
40
+ end
41
+ end