class Celluloid::Task
Tasks are interruptable/resumable execution contexts used to run methods
Attributes
chain_id[RW]
guard_warnings[RW]
meta[R]
status[R]
type[R]
Public Class Methods
current()
click to toggle source
Obtain the current task
# File lib/celluloid/task.rb, line 5 def self.current Thread.current[:celluloid_task] || raise(NotTaskError, "not within a task context") end
new(type, meta) { || ... }
click to toggle source
Create a new task
# File lib/celluloid/task.rb, line 18 def initialize(type, meta) @type = type @meta = meta @status = :new @exclusive = false @dangerous_suspend = @meta ? @meta.dup.delete(:dangerous_suspend) : false @guard_warnings = false actor = Thread.current[:celluloid_actor] @chain_id = Internals::CallChain.current_id raise NotActorError, "can't create tasks outside of actors" unless actor guard "can't create tasks inside of tasks" if Thread.current[:celluloid_task] create do begin @status = :running actor.setup_thread name_current_thread thread_metadata Thread.current[:celluloid_task] = self Internals::CallChain.current_id = @chain_id actor.tasks << self yield rescue TaskTerminated # Task was explicitly terminated ensure name_current_thread nil @status = :dead actor.tasks.delete self end end end
suspend(status)
click to toggle source
Suspend the running task, deferring to the scheduler
# File lib/celluloid/task.rb, line 10 def self.suspend(status) Task.current.suspend(status) end
Public Instance Methods
backtrace()
click to toggle source
# File lib/celluloid/task.rb, line 137 def backtrace; end
create(&_block)
click to toggle source
# File lib/celluloid/task.rb, line 55 def create(&_block) raise "Implement #{self.class}#create" end
exclusive() { || ... }
click to toggle source
Execute a code block in exclusive mode.
# File lib/celluloid/task.rb, line 96 def exclusive if @exclusive yield else begin @exclusive = true yield ensure @exclusive = false end end end
exclusive?()
click to toggle source
Is this task running in exclusive mode?
# File lib/celluloid/task.rb, line 133 def exclusive? @exclusive end
guard(message)
click to toggle source
# File lib/celluloid/task.rb, line 149 def guard(message) # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!! # rubocop:disable Style/GlobalVars if @guard_warnings Internals::Logger.warn message if $CELLULOID_DEBUG else raise message if $CELLULOID_DEBUG end # rubocop:enable Style/GlobalVars end
inspect()
click to toggle source
Nicer string inspect for tasks
# File lib/celluloid/task.rb, line 145 def inspect "#<#{self.class}:0x#{object_id.to_s(16)} @type=#{@type.inspect}, @meta=#{@meta.inspect}, @status=#{@status.inspect}>" end
resume(value = nil)
click to toggle source
Resume a suspended task, giving it a value to return if needed
# File lib/celluloid/task.rb, line 83 def resume(value = nil) guard "Cannot resume a task from inside of a task" if Thread.current[:celluloid_task] if running? deliver(value) else # rubocop:disable Metrics/LineLength Internals::Logger.warn "Attempted to resume a dead task: type=#{@type.inspect}, meta=#{@meta.inspect}, status=#{@status.inspect}" # rubocop:enable Metrics/LineLength end nil end
running?()
click to toggle source
Is the current task still running?
# File lib/celluloid/task.rb, line 140 def running? @status != :dead end
suspend(status)
click to toggle source
Suspend the current task, changing the status to the given argument
# File lib/celluloid/task.rb, line 60 def suspend(status) raise "Cannot suspend while in exclusive mode" if exclusive? raise "Cannot suspend a task from outside of itself" unless Task.current == self @status = status # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!! # rubocop:disable Style/GlobalVars if $CELLULOID_DEBUG && @dangerous_suspend Internals::Logger.with_backtrace(caller[2...8]) do |logger| logger.warn "Dangerously suspending task: type=#{@type.inspect}, meta=#{@meta.inspect}, status=#{@status.inspect}" end end # rubocop:enable Style/GlobalVars value = signal @status = :running raise value if value.is_a?(Celluloid::Interruption) value end
terminate()
click to toggle source
Terminate this task
# File lib/celluloid/task.rb, line 110 def terminate raise "Cannot terminate an exclusive task" if exclusive? if running? # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!! # rubocop:disable Style/GlobalVars if $CELLULOID_DEBUG Internals::Logger.with_backtrace(backtrace) do |logger| type = @dangerous_suspend ? :warn : :debug logger.send(type, "Terminating task: type=#{@type.inspect}, meta=#{@meta.inspect}, status=#{@status.inspect}") end end # rubocop:enable Style/GlobalVars exception = TaskTerminated.new("task was terminated") exception.set_backtrace(caller) resume exception else raise DeadTaskError, "task is already dead" end end
Private Instance Methods
name_current_thread(new_name)
click to toggle source
# File lib/celluloid/task.rb, line 162 def name_current_thread(new_name) return unless RUBY_PLATFORM == "java" if new_name.nil? new_name = Thread.current[:celluloid_original_thread_name] Thread.current[:celluloid_original_thread_name] = nil else Thread.current[:celluloid_original_thread_name] = Thread.current.to_java.getNativeThread.get_name end Thread.current.to_java.getNativeThread.set_name(new_name) end
thread_metadata()
click to toggle source
# File lib/celluloid/task.rb, line 173 def thread_metadata method = @meta && @meta[:method_name] || "<no method>" klass = Thread.current[:celluloid_actor] && Thread.current[:celluloid_actor].behavior.subject.bare_object.class || "<no actor>" format("[Celluloid] %s#%s", klass, method) end