Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions gems/concurrent-ruby/1.1/_test/test_helpers.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class TaskObserver
include Concurrent::_Observer[untyped]
end
65 changes: 65 additions & 0 deletions gems/concurrent-ruby/1.1/_test/timer_task.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
require 'concurrent-ruby'

# Basic usage
task = Concurrent::TimerTask.new{ puts 'Boom!' }
task.execute
task.execution_interval #=> 60 (default)
task.shutdown #=> true


# Configuring :execution_interval
task = Concurrent::TimerTask.new(execution_interval: 5) do
puts 'Boom!'
end
task.execution_interval #=> 5

# Immediate execution with :run_now
task = Concurrent::TimerTask.new(run_now: true) { puts 'Boom!' }
task.execute

# Configuring :interval_type with either :fixed_delay or :fixed_rate, default is :fixed_delay

task = Concurrent::TimerTask.new(execution_interval: 5, interval_type: :fixed_rate) do
puts 'Boom!'
end
task.interval_type #=> :fixed_rate

# Last #value and Dereferenceable mixin
task = Concurrent::TimerTask.new(
dup_on_deref: true,
execution_interval: 5
){ Time.now }
task.execute
task.value

# Controlling execution from within the block
timer_task = Concurrent::TimerTask.new(execution_interval: 1) do |task|
task.execution_interval.to_i.times { print 'Boom! ' }
task.execution_interval += 1
if task.execution_interval > 5
puts 'Stopping...'
task.shutdown
end
end

timer_task.execute

# Observation

class TaskObserver
def update(time, result, ex)
if result
print "(#{time}) Execution successfully returned #{result}\n"
else
print "(#{time}) Execution failed with error #{ex}\n"
end
end
end

task = Concurrent::TimerTask.new(execution_interval: 1){ 42 }
task.add_observer(TaskObserver.new)
task.add_observer { |time, result, error| pp time, result, error }
task.add_observer { |time, result| pp time, result }
task.add_observer { |time| pp time }
task.execute
task.shutdown
47 changes: 47 additions & 0 deletions gems/concurrent-ruby/1.1/timer_task.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Concurrent
interface _Observer[T]
def update: (Time, T? result, StandardError? exception) -> void
end

interface _Dereferenceable[T]
def value: -> T
def deref: -> T
end

interface _Observable[T]
def add_observer: (_Observer[T]) -> _Observer[T] # Typed: observer with standard `update` method
| () { (?Time, ?T?, ?StandardError?) -> void } -> ^(?Time, ?T?, ?StandardError?) -> void # Typed: block form
| (untyped observer, Symbol func) -> untyped # Untyped: custom method name
def count_observers: -> Integer
def delete_observer: (_Observer[T]) -> _Observer[T]
| (^(?Time, ?T?, ?StandardError?) -> void) -> ^(?Time, ?T?, ?StandardError?) -> void
| (untyped observer) -> untyped
def delete_observers: -> self
def with_observer: (_Observer[T]) -> self
| () { (?Time, ?T?, ?StandardError?) -> void } -> self
| (untyped observer, Symbol func) -> self
end

class TimerTask[T]
include _Observable[T]
include _Dereferenceable[T]

def initialize: (
?execution_interval: Float | Integer,
?run_now: bool,
?executor: executor,
?dup_on_deref: bool,
?freeze_on_deref: bool,
?copy_on_deref: (^(T) -> T)?,
?interval_type: :fixed_rate | :fixed_delay
) { (instance) -> T } -> void

def execute: -> self
def execution_interval: -> (Float | Integer)
def execution_interval=: (Float | Integer) -> void
def shutdown: -> bool
def interval_type: -> (:fixed_rate | :fixed_delay)
def timeout_interval: -> Float
def running?: -> bool
end
end