class Celluloid::Task - celluloid-0.15.2 Documentation

# 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/tasks.rb, line 18
    def self.current
      Thread.current[:celluloid_task] or raise NotTaskError, "not within a task context"
    end

new(type, meta) { || ... } click to toggle source

Create a new task

    # File lib/celluloid/tasks.rb, line 31
    def initialize(type, meta)
      @type     = type
      @meta     = meta
      @status   = :new

      @exclusive         = false
      @dangerous_suspend = @meta ? @meta.delete(:dangerous_suspend) : false
      @guard_warnings    = false

      actor     = Thread.current[:celluloid_actor]
      @chain_id = 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

          Thread.current[:celluloid_task] = self
          CallChain.current_id = @chain_id

          actor.tasks << self
          yield
        rescue Task::TerminatedError
          # Task was explicitly terminated
        ensure
          @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/tasks.rb, line 23
    def self.suspend(status)
      Task.current.suspend(status)
    end

### Public Instance Methods

backtrace() click to toggle source

    # File lib/celluloid/tasks.rb, line 135
    def backtrace
    end

create(&block) click to toggle source

    # File lib/celluloid/tasks.rb, line 65
    def create(&block)
      raise "Implement #{self.class}#create"
    end

exclusive() { || ... } click to toggle source

Execute a code block in exclusive mode.

    # File lib/celluloid/tasks.rb, line 103
    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/tasks.rb, line 131
    def exclusive?
      @exclusive
    end

guard(message) click to toggle source

    # File lib/celluloid/tasks.rb, line 146
    def guard(message)
      if @guard_warnings
        Logger.warn message if $CELLULOID_DEBUG
      else
        raise message if $CELLULOID_DEBUG
      end
    end

inspect() click to toggle source

Nicer string inspect for tasks

    # File lib/celluloid/tasks.rb, line 142
    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/tasks.rb, line 96
    def resume(value = nil)
      guard "Cannot resume a task from inside of a task" if Thread.current[:celluloid_task]
      deliver(value)
      nil
    end

running?() click to toggle source

Is the current task still running?

    # File lib/celluloid/tasks.rb, line 139
    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/tasks.rb, line 70
    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

      if $CELLULOID_DEBUG && @dangerous_suspend
        warning = "Dangerously suspending task: "
        warning << [
          "type=#{@type.inspect}",
          "meta=#{@meta.inspect}",
          "status=#{@status.inspect}"
        ].join(", ")

        Logger.warn [warning, *caller[2..8]].join("\n\t")
      end

      value = signal

      @status = :running
      raise value if value.is_a?(Celluloid::ResumableError)

      value
    end

terminate() click to toggle source

Terminate this task

    # File lib/celluloid/tasks.rb, line 117
    def terminate
      raise "Cannot terminate an exclusive task" if exclusive?

      if running?
        Celluloid.logger.warn "Terminating task: type=#{@type.inspect}, meta=#{@meta.inspect}, status=#{@status.inspect}"
        exception = Task::TerminatedError.new("task was terminated")
        exception.set_backtrace(caller)
        resume exception
      else
        raise DeadTaskError, "task is already dead"
      end
    end