Class: Concurrent::SerializedExecution

Inherits:
Object
  • Object
show all
Includes:
Logging, Synchronization
Defined in:
lib/concurrent/executor/serialized_execution.rb

Overview

Ensures passed jobs in a serialized order never running at the same time.

Defined Under Namespace

Classes: Job

Instance Method Summary collapse

Methods included from Logging

#log

Constructor Details

#initializeSerializedExecution

Returns a new instance of SerializedExecution.



19
20
21
22
23
24
# File 'lib/concurrent/executor/serialized_execution.rb', line 19

def initialize
  synchronize do
    @being_executed = false
    @stash          = []
  end
end

Instance Method Details

#post(executor, *args) { ... } ⇒ Boolean

Submit a task to the executor for asynchronous processing.

Parameters:

  • executor (Executor)

    to be used for this job

  • args (Array)

    zero or more arguments to be passed to the task

Yields:

  • the asynchronous task to perform

Returns:

  • (Boolean)

    ‘true` if the task is queued, `false` if the executor is not running

Raises:

  • (ArgumentError)

    if no task is given



38
39
40
41
# File 'lib/concurrent/executor/serialized_execution.rb', line 38

def post(executor, *args, &task)
  posts [[executor, args, task]]
  true
end

#posts(posts) ⇒ Object

As #post but allows to submit multiple tasks at once, it’s guaranteed that they will not be interleaved by other tasks.

Parameters:

  • posts (Array<Array(Executor, Array<Object>, Proc)>)

    array of triplets where first is a Executor, second is array of args for task, third is a task (Proc)



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/concurrent/executor/serialized_execution.rb', line 48

def posts(posts)
  # if can_overflow?
  #   raise ArgumentError, 'SerializedExecution does not support thread-pools which can overflow'
  # end

  return nil if posts.empty?

  jobs = posts.map { |executor, args, task| Job.new executor, args, task }

  job_to_post = synchronize do
    if @being_executed
      @stash.push(*jobs)
      nil
    else
      @being_executed = true
      @stash.push(*jobs[1..-1])
      jobs.first
    end
  end

  call_job job_to_post if job_to_post
  true
end