Class: LittleGhost::Support::Task
- Inherits:
-
Object
- Object
- LittleGhost::Support::Task
- Defined in:
- lib/little_ghost/support/task.rb
Overview
Task represents one unit of framework-owned concurrent work. It provides the same completion contract whether TaskRunner selected a thread or fiber.
Constant Summary collapse
- CURRENT_KEY =
:nodoc:
:little_ghost_support_task
Class Method Summary collapse
-
.current ⇒ Object
Returns the Task currently running for this caller, if any.
Instance Method Summary collapse
-
#alive? ⇒ Boolean
Indicates that the task has not finished.
-
#call ⇒ Object
:nodoc:.
-
#current? ⇒ Boolean
Indicates that the caller is running this task.
-
#error ⇒ Object
Returns the worker failure after completion, or nil.
-
#initialize(execution_state:, capture_interruptions: false, &work) ⇒ Task
constructor
:nodoc:.
-
#result ⇒ Object
Returns the task result after completion.
-
#start(worker = nil, terminable: false, joinable: false) ⇒ Object
:nodoc:.
-
#terminate ⇒ Object
Requests forceful termination of a thread-backed task.
-
#wait(deadline: nil) ⇒ Object
Waits for completion and returns this Task.
Constructor Details
#initialize(execution_state:, capture_interruptions: false, &work) ⇒ Task
:nodoc:
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/little_ghost/support/task.rb', line 17 def initialize(execution_state:, capture_interruptions: false, &work) # :nodoc: @execution_state = execution_state @capture_interruptions = capture_interruptions @work = work @mutex = Mutex.new @condition = ConditionVariable.new @finished = false @result = nil @error = nil @terminable = false @joinable = false end |
Class Method Details
.current ⇒ Object
Returns the Task currently running for this caller, if any.
12 13 14 |
# File 'lib/little_ghost/support/task.rb', line 12 def current ExecutionState[CURRENT_KEY] end |
Instance Method Details
#alive? ⇒ Boolean
Indicates that the task has not finished.
68 69 70 |
# File 'lib/little_ghost/support/task.rb', line 68 def alive? @mutex.synchronize { !@finished } end |
#call ⇒ Object
:nodoc:
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/little_ghost/support/task.rb', line 101 def call # :nodoc: ExecutionState.with(@execution_state) do result = ExecutionState.with(CURRENT_KEY => self) { @work.call } @mutex.synchronize { @result = result } end rescue => caught @mutex.synchronize { @error = caught } rescue Exception => caught # rubocop:disable Lint/RescueException raise unless @capture_interruptions @mutex.synchronize { @error = caught } ensure @mutex.synchronize do @finished = true @condition.broadcast end end |
#current? ⇒ Boolean
Indicates that the caller is running this task.
73 74 75 |
# File 'lib/little_ghost/support/task.rb', line 73 def current? equal?(self.class.current) end |
#error ⇒ Object
Returns the worker failure after completion, or nil.
63 64 65 |
# File 'lib/little_ghost/support/task.rb', line 63 def error @mutex.synchronize { @error } end |
#result ⇒ Object
Returns the task result after completion.
58 59 60 |
# File 'lib/little_ghost/support/task.rb', line 58 def result @mutex.synchronize { @result } end |
#start(worker = nil, terminable: false, joinable: false) ⇒ Object
:nodoc:
92 93 94 95 96 97 98 99 |
# File 'lib/little_ghost/support/task.rb', line 92 def start(worker = nil, terminable: false, joinable: false) # :nodoc: @mutex.synchronize do @worker = worker @terminable = terminable @joinable = joinable end self end |
#terminate ⇒ Object
Requests forceful termination of a thread-backed task. Fiber tasks are cooperatively cancelled by their owning operation, so this method returns false for them. The owner remains responsible for a bounded wait after termination.
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/little_ghost/support/task.rb', line 81 def terminate return false unless @terminable return false if current? worker = @mutex.synchronize { @worker unless @finished } return false unless worker worker.kill true end |
#wait(deadline: nil) ⇒ Object
Waits for completion and returns this Task.
deadline is an absolute Time. Reaching it raises
DeadlineExceededError without stopping the task.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/little_ghost/support/task.rb', line 34 def wait(deadline: nil) raise Error, "a task cannot wait for itself" if current? monotonic_deadline = if deadline monotonic_time + [deadline - Time.now, 0].max end worker, joinable = @mutex.synchronize do until @finished if monotonic_deadline remaining = monotonic_deadline - monotonic_time raise DeadlineExceededError, "Task did not finish before the wait deadline" unless remaining.positive? @condition.wait(@mutex, remaining) else @condition.wait(@mutex) end end [@worker, @joinable] end worker.join if joinable self end |