diff --git a/docs-source/signpost.md b/docs-source/signpost.md index 4f4e665a6..b09c1b7d2 100644 --- a/docs-source/signpost.md +++ b/docs-source/signpost.md @@ -3,6 +3,7 @@ Pick a `concurrent-ruby` version: * [master](./master/index.html) +* [1.1.10 with edge 0.6.0](./1.1.10/index.html) * [1.1.9 with edge 0.6.0](./1.1.9/index.html) * [1.1.8 with edge 0.6.0](./1.1.8/index.html) * [1.1.7 with edge 0.6.0](./1.1.7/index.html) diff --git a/docs/1.1.10/Concurrent.html b/docs/1.1.10/Concurrent.html new file mode 100644 index 000000000..4ad6e10f0 --- /dev/null +++ b/docs/1.1.10/Concurrent.html @@ -0,0 +1,3150 @@ + + + + + + + Module: Concurrent + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent.rb,
+ lib/concurrent-ruby/concurrent/map.rb,
lib/concurrent-ruby/concurrent/set.rb,
lib/concurrent-ruby/concurrent/atom.rb,
lib/concurrent-ruby/concurrent/hash.rb,
lib/concurrent-ruby/concurrent/ivar.rb,
lib/concurrent-ruby/concurrent/mvar.rb,
lib/concurrent-ruby/concurrent/tvar.rb,
lib/concurrent-ruby/concurrent/agent.rb,
lib/concurrent-ruby/concurrent/array.rb,
lib/concurrent-ruby/concurrent/async.rb,
lib/concurrent-ruby/concurrent/delay.rb,
lib/concurrent-ruby/concurrent/maybe.rb,
lib/concurrent-ruby/concurrent/tuple.rb,
lib/concurrent-ruby/concurrent/errors.rb,
lib/concurrent-ruby/concurrent/future.rb,
lib/concurrent-ruby/concurrent/options.rb,
lib/concurrent-ruby/concurrent/promise.rb,
lib/concurrent-ruby/concurrent/version.rb,
lib/concurrent-ruby/concurrent/dataflow.rb,
lib/concurrent-ruby/concurrent/promises.rb,
lib/concurrent-ruby/concurrent/constants.rb,
lib/concurrent-ruby/concurrent/exchanger.rb,
lib/concurrent-ruby/concurrent/re_include.rb,
lib/concurrent-ruby/concurrent/timer_task.rb,
lib/concurrent-ruby/concurrent/atomic/event.rb,
lib/concurrent-ruby/concurrent/configuration.rb,
lib/concurrent-ruby/concurrent/mutable_struct.rb,
lib/concurrent-ruby/concurrent/scheduled_task.rb,
lib/concurrent-ruby/concurrent/utility/engine.rb,
lib/concurrent-ruby/concurrent/concern/logging.rb,
lib/concurrent-ruby/concurrent/settable_struct.rb,
lib/concurrent-ruby/concurrent/synchronization.rb,
lib/concurrent-ruby/concurrent/atomic/semaphore.rb,
lib/concurrent-ruby/concurrent/immutable_struct.rb,
lib/concurrent-ruby/concurrent/thread_safe/util.rb,
lib/concurrent-ruby/concurrent/concern/obligation.rb,
lib/concurrent-ruby/concurrent/concern/observable.rb,
lib/concurrent-ruby/concurrent/executor/timer_set.rb,
lib/concurrent-ruby/concurrent/concern/deprecation.rb,
lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb,
lib/concurrent-ruby/concurrent/synchronization/lock.rb,
lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb,
lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb,
lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb,
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb,
lib/concurrent-ruby/concurrent/synchronization/object.rb,
lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb,
lib/concurrent-ruby/concurrent/utility/monotonic_time.rb,
lib/concurrent-ruby/concurrent/utility/native_integer.rb,
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb,
lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb,
lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb,
lib/concurrent-ruby/concurrent/concern/dereferenceable.rb,
lib/concurrent-ruby/concurrent/synchronization/volatile.rb,
lib/concurrent-ruby/concurrent/executor/executor_service.rb,
lib/concurrent-ruby/concurrent/synchronization/condition.rb,
lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb,
lib/concurrent-ruby/concurrent/utility/processor_counter.rb,
lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb,
lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb,
lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb,
lib/concurrent-ruby/concurrent/synchronization/mri_object.rb,
lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb,
lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb,
lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb,
lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb,
lib/concurrent-ruby/concurrent/executor/immediate_executor.rb,
lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb,
lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb,
lib/concurrent-ruby/concurrent/atomic/java_thread_local_var.rb,
lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb,
lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb,
lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb,
lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb,
lib/concurrent-ruby/concurrent/executor/serialized_execution.rb,
lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb,
lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb,
lib/concurrent-ruby/concurrent/executor/java_executor_service.rb,
lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb,
lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb,
lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb,
lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb,
lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb,
lib/concurrent-ruby/concurrent/thread_safe/util/cheap_lockable.rb,
lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb,
lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb,
lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb,
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb,
lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb,
lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb,
lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb,
lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb,
lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb,
lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb,
lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb,
lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb,
lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb,
lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb,
lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb,
lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb,
lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb,
lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb,
lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb,
lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb,
lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb,
lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb,
lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb,
lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb,
lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb,
lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb,
lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb,
lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb,
lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb,
lib/concurrent-ruby/concurrent/collection/map/atomic_reference_map_backend.rb,
lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb,
lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb,
lib/concurrent-ruby-edge/concurrent/edge.rb,
lib/concurrent-ruby-edge/concurrent/actor.rb,
lib/concurrent-ruby-edge/concurrent/channel.rb,
lib/concurrent-ruby-edge/concurrent/actor/core.rb,
lib/concurrent-ruby-edge/concurrent/actor/root.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils.rb,
lib/concurrent-ruby-edge/concurrent/actor/errors.rb,
lib/concurrent-ruby-edge/concurrent/channel/tick.rb,
lib/concurrent-ruby-edge/concurrent/edge/channel.rb,
lib/concurrent-ruby-edge/concurrent/edge/version.rb,
lib/concurrent-ruby-edge/concurrent/actor/context.rb,
lib/concurrent-ruby-edge/concurrent/edge/promises.rb,
lib/concurrent-ruby-edge/concurrent/edge/throttle.rb,
lib/concurrent-ruby-edge/concurrent/lazy_register.rb,
lib/concurrent-ruby-edge/concurrent/actor/envelope.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb,
lib/concurrent-ruby-edge/concurrent/actor/reference.rb,
lib/concurrent-ruby-edge/concurrent/actor/type_check.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/pool.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector.rb,
lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb,
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/ad_hoc.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/balancer.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb,
lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/broadcast.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/ticker.rb,
lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/awaits.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb,
lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb,
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb,
lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb,
lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/supervising.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/put_clause.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/sets_results.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/take_clause.rb,
lib/concurrent-ruby-edge/concurrent/edge/old_channel_integration.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/removes_child.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/after_clause.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/error_clause.rb,
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/default_clause.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/executes_context.rb,
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb,
lib/concurrent-ruby-edge/concurrent/actor/default_dead_letter_handler.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/errors_on_unknown_message.rb
+
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ + + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: Actor, Async, Concern, Edge, ErlangActor, ImmutableStruct, MutableStruct, Promises, ReInclude, SettableStruct, Synchronization, Utility + + + + Classes: Agent, Array, Atom, AtomicBoolean, AtomicFixnum, AtomicMarkableReference, AtomicReference, CachedThreadPool, Cancellation, Channel, ConcurrentUpdateError, CountDownLatch, CyclicBarrier, Delay, Event, Exchanger, FixedThreadPool, Future, Hash, IVar, ImmediateExecutor, IndirectImmediateExecutor, LazyRegister, LockFreeStack, MVar, Map, Maybe, MultipleAssignmentError, MultipleErrors, ProcessingActor, Promise, ReadWriteLock, ReentrantReadWriteLock, SafeTaskExecutor, ScheduledTask, Semaphore, SerializedExecution, SerializedExecutionDelegator, Set, SimpleExecutorService, SingleThreadExecutor, TVar, ThreadLocalVar, ThreadPoolExecutor, Throttle, TimerSet, TimerTask, Transaction, Tuple, WrappingExecutor + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
Error = + +
+
Class.new(StandardError)
+ +
ConfigurationError = +
+
+

Raised when errors occur during configuration.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
CancelledOperationError = +
+
+

Raised when an asynchronous operation is cancelled before execution.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
LifecycleError = +
+
+

Raised when a lifecycle method (such as stop) is called in an improper +sequence or when the object is in an inappropriate state.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
ImmutabilityError = +
+
+

Raised when an attempt is made to violate an immutability guarantee.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
IllegalOperationError = +
+
+

Raised when an operation is attempted which is not legal given the +receiver's current state

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
InitializationError = +
+
+

Raised when an object's methods are called when it has not been +properly initialized.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
MaxRestartFrequencyError = +
+
+

Raised when an object with a start/stop lifecycle has been started an +excessive number of times. Often used in conjunction with a restart +policy or strategy.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
RejectedExecutionError = +
+
+

Raised by an Executor when it is unable to process a given task, +possibly because of a reject policy or other internal error.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
ResourceLimitError = +
+
+

Raised when any finite resource, such as a lock counter, exceeds its +maximum limit/threshold.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
TimeoutError = +
+
+

Raised when an operation times out.

+ + +
+
+
+ + +
+
+
Class.new(Error)
+ +
PromiseExecutionError = + +
+
Class.new(StandardError)
+ +
VERSION = + +
+
'1.1.10'
+ +
NULL_LOGGER = +
+
+

Suppresses all output when used for logging.

+ + +
+
+
+ + +
+
+
lambda { |level, progname, message = nil, &block| }
+ +
EDGE_VERSION = +
+
+ + +
+
+
+ + +
+
+
'0.6.0'
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + +
+

Class Method Details

+ + +
+

+ + .abort_transactionundocumented + + + + + +

+
+

Abort a currently running transaction - see Concurrent::atomically.

+ + +
+
+
+ +

Raises:

+ + +
+ + + + +
+
+
+
+139
+140
+141
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 139
+
+def abort_transaction
+  raise Transaction::AbortError.new
+end
+
+
+ +
+

+ + .atomicallyundocumented + + + + + +

+
+

Run a block that reads and writes TVars as a single atomic transaction. +With respect to the value of TVar objects, the transaction is atomic, in +that it either happens or it does not, consistent, in that the TVar +objects involved will never enter an illegal state, and isolated, in that +transactions never interfere with each other. You may recognise these +properties from database transactions.

+ +

There are some very important and unusual semantics that you must be aware of:

+ +
    +
  • Most importantly, the block that you pass to atomically may be executed +more than once. In most cases your code should be free of +side-effects, except for via TVar.

  • +
  • If an exception escapes an atomically block it will abort the transaction.

  • +
  • It is undefined behaviour to use callcc or Fiber with atomically.

  • +
  • If you create a new thread within an atomically, it will not be part of +the transaction. Creating a thread counts as a side-effect.

  • +
+ +

Transactions within transactions are flattened to a single transaction.

+ + +
+
+
+ +
+

Examples:

+ + +
a = new TVar(100_000)
+b = new TVar(100)
+
+Concurrent::atomically do
+  a.value -= 10
+  b.value += 10
+end
+ +
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 82
+
+def atomically
+  raise ArgumentError.new('no block given') unless block_given?
+
+  # Get the current transaction
+
+  transaction = Transaction::current
+
+  # Are we not already in a transaction (not nested)?
+
+  if transaction.nil?
+    # New transaction
+
+    begin
+      # Retry loop
+
+      loop do
+
+        # Create a new transaction
+
+        transaction = Transaction.new
+        Transaction::current = transaction
+
+        # Run the block, aborting on exceptions
+
+        begin
+          result = yield
+        rescue Transaction::AbortError => e
+          transaction.abort
+          result = Transaction::ABORTED
+        rescue Transaction::LeaveError => e
+          transaction.abort
+          break result
+        rescue => e
+          transaction.abort
+          raise e
+        end
+        # If we can commit, break out of the loop
+
+        if result != Transaction::ABORTED
+          if transaction.commit
+            break result
+          end
+        end
+      end
+    ensure
+      # Clear the current transaction
+
+      Transaction::current = nil
+    end
+  else
+    # Nested transaction - flatten it and just run the block
+
+    yield
+  end
+end
+
+
+ +
+

+ + .call_dataflow(method, executor, *inputs, &block) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+
+
# File 'lib/concurrent-ruby/concurrent/dataflow.rb', line 56
+
+def call_dataflow(method, executor, *inputs, &block)
+  raise ArgumentError.new('an executor must be provided') if executor.nil?
+  raise ArgumentError.new('no block given') unless block_given?
+  unless inputs.all? { |input| input.is_a? IVar }
+    raise ArgumentError.new("Not all dependencies are IVars.\nDependencies: #{ inputs.inspect }")
+  end
+
+  result = Future.new(executor: executor) do
+    values = inputs.map { |input| input.send(method) }
+    block.call(*values)
+  end
+
+  if inputs.empty?
+    result.execute
+  else
+    counter = DependencyCounter.new(inputs.size) { result.execute }
+
+    inputs.each do |input|
+      input.add_observer counter
+    end
+  end
+
+  result
+end
+
+
+ +
+

+ + .create_simple_logger(level = Logger::FATAL, output = $stderr) ⇒ Logger + + + + + +

+
+

Returns Logger with provided level and output.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Logger) + + + + — +

    Logger with provided level and output.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 20
+
+def self.create_simple_logger(level = Logger::FATAL, output = $stderr)
+  # TODO (pitr-ch 24-Dec-2016): figure out why it had to be replaced, stdlogger was deadlocking
+  lambda do |severity, progname, message = nil, &block|
+    return false if severity < level
+
+    message           = block ? block.call : message
+    formatted_message = case message
+                        when String
+                          message
+                        when Exception
+                          format "%s (%s)\n%s",
+                                 message.message, message.class, (message.backtrace || []).join("\n")
+                        else
+                          message.inspect
+                        end
+
+    output.print format "[%s] %5s -- %s: %s\n",
+                        Time.now.strftime('%Y-%m-%d %H:%M:%S.%L'),
+                        Logger::SEV_LABEL[severity],
+                        progname,
+                        formatted_message
+    true
+  end
+end
+
+
+ +
+

+ + .create_stdlib_logger(level = Logger::FATAL, output = $stderr) ⇒ Logger + + + + + +

+
+
Deprecated.
+

Returns Logger with provided level and output.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Logger) + + + + — +

    Logger with provided level and output.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 52
+
+def self.create_stdlib_logger(level = Logger::FATAL, output = $stderr)
+  logger           = Logger.new(output)
+  logger.level     = level
+  logger.formatter = lambda do |severity, datetime, progname, msg|
+    formatted_message = case msg
+                        when String
+                          msg
+                        when Exception
+                          format "%s (%s)\n%s",
+                                 msg.message, msg.class, (msg.backtrace || []).join("\n")
+                        else
+                          msg.inspect
+                        end
+    format "[%s] %5s -- %s: %s\n",
+           datetime.strftime('%Y-%m-%d %H:%M:%S.%L'),
+           severity,
+           progname,
+           formatted_message
+  end
+
+  lambda do |loglevel, progname, message = nil, &block|
+    logger.add loglevel, message, progname, &block
+  end
+end
+
+
+ +
+

+ + .dataflow(*inputs) {|inputs| ... } ⇒ Object + + + + + +

+
+

Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available. +Data dependencies are Future values. The dataflow task itself is also a Future value, so you can build up a graph of these tasks, each of which is run when all the data and other tasks it depends on are available or completed.

+ +

Our syntax is somewhat related to that of Akka's flow and Habanero Java's DataDrivenFuture. However unlike Akka we don't schedule a task at all until it is ready to run, and unlike Habanero Java we pass the data values into the task instead of dereferencing them again in the task.

+ +

The theory of dataflow goes back to the 70s. In the terminology of the literature, our implementation is coarse-grained, in that each task can be many instructions, and dynamic in that you can create more tasks within other tasks.

+ +

Example

+ +

A dataflow task is created with the dataflow method, passing in a block.

+ +
task = Concurrent::dataflow { 14 }
+
+ +

This produces a simple Future value. The task will run immediately, as it has no dependencies. We can also specify Future values that must be available before a task will run. When we do this we get the value of those futures passed to our block.

+ +
a = Concurrent::dataflow { 1 }
+b = Concurrent::dataflow { 2 }
+c = Concurrent::dataflow(a, b) { |av, bv| av + bv }
+
+ +

Using the dataflow method you can build up a directed acyclic graph (DAG) of tasks that depend on each other, and have the tasks run as soon as their dependencies are ready and there is CPU capacity to schedule them. This can help you create a program that uses more of the CPU resources available to you.

+ +

Derivation

+ +

This section describes how we could derive dataflow from other primitives in this library.

+ +

Consider a naive fibonacci calculator.

+ +
def fib(n)
+  if n < 2
+    n
+  else
+    fib(n - 1) + fib(n - 2)
+  end
+end
+
+puts fib(14) #=> 377
+
+ +

We could modify this to use futures.

+ +
def fib(n)
+  if n < 2
+    Concurrent::Future.new { n }
+  else
+    n1 = fib(n - 1).execute
+    n2 = fib(n - 2).execute
+    Concurrent::Future.new { n1.value + n2.value }
+  end
+end
+
+f = fib(14) #=> #f.execute   #=> #
+sleep(0.5)
+
+puts f.value #=> 377
+
+ +

One of the drawbacks of this approach is that all the futures start, and then most of them immediately block on their dependencies. We know that there's no point executing those futures until their dependencies are ready, so let's not execute each future until all their dependencies are ready.

+ +

To do this we'll create an object that counts the number of times it observes a future finishing before it does something - and for us that something will be to execute the next future.

+ +
class CountingObserver
+
+  def initialize(count, &block)
+    @count = count
+    @block = block
+  end
+
+  def update(time, value, reason)
+    @count -= 1
+
+    if @count <= 0
+      @block.call()
+    end
+  end
+
+end
+
+def fib(n)
+  if n < 2
+    Concurrent::Future.new { n }.execute
+  else
+    n1 = fib(n - 1)
+    n2 = fib(n - 2)
+
+    result = Concurrent::Future.new { n1.value + n2.value }
+
+    barrier = CountingObserver.new(2) { result.execute }
+    n1.add_observer barrier
+    n2.add_observer barrier
+
+    n1.execute
+    n2.execute
+
+    result
+  end
+end
+
+ +

We can wrap this up in a dataflow utility.

+ +
f = fib(14) #=> #sleep(0.5)
+
+puts f.value #=> 377
+
+def dataflow(*inputs, &block)
+  result = Concurrent::Future.new(&block)
+
+  if inputs.empty?
+    result.execute
+  else
+    barrier = CountingObserver.new(inputs.size) { result.execute }
+
+    inputs.each do |input|
+      input.add_observer barrier
+    end
+  end
+
+  result
+end
+
+def fib(n)
+  if n < 2
+    dataflow { n }
+  else
+    n1 = fib(n - 1)
+    n2 = fib(n - 2)
+    dataflow(n1, n2) { n1.value + n2.value }
+  end
+end
+
+f = fib(14) #=> #sleep(0.5)
+
+puts f.value #=> 377
+
+ +

Since we know that the futures the dataflow computation depends on are already going to be available when the future is executed, we might as well pass the values into the block so we don't have to reference the futures inside the block. This allows us to write the dataflow block as straight non-concurrent code without reference to futures.

+ +
def dataflow(*inputs, &block)
+  result = Concurrent::Future.new do
+    values = inputs.map { |input| input.value }
+    block.call(*values)
+  end
+
+  if inputs.empty?
+    result.execute
+  else
+    barrier = CountingObserver.new(inputs.size) { result.execute }
+
+    inputs.each do |input|
+      input.add_observer barrier
+    end
+  end
+
+  result
+end
+
+def fib(n)
+  if n < 2
+    Concurrent::dataflow { n }
+  else
+    n1 = fib(n - 1)
+    n2 = fib(n - 2)
+    Concurrent::dataflow(n1, n2) { |v1, v2| v1 + v2 }
+  end
+end
+
+f = fib(14) #=> #sleep(0.5)
+
+puts f.value #=> 377
+
+

+ + +
+
+
+

Parameters:

+
    + +
  • + + inputs + + + (Future) + + + + — +

    zero or more Future operations that this dataflow depends upon

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    The operation to perform once all the dependencies are met

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + inputs + + + (Future) + + + + — +

    each of the Future inputs to the dataflow

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    the result of the block operation

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the result of all the operations

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
  • + + + (ArgumentError) + + + + — +

    if any of the inputs are not IVars

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+34
+35
+36
+
+
# File 'lib/concurrent-ruby/concurrent/dataflow.rb', line 34
+
+def dataflow(*inputs, &block)
+  dataflow_with(Concurrent.global_io_executor, *inputs, &block)
+end
+
+
+ +
+

+ + .dataflow!(*inputs, &block) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+44
+45
+46
+
+
# File 'lib/concurrent-ruby/concurrent/dataflow.rb', line 44
+
+def dataflow!(*inputs, &block)
+  dataflow_with!(Concurrent.global_io_executor, *inputs, &block)
+end
+
+
+ +
+

+ + .dataflow_with(executor, *inputs, &block) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+39
+40
+41
+
+
# File 'lib/concurrent-ruby/concurrent/dataflow.rb', line 39
+
+def dataflow_with(executor, *inputs, &block)
+  call_dataflow(:value, executor, *inputs, &block)
+end
+
+
+ +
+

+ + .dataflow_with!(executor, *inputs, &block) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+49
+50
+51
+
+
# File 'lib/concurrent-ruby/concurrent/dataflow.rb', line 49
+
+def dataflow_with!(executor, *inputs, &block)
+  call_dataflow(:value!, executor, *inputs, &block)
+end
+
+
+ +
+

+ + .disable_at_exit_handlers!undocumented + + + + + +

+
+
Deprecated.

Has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841.

+
+ +
+ Note: +

this option should be needed only because of at_exit ordering +issues which may arise when running some of the testing frameworks. +E.g. Minitest's test-suite runs itself in at_exit callback which +executes after the pools are already terminated. Then auto termination +needs to be disabled and called manually after test-suite ends.

+
+
+ +
+ Note: +

This method should never be called +from within a gem. It should only be used from within the main +application and even then it should be used only when necessary.

+
+
+ +

Disables AtExit handlers including pool auto-termination handlers. +When disabled it will be the application programmer's responsibility +to ensure that the handlers are shutdown properly prior to application +exit by calling AtExit.run method.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+131
+132
+133
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 131
+
+def self.disable_at_exit_handlers!
+  deprecated "Method #disable_at_exit_handlers! has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841."
+end
+
+
+ +
+

+ + .executor(executor_identifier) ⇒ Executor + + + + + +

+
+

General access point to global executors.

+ + +
+
+
+

Parameters:

+ + +

Returns:

+
    + +
  • + + + (Executor) + + + +
  • + +
+ +
+ + + + +
+
+
+
+166
+167
+168
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 166
+
+def self.executor(executor_identifier)
+  Options.executor(executor_identifier)
+end
+
+
+ +
+

+ + .global_fast_executorThreadPoolExecutor + + + + + +

+
+

Global thread pool optimized for short, fast operations.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+138
+139
+140
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 138
+
+def self.global_fast_executor
+  GLOBAL_FAST_EXECUTOR.value
+end
+
+
+ +
+

+ + .global_immediate_executorundocumented + + + + + +

+ + + + +
+
+
+
+149
+150
+151
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 149
+
+def self.global_immediate_executor
+  GLOBAL_IMMEDIATE_EXECUTOR
+end
+
+
+ +
+

+ + .global_io_executorThreadPoolExecutor + + + + + +

+
+

Global thread pool optimized for long, blocking (IO) tasks.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+145
+146
+147
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 145
+
+def self.global_io_executor
+  GLOBAL_IO_EXECUTOR.value
+end
+
+
+ +
+

+ + .global_loggerundocumented + + + + + +

+ + + + +
+
+
+
+92
+93
+94
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 92
+
+def self.global_logger
+  GLOBAL_LOGGER.value
+end
+
+
+ +
+

+ + .global_logger=(value) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+96
+97
+98
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 96
+
+def self.global_logger=(value)
+  GLOBAL_LOGGER.value = value
+end
+
+
+ +
+

+ + .global_timer_setConcurrent::TimerSet + + + + + +

+
+

Global thread pool user for global timers.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+156
+157
+158
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 156
+
+def self.global_timer_set
+  GLOBAL_TIMER_SET.value
+end
+
+
+ +
+

+ + .leave_transactionundocumented + + + + + +

+
+

Leave a transaction without committing or aborting - see Concurrent::atomically.

+ + +
+
+
+ +

Raises:

+ + +
+ + + + +
+
+
+
+144
+145
+146
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 144
+
+def leave_transaction
+  raise Transaction::LeaveError.new
+end
+
+
+ +
+

+ + .monotonic_time(unit = :float_second) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+19
+20
+21
+
+
# File 'lib/concurrent-ruby/concurrent/utility/monotonic_time.rb', line 19
+
+def monotonic_time(unit = :float_second)
+  Process.clock_gettime(Process::CLOCK_MONOTONIC, unit)
+end
+
+
+ +
+

+ + .new_fast_executor(opts = {}) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 170
+
+def self.new_fast_executor(opts = {})
+  FixedThreadPool.new(
+      [2, Concurrent.processor_count].max,
+      auto_terminate:  opts.fetch(:auto_terminate, true),
+      idletime:        60, # 1 minute
+      max_queue:       0, # unlimited
+      fallback_policy: :abort, # shouldn't matter -- 0 max queue
+      name:            "fast"
+  )
+end
+
+
+ +
+

+ + .new_io_executor(opts = {}) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+181
+182
+183
+184
+185
+186
+187
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 181
+
+def self.new_io_executor(opts = {})
+  CachedThreadPool.new(
+      auto_terminate:  opts.fetch(:auto_terminate, true),
+      fallback_policy: :abort, # shouldn't matter -- 0 max queue
+      name:            "io"
+  )
+end
+
+
+ +
+

+ + .physical_processor_countundocumented + + + + + +

+ + + + +
+
+
+
+127
+128
+129
+
+
# File 'lib/concurrent-ruby/concurrent/utility/processor_counter.rb', line 127
+
+def self.physical_processor_count
+  processor_counter.physical_processor_count
+end
+
+
+ +
+

+ + .processor_countundocumented + + + + + +

+ + + + +
+
+
+
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/utility/processor_counter.rb', line 123
+
+def self.processor_count
+  processor_counter.processor_count
+end
+
+
+ +
+

+ + .use_simple_logger(level = Logger::FATAL, output = $stderr) ⇒ undocumented + + + + + +

+
+

Use logger created by #create_simple_logger to log concurrent-ruby messages.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+46
+47
+48
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 46
+
+def self.use_simple_logger(level = Logger::FATAL, output = $stderr)
+  Concurrent.global_logger = create_simple_logger level, output
+end
+
+
+ +
+

+ + .use_stdlib_logger(level = Logger::FATAL, output = $stderr) ⇒ undocumented + + + + + +

+
+
Deprecated.
+

Use logger created by #create_stdlib_logger to log concurrent-ruby messages.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+79
+80
+81
+
+
# File 'lib/concurrent-ruby/concurrent/configuration.rb', line 79
+
+def self.use_stdlib_logger(level = Logger::FATAL, output = $stderr)
+  Concurrent.global_logger = create_stdlib_logger level, output
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #exchange(value, timeout = nil) ⇒ Object + + + + + +

+
+

Waits for another thread to arrive at this exchange point (unless the +current thread is interrupted), and then transfers the given object to +it, receiving its object in return. The timeout value indicates the +approximate number of seconds the method should block while waiting +for the exchange. When the timeout value is nil the method will +block indefinitely.

+ +

In some edge cases when a timeout is given a return value of nil may be +ambiguous. Specifically, if nil is a valid value in the exchange it will +be impossible to tell whether nil is the actual return value or if it +signifies timeout. When nil is a valid value in the exchange consider +using #exchange! or #try_exchange instead.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the value to exchange with another thread

    +
    + +
  • + +
  • + + timeout + + + (Numeric, nil) + + + (defaults to: nil) + + + — +

    in seconds, nil blocks indefinitely

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value exchanged by the other thread or nil on timeout

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/exchanger.rb', line 340
+
+
+
+
+ +
+

+ + #exchange!(value, timeout = nil) ⇒ Object + + + + + +

+
+

Waits for another thread to arrive at this exchange point (unless the +current thread is interrupted), and then transfers the given object to +it, receiving its object in return. The timeout value indicates the +approximate number of seconds the method should block while waiting +for the exchange. When the timeout value is nil the method will +block indefinitely.

+ +

On timeout a TimeoutError exception will be raised.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the value to exchange with another thread

    +
    + +
  • + +
  • + + timeout + + + (Numeric, nil) + + + (defaults to: nil) + + + — +

    in seconds, nil blocks indefinitely

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value exchanged by the other thread

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/exchanger.rb', line 344
+
+
+
+
+ +
+

+ + #initialize(opts = {}) ⇒ undocumented + + + + + +

+
+

Create a new thread pool.

+ + +
+
+
+ + + + +

Options Hash (opts):

+
    + +
  • + :fallback_policy + (Symbol) + + + — default: + :discard + + + + —

    the policy for handling new +tasks that are received when the queue size has reached +max_queue or the executor has shut down

    +
    + +
  • + +
+ + +

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if :fallback_policy is not one of the values specified +in FALLBACK_POLICIES

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/exchanger.rb', line 337
+
+
+
+
+ +
+

+ + #try_exchange(value, timeout = nil) ⇒ Concurrent::Maybe + + + + + +

+
+

Waits for another thread to arrive at this exchange point (unless the +current thread is interrupted), and then transfers the given object to +it, receiving its object in return. The timeout value indicates the +approximate number of seconds the method should block while waiting +for the exchange. When the timeout value is nil the method will +block indefinitely.

+ +

The return value will be a Maybe set to Just on success or +Nothing on timeout.

+ + +
+
+
+ +
+

Examples:

+ + +

+exchanger = Concurrent::Exchanger.new
+
+result = exchanger.exchange(:foo, 0.5)
+
+if result.just?
+  puts result.value #=> :bar
+else
+  puts 'timeout'
+end
+ +
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the value to exchange with another thread

    +
    + +
  • + +
  • + + timeout + + + (Numeric, nil) + + + (defaults to: nil) + + + — +

    in seconds, nil blocks indefinitely

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Concurrent::Maybe) + + + + — +

    on success a Just maybe will be returned with +the item exchanged by the other thread as #value; on timeout a +Nothing maybe will be returned with TimeoutError as #reason

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/exchanger.rb', line 348
+
+
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor.html b/docs/1.1.10/Concurrent/Actor.html new file mode 100644 index 000000000..f47023029 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor.html @@ -0,0 +1,1300 @@ + + + + + + + Module: Concurrent::Actor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Actor + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor.rb,
+ lib/concurrent-ruby-edge/concurrent/actor/core.rb,
lib/concurrent-ruby-edge/concurrent/actor/root.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils.rb,
lib/concurrent-ruby-edge/concurrent/actor/errors.rb,
lib/concurrent-ruby-edge/concurrent/actor/context.rb,
lib/concurrent-ruby-edge/concurrent/actor/envelope.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb,
lib/concurrent-ruby-edge/concurrent/actor/reference.rb,
lib/concurrent-ruby-edge/concurrent/actor/type_check.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/pool.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/ad_hoc.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/balancer.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/broadcast.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/awaits.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb,
lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb,
lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/supervising.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/sets_results.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/removes_child.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/executes_context.rb,
lib/concurrent-ruby-edge/concurrent/actor/default_dead_letter_handler.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/errors_on_unknown_message.rb
+
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Actor model

+ +
    +
  • Light-weighted running on thread-pool.
  • +
  • Inspired by Akka and Erlang.
  • +
  • Modular.
  • +
+ +

This Actor model implementation makes actors very cheap to create and discard. +Thousands of actors can be created, allowing you to break the program into smaller +maintainable pieces, without violating the single responsibility principle.

+ +

What is an actor model?

+ +

Actor-based concurrency is all the rage in some circles. Originally described in 1973, the actor model is a paradigm +for creating asynchronous, concurrent objects that is becoming increasingly popular. Much has changed since actors +were first written about four decades ago, which has led to a serious fragmentation within the actor community. +There is no universally accepted, strict definition of "actor" and actor implementations differ widely between +languages and libraries.

+ +

Wiki definition is pretty good: +The actor model in computer science is a mathematical model of concurrent computation +that treats actors as the universal primitives of concurrent digital computation: +in response to a message that it receives, an actor can make local decisions, +create more actors, send more messages, and determine how to respond to the next +message received.

+ +

Why?

+ +

Concurrency is hard to get right, actors are one of many ways how to simplify the problem.

+ +

Quick example

+ +

An example:

+ +
class Counter < Concurrent::Actor::Context
+  # Include context of an actor which gives this class access to reference
+  # and other information about the actor
+
+  # use initialize as you wish
+  def initialize(initial_value)
+    @count = initial_value
+  end
+
+  # override on_message to define actor's behaviour
+  def on_message(message)
+    if Integer === message
+      @count += message
+    end
+  end
+end #
+
+# Create new actor naming the instance 'first'.
+# Return value is a reference to the actor, the actual actor is never returned.
+counter = Counter.spawn(:first, 5)
+
+# Tell a message and forget returning self.
+counter.tell(1)
+counter << 1
+# (First counter now contains 7.)
+
+# Send a messages asking for a result.
+counter.ask(0).class
+counter.ask(0).value
+
+ +

class Adder < Concurrent::Actor::RestartingContext
+  def initialize(init)
+    @count = init
+  end
+
+  def on_message(message)
+    case message
+    when :add
+      @count += 1
+    else
+      # pass to ErrorsOnUnknownMessage behaviour, which will just fail
+      pass
+    end
+  end
+end 
+
+# `link: true` makes the actor linked to root actor and supervised
+# which is default behavior
+adder = Adder.spawn(name: :adder, link: true, args: [1])
+    # => #
+adder.parent
+    # => #
+
+# tell and forget
+adder.tell(:add).tell(:add)
+    # => #
+# ask to get result
+adder.ask!(:add)                                   # => 4
+# fail the actor
+adder.ask!(:bad) rescue $!
+    # => #>
+# actor is restarted with initial values
+adder.ask!(:add)                                   # => 2
+adder.ask!(:terminate!)                            # => true

+ +

Spawning actors

+ + + +

Sending messages

+ +
    +
  • Reference#tell +Sends the message asynchronously to the actor and immediately returns +self (the reference) allowing to chain message telling.
  • +
  • Reference#ask +
  • +
  • Reference#ask! +Sends the message synchronously and blocks until the message +is processed. Raises on error.
  • +
+ +

Messages are processed in same order as they are sent by a sender. It may interleaved with +messages from other senders though.

+ +

Immutability

+ +

Messages sent between actors should be immutable. Gems like

+ +
    +
  • Algebrick - Typed struct on steroids based on +algebraic types and pattern matching
  • +
  • Hamster - Efficient, Immutable, Thread-Safe +Collection classes for Ruby
  • +
+ +

are very helpful.

+ +

require 'algebrick'                                # => true
+
+# Actor message protocol definition with Algebrick
+Protocol = Algebrick.type do
+  variants Add      = type { fields! a: Numeric, b: Numeric },
+           Subtract = type { fields! a: Numeric, b: Numeric }
+end                                                # => Protocol(Add | Subtract)
+
+class Calculator < Concurrent::Actor::RestartingContext
+  include Algebrick::Matching
+
+  def on_message(message)
+    # pattern matching on the message with deconstruction
+    # ~ marks values which are passed to the block
+    match message,
+          (on Add.(~any, ~any) do |a, b|
+            a + b
+          end),
+          # or using multi-assignment
+          (on ~Subtract do |(a, b)|
+            a - b
+          end)
+  end
+end 
+
+calculator = Calculator.spawn('calculator')
+    # => #
+addition = calculator.ask Add[1, 2]
+    # => <#Concurrent::Promises::Future:0x7fbedc05f7b0 pending>
+subtraction = calculator.ask Subtract[1, 0.5]
+    # => <#Concurrent::Promises::Future:0x7fbedd891388 pending>
+results = (addition & subtraction)
+    # => <#Concurrent::Promises::Future:0x7fbedc04eeb0 pending>
+results.value!                                     # => [3, 0.5]
+
+calculator.ask! :terminate!                        # => true

+ +

Actor definition

+ +

New actor is defined by subclassing RestartingContext, Context and defining its abstract methods. +AbstractContext can be subclassed directly to implement more specific behaviour see Root implementation.

+ + + +

Example of ac actor definition:

+ +

Message = Struct.new :action, :value 
+
+class AnActor < Concurrent::Actor::RestartingContext
+  def initialize(init)
+    @counter = init
+  end
+
+  # override #on_message to define actor's behaviour on message received
+  def on_message(message)
+    case message.action
+    when :add
+      @counter = @counter + message.value
+    when :subtract
+      @counter = @counter - message.value
+    when :value
+      @counter
+    else
+      pass
+    end
+  end
+
+  # set counter to zero when there is an error
+  def on_event(event)
+    if event == :reset
+      @counter = 0 # ignore initial value
+    end
+  end
+end 
+
+an_actor = AnActor.spawn name: 'an_actor', args: 10 
+an_actor << Message.new(:add, 1) << Message.new(:subtract, 2) 
+an_actor.ask!(Message.new(:value, nil))            # => 9
+an_actor << :boo << Message.new(:add, 1) 
+an_actor.ask!(Message.new(:value, nil))            # => 1
+an_actor << :terminate!
+    # => #

+ +

See methods of AbstractContext what else can be tweaked, e.g AbstractContext#default_reference_class

+ +

Reference

+ +

Reference is public interface of Actor instances. It is used for sending messages and can +be freely passed around the application. It also provides some basic information about the actor, +see PublicDelegations.

+ +
AdHoc.spawn('printer') { -> message { puts message } }
+# => #
+#                                   ^object_id     ^path     ^context class
+
+

+ +

Garbage collection

+ +

Spawned actor cannot be garbage-collected until it's terminated. There is a reference held in the parent actor.

+ +

Parent-child relationship, name, and path

+ +
    +
  • Core#name +The name of actor instance, it should be uniq (not enforced). Allows easier orientation +between actor instances.
  • +
  • Core#path +Path of this actor. It is used for easier orientation and logging. +Path is constructed recursively with: parent.path + self.name up to a Actor.root, +e.g. /an_actor/its_child.
  • +
  • Core#parent +A parent Actor. When actor is spawned the Actor.current becomes its parent. +When actor is spawned from a thread outside of an actor (Actor.current is nil) Actor.root is assigned.
  • +
+ +

Behaviour

+ +

Actors have modular architecture, which is achieved by combining a light core with chain of +behaviours. Each message or internal event propagates through the chain allowing the +behaviours react based on their responsibility.

+ +
    +
  • Behaviour::Linking:

    + +
    +

    Links the actor to other actors and sends actor's events to them, +like: :terminated, :paused, :resumed, errors, etc. +Linked actor needs to handle those messages.

    + +
    listener = AdHoc.spawn name: :listener do
    +  lambda do |message|
    +    case message
    +    when Reference
    +      if message.ask!(:linked?)
    +        message << :unlink
    +      else
    +        message << :link
    +      end
    +    else
    +      puts "got event #{message.inspect} from #{envelope.sender}"
    +    end
    +  end
    +end
    +
    +an_actor = AdHoc.spawn name: :an_actor, supervise: true, behaviour_definition: Behaviour.restarting_behaviour_definition do
    +  lambda { |message| raise 'failed'}
    +end
    +
    +# link the actor
    +listener.ask(an_actor).wait
    +an_actor.ask(:fail).wait
    +# unlink the actor
    +listener.ask(an_actor).wait
    +an_actor.ask(:fail).wait
    +an_actor << :terminate!
    +
    + +

    produces only two events, other events happened after unlinking

    + +
    got event #<RuntimeError: failed> from #<Concurrent::Actor::Reference /an_actor (Concurrent::Actor::Utils::AdHoc)>
    +got event :reset from #<Concurrent::Actor::Reference /an_actor (Concurrent::Actor::Utils::AdHoc)>
    +
    +

    +
  • +
  • Behaviour::Awaits:

    + +
    +

    Accepts :await messages. Which allows to wait on Actor to process all previously send +messages.

    + +
    actor << :a << :b
    +actor.ask(:await).wait # blocks until :a and :b are processed
    +
    +

    +
  • +
  • Behaviour::Pausing:

    + +
    +

    Allows to pause actors on errors. +When paused all arriving messages are collected and processed after the actor +is resumed or reset. Resume will simply continue with next message. +Reset also reinitialized context.

    +
  • +
  • Behaviour::Supervising:

    + +
    +

    Handles supervised actors. Handle configures what to do with failed child: :terminate!, :resume!, :reset!, +or :restart!. Strategy sets :one_for_one (restarts just failed actor) or :one_for_all (restarts all child actors).

    +
  • +
  • Behaviour::Supervising:

    + +
    +

    Handles supervised actors. Handle configures what to do with failed child: :terminate!, :resume!, :reset!, +or :restart!. Strategy sets :one_for_one (restarts just failed actor) or :one_for_all (restarts all child actors).

    +
  • +
  • Behaviour::ExecutesContext:

    + +
    +

    Delegates messages and events to AbstractContext instance.

    +
  • +
  • Behaviour::ErrorsOnUnknownMessage:

    + +
    +

    Simply fails when message arrives here. It's usually the last behaviour.

    +
  • +
  • Behaviour::Termination:

    + +
    +

    Handles actor termination. Waits until all its children are terminated, +can be configured on behaviour initialization.

    +
  • +
  • Behaviour::RemovesChild:

    + +
    +

    Removes terminated children.

    +
  • +
+ +

If needed new behaviours can be added, or old one removed to get required behaviour.

+ + +

+ +

IO cooperation

+ +

Actors are running on shared thread poll which allows user to create many actors cheaply. +Downside is that these actors cannot be directly used to do IO or other blocking operations. +Blocking operations could starve the default_task_pool. However there are two options:

+ +
    +
  • Create an regular actor which will schedule blocking operations in global_operation_pool +(which is intended for blocking operations) sending results back to self in messages.
  • +
  • Create an actor using global_operation_pool instead of global_task_pool, e.g. +AnIOActor.spawn name: :blocking, executor: Concurrent.configuration.global_operation_pool.
  • +
+ +

Example

+ +

require 'concurrent'                               # => false
+
+# logger = Logger.new(STDOUT)
+# Concurrent.configuration.logger = logger.method(:add)
+
+# First option is to use operation pool
+
+class ActorDoingIO < Concurrent::Actor::RestartingContext
+  def on_message(message)
+    # do IO operation
+  end
+
+  def default_executor
+    Concurrent.global_io_executor
+  end
+end 
+
+actor_doing_io = ActorDoingIO.spawn :actor_doing_io
+    # => #
+actor_doing_io.executor == Concurrent.global_io_executor
+    # => true
+
+# It can be also built into a pool so there is not too many IO operations
+
+class IOWorker < Concurrent::Actor::Context
+  def on_message(io_job)
+    # do IO work
+    sleep 0.1
+    puts "#{path} second:#{(Time.now.to_f*100).floor} message:#{io_job}"
+  end
+
+  def default_executor
+    Concurrent.global_io_executor
+  end
+end 
+
+pool = Concurrent::Actor::Utils::Pool.spawn('pool', 2) do |index|
+  IOWorker.spawn(name: "worker-#{index}")
+end
+    # => #
+
+pool << 1 << 2 << 3 << 4 << 5 << 6
+    # => #
+
+# prints two lines each second
+# /pool/worker-0 second:1414677666 message:1
+# /pool/worker-1 second:1414677666 message:2
+# /pool/worker-0 second:1414677667 message:3
+# /pool/worker-1 second:1414677667 message:4
+# /pool/worker-0 second:1414677668 message:5
+# /pool/worker-1 second:1414677668 message:6
+
+sleep 1                                            # => 1

+ +

Dead letter routing

+ +

see AbstractContext#dead_letter_routing description:

+ +
+

Defines an actor responsible for dead letters. Any rejected message send +with Reference#tell is sent there, a message with future is considered +already monitored for failures. Default behaviour is to use +AbstractContext#dead_letter_routing of the parent, so if no +AbstractContext#dead_letter_routing method is overridden in +parent-chain the message ends up in Actor.root.dead_letter_routing +agent which will log warning.

+
+ +

FAQ

+ +

What happens if I try to supervise using a normal Context?

+ +

Alleged supervisor will receive errors from its supervised actors. They'll have to be handled manually.

+ +

How to change supervision strategy?

+ +

Use option behaviour_definition: Behaviour.restarting_behaviour_definition(:resume!) or +behaviour_definition: Behaviour.restarting_behaviour_definition(:reset!, :one_for_all)

+ +

How to change behaviors?

+ +

Any existing behavior can be subclassed

+ +

How to implement custom restarting?

+ +

By subclassing Behaviour::Pausing and overriding Behaviour::Pausing#restart!. Implementing +AbstractContext#on_event could be also considered.

+ +

We'll be happy to answer any other questions, +just open an Issue or find us on +https://gitter.im/ruby-concurrency/concurrent-ruby.

+ +

Speed

+ +

Simple benchmark Actor vs Celluloid, the numbers are looking good +but you know how it is with benchmarks. Source code is in +examples/actor/celluloid_benchmark.rb. It sends numbers between x actors +and adding 1 until certain limit is reached.

+ +

Benchmark legend:

+ +
    +
  • mes. - number of messages send between the actors
  • +
  • act. - number of actors exchanging the messages
  • +
  • impl. - which gem is used
  • +
+ +

JRUBY

+ +
Rehearsal ---------------------------------------------------------
+50000    2 concurrent  26.140000   0.610000  26.750000 (  7.761000)
+50000    2 celluloid   41.440000   5.270000  46.710000 ( 17.535000)
+50000  500 concurrent  11.340000   0.180000  11.520000 (  3.498000)
+50000  500 celluloid   19.310000  10.680000  29.990000 ( 14.619000)
+50000 1000 concurrent  10.640000   0.180000  10.820000 (  3.563000)
+50000 1000 celluloid   17.840000  19.850000  37.690000 ( 18.892000)
+50000 1500 concurrent  14.120000   0.290000  14.410000 (  4.618000)
+50000 1500 celluloid   19.060000  28.920000  47.980000 ( 25.185000)
+---------------------------------------------- total: 225.870000sec
+
+ mes. act.      impl.       user     system      total        real
+50000    2 concurrent   7.320000   0.530000   7.850000 (  3.637000)
+50000    2 celluloid   13.780000   4.730000  18.510000 ( 10.756000)
+50000  500 concurrent   9.270000   0.140000   9.410000 (  3.020000)
+50000  500 celluloid   16.540000  10.920000  27.460000 ( 14.308000)
+50000 1000 concurrent   9.970000   0.160000  10.130000 (  3.445000)
+50000 1000 celluloid   15.930000  20.840000  36.770000 ( 18.272000)
+50000 1500 concurrent  11.580000   0.240000  11.820000 (  3.723000)
+50000 1500 celluloid   19.440000  29.060000  48.500000 ( 25.227000) (1)
+
+ +

MRI 2.1.0

+ +
Rehearsal ---------------------------------------------------------
+50000    2 concurrent   4.180000   0.080000   4.260000 (  4.269435)
+50000    2 celluloid    7.740000   3.100000  10.840000 ( 10.043875)
+50000  500 concurrent   5.900000   1.310000   7.210000 (  6.565067)
+50000  500 celluloid   12.820000   5.810000  18.630000 ( 17.320765)
+50000 1000 concurrent   6.080000   1.640000   7.720000 (  6.931294)
+50000 1000 celluloid   17.130000   8.320000  25.450000 ( 23.786146)
+50000 1500 concurrent   6.940000   2.030000   8.970000 (  7.927330)
+50000 1500 celluloid   20.980000  12.040000  33.020000 ( 30.849578)
+---------------------------------------------- total: 116.100000sec
+
+ mes. act.      impl.       user     system      total        real
+50000    2 concurrent   3.730000   0.100000   3.830000 (  3.822688)
+50000    2 celluloid    7.900000   2.910000  10.810000 (  9.924014)
+50000  500 concurrent   5.420000   1.230000   6.650000 (  6.025579)
+50000  500 celluloid   12.720000   5.540000  18.260000 ( 16.889517)
+50000 1000 concurrent   5.420000   0.910000   6.330000 (  5.896689)
+50000 1000 celluloid   16.090000   8.040000  24.130000 ( 22.347102)
+50000 1500 concurrent   5.580000   0.760000   6.340000 (  6.038535)
+50000 1500 celluloid   20.000000  11.680000  31.680000 ( 29.590774) (1)
+
+ +

Note (1): Celluloid is using thread per actor so this bench is creating about 1500 +native threads. Actor is using constant number of threads.

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: Behaviour, InternalDelegations, PublicDelegations, TypeCheck, Utils + + + + Classes: AbstractContext, ActorTerminated, Context, Core, DefaultDeadLetterHandler, Envelope, Reference, RestartingContext, Root, UnknownMessage + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
Error = +
+
+ + +
+
+
+ + +
+
+
Class.new(StandardError)
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .currentReference, nil + + + + + +

+
+

Returns current executing actor if any.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Reference, nil) + + + + — +

    current executing actor if any

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+33
+34
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor.rb', line 33
+
+def self.current
+  Thread.current[:__current_actor__]
+end
+
+
+ +
+

+ + .rootundocumented + + + + + +

+
+

A root actor, a default parent of all actors spawned outside an actor

+ + +
+
+
+ + +
+ + + + +
+
+
+
+48
+49
+50
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor.rb', line 48
+
+def self.root
+  @root.value!
+end
+
+
+ +
+

+ + .spawn(*args, &block) ⇒ Reference + + + + + +

+
+

Spawns a new actor. Concurrent::Actor::AbstractContext.spawn allows to omit class parameter. +To see the list of available options see Concurrent::Actor::Core#initialize

+ + +
+
+
+ +
+

Examples:

+ + +

by class and name

+

+ +
Actor.spawn(AdHoc, :ping1) { -> message { message } }
+ + +

by option hash

+

+ +
inc2 = Actor.spawn(class:    AdHoc,
+                   name:     'increment by 2',
+                   args:     [2],
+                   executor: Concurrent.global_io_executor) do |increment_by|
+  lambda { |number| number + increment_by }
+end
+inc2.ask!(2) # => 4
+ +
+

Parameters:

+
    + +
  • + + block + + + + + + + — +

    for context_class instantiation

    +
    + +
  • + +
  • + + args + + + + + + + — + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Reference) + + + + — +

    never the actual actor

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor.rb', line 71
+
+def self.spawn(*args, &block)
+  options = to_spawn_options(*args)
+  if options[:executor] && options[:executor].is_a?(ImmediateExecutor)
+    raise ArgumentError, 'ImmediateExecutor is not supported'
+  end
+  if Actor.current
+    Core.new(options.merge(parent: Actor.current), &block).reference
+  else
+    root.ask([:spawn, options, block]).value!
+  end
+end
+
+
+ +
+

+ + .spawn!(*args, &block) ⇒ undocumented + + + + + +

+
+

as spawn but it'll block until actor is initialized or it'll raise exception on error

+ + +
+
+
+ + +
+ + + + +
+
+
+
+84
+85
+86
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor.rb', line 84
+
+def self.spawn!(*args, &block)
+  spawn(to_spawn_options(*args).merge(initialized: future = Concurrent::Promises.resolvable_future), &block).tap { future.wait! }
+end
+
+
+ +
+

+ + + .to_spawn_options(context_class, name, *args) ⇒ undocumented + + .to_spawn_options(opts) ⇒ undocumented + + + + + + +

+
+ + +
+
+
+ +

Overloads:

+
    + + +
  • + .to_spawn_options(context_class, name, *args) ⇒ undocumented +
    +
    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + context_class + + + (AbstractContext) + + + + — +

      to be spawned

      +
      + +
    • + +
    • + + name + + + (String, Symbol) + + + + — +

      of the instance, it's used to generate the +Concurrent::Actor::Core#path of the actor

      +
      + +
    • + +
    • + + args + + + + + + + — +

      for context_class instantiation

      +
      + +
    • + +
    + + +
    +
  • + + +
  • + .to_spawn_options(opts) ⇒ undocumented + +
    + + +
    +
  • + +
+ + +
+ + + + +
+
+
+
+95
+96
+97
+98
+99
+100
+101
+102
+103
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor.rb', line 95
+
+def self.to_spawn_options(*args)
+  if args.size == 1 && args.first.is_a?(::Hash)
+    args.first
+  else
+    { class: args[0],
+      name:  args[1],
+      args:  args[2..-1] }
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/AbstractContext.html b/docs/1.1.10/Concurrent/Actor/AbstractContext.html new file mode 100644 index 000000000..d9c90db83 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/AbstractContext.html @@ -0,0 +1,2554 @@ + + + + + + + Class: Concurrent::Actor::AbstractContext + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::AbstractContext + Abstract + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
InternalDelegations, TypeCheck
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/context.rb
+
+ +
+ +

Overview

+
+
+ This class is abstract. + +
+

New actor is defined by subclassing RestartingContext, Context and defining its abstract methods. +AbstractContext can be subclassed directly to implement more specific behaviour see Root implementation.

+ + + +

Example of ac actor definition:

+ +

Message = Struct.new :action, :value 
+
+class AnActor < Concurrent::Actor::RestartingContext
+  def initialize(init)
+    @counter = init
+  end
+
+  # override #on_message to define actor's behaviour on message received
+  def on_message(message)
+    case message.action
+    when :add
+      @counter = @counter + message.value
+    when :subtract
+      @counter = @counter - message.value
+    when :value
+      @counter
+    else
+      pass
+    end
+  end
+
+  # set counter to zero when there is an error
+  def on_event(event)
+    if event == :reset
+      @counter = 0 # ignore initial value
+    end
+  end
+end 
+
+an_actor = AnActor.spawn name: 'an_actor', args: 10 
+an_actor << Message.new(:add, 1) << Message.new(:subtract, 2) 
+an_actor.ask!(Message.new(:value, nil))            # => 9
+an_actor << :boo << Message.new(:add, 1) 
+an_actor.ask!(Message.new(:value, nil))            # => 1
+an_actor << :terminate!
+    # => #

+ +

See methods of AbstractContext what else can be tweaked, e.g #default_reference_class

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

Context, RestartingContext, Root

+
+ + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + +
+

Instance Attribute Details

+ + + +
+

+ + #coreundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+28
+29
+30
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 28
+
+def core
+  @core
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .spawn(name_or_opts, *args, &block) ⇒ undocumented + + + + + +

+
+

Behaves as Concurrent::Actor.spawn but :class is auto-inserted based on receiver so it can be omitted.

+ + +
+
+
+ +
+

Examples:

+ + +

by class and name

+

+ +
AdHoc.spawn(:ping1) { -> message { message } }
+ + +

by option hash

+

+ +
inc2 = AdHoc.spawn(name:     'increment by 2',
+                   args:     [2],
+                   executor: Concurrent.configuration.global_task_pool) do |increment_by|
+  lambda { |number| number + increment_by }
+end
+inc2.ask!(2) # => 4
+ +
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+115
+116
+117
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 115
+
+def self.spawn(name_or_opts, *args, &block)
+  Actor.spawn to_spawn_options(name_or_opts, *args), &block
+end
+
+
+ +
+

+ + .spawn!(name_or_opts, *args, &block) ⇒ undocumented + + + + + +

+
+

behaves as Concurrent::Actor.spawn! but :class is auto-inserted based on receiver so it can be omitted.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+120
+121
+122
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 120
+
+def self.spawn!(name_or_opts, *args, &block)
+  Actor.spawn! to_spawn_options(name_or_opts, *args), &block
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #ask(message) ⇒ undocumented + + + + Also known as: + ask! + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+96
+97
+98
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 96
+
+def ask(message)
+  raise 'actor cannot ask itself'
+end
+
+
+ +
+

+ + #behaviour_definitionArray<Array(Behavior::Abstract, Array<Object>)> + + + + + +

+
+ + +
+
+
+ +

Returns:

+ +

Raises:

+
    + +
  • + + + (NotImplementedError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+70
+71
+72
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 70
+
+def behaviour_definition
+  raise NotImplementedError
+end
+
+
+ +
+

+ + #dead_letter_routingReference + + + + + +

+
+

Defines an actor responsible for dead letters. Any rejected message send +with Reference#tell is sent there, a message with future is considered +already monitored for failures. Default behaviour is to use +#dead_letter_routing of the parent, so if no +#dead_letter_routing method is overridden in +parent-chain the message ends up in Actor.root.dead_letter_routing +agent which will log warning.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+65
+66
+67
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 65
+
+def dead_letter_routing
+  parent.dead_letter_routing
+end
+
+
+ +
+

+ + #default_executorExecutor + + + + + +

+
+

override to se different default executor, e.g. to change it to global_operation_pool

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Executor) + + + +
  • + +
+ +
+ + + + +
+
+
+
+87
+88
+89
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 87
+
+def default_executor
+  Concurrent.global_io_executor
+end
+
+
+ +
+

+ + #default_reference_classCLass + + + + + +

+
+

override if different class for reference is needed

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (CLass) + + + + — +

    descendant of Reference

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+81
+82
+83
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 81
+
+def default_reference_class
+  Reference
+end
+
+
+ +
+

+ + #envelopeEnvelope + + + + + +

+
+

Returns current envelope, accessible inside #on_message processing.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Envelope) + + + + — +

    current envelope, accessible inside #on_message processing

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+75
+76
+77
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 75
+
+def envelope
+  @envelope or raise 'envelope not set'
+end
+
+
+ +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+ + +
+
+
+ + +
+ + + + +
+
+
+
+44
+45
+46
+47
+48
+49
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 44
+
+def on_envelope(envelope)
+  @envelope = envelope
+  on_message envelope.message
+ensure
+  @envelope = nil
+end
+
+
+ +
+

+ + #on_event(event) ⇒ undocumented + + + + + +

+
+

override to add custom code invocation on internal events like :terminated, :resumed, anError.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+40
+41
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 40
+
+def on_event(event)
+end
+
+
+ +
+

+ + #on_message(message) ⇒ Object + + + + + +

+
+
+ This method is abstract. +

override to define Actor's behaviour

+
+
+ +
+ Note: +

self should not be returned (or sent to other actors), PublicDelegations#reference should be used +instead

+
+
+ +

Returns a result which will be used to set the Future supplied to Reference#ask.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    a result which will be used to set the Future supplied to Reference#ask

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NotImplementedError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 35
+
+def on_message(message)
+  raise NotImplementedError
+end
+
+
+ +
+

+ + #passundocumented + + + + + +

+
+

if you want to pass the message to next behaviour, usually +Behaviour::ErrorsOnUnknownMessage

+ + +
+
+
+ + +
+ + + + +
+
+
+
+53
+54
+55
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 53
+
+def pass
+  core.behaviour!(Behaviour::ExecutesContext).pass envelope
+end
+
+
+ +
+

+ + #tell(message) ⇒ undocumented + + + + Also known as: + << + + + + +

+
+

tell self a message

+ + +
+
+
+ + +
+ + + + +
+
+
+
+92
+93
+94
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 92
+
+def tell(message)
+  reference.tell message
+end
+
+
+ +
+

+ + #behaviour(behaviour_class) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+

see Core#behaviour

+ + +
+
+
+ + +
+
+ +
+

+ + #behaviour!(behaviour_class) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+

see Core#behaviour!

+ + +
+
+
+ + +
+
+ +
+

+ + #Child!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Child?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #childrenundocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #contextAbstractContext + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ +

Returns:

+ + +
+
+ +
+

+ + #context_classundocumented + + + + Also known as: + actor_class + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #executorundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #log(level, message = nil, &block) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+

delegates to core.log

+ + +
+
+
+ + +

See Also:

+
    + +
  • Logging#log
  • + +
+ +
+
+ +
+

+ + #Match!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Match?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #nameundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #parentundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #pathundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #redirect(reference, envelope = self.envelope) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #referenceundocumented + + + + Also known as: + ref + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #terminate!(reason = nil) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+
    + +
  • Termination#terminate!
  • + +
+ +
+
+ +
+

+ + #terminated?Boolean + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +

See Also:

+
    + +
  • Termination#terminated?
  • + +
+ +
+
+ +
+

+ + #Type!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Type?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/ActorTerminated.html b/docs/1.1.10/Concurrent/Actor/ActorTerminated.html new file mode 100644 index 000000000..2ce134fb7 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/ActorTerminated.html @@ -0,0 +1,669 @@ + + + + + + + Class: Concurrent::Actor::ActorTerminated + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::ActorTerminated + + + +

+
+ +
+
Inherits:
+
+ Error + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
TypeCheck
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/errors.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(reference) ⇒ ActorTerminated + + + + + +

+
+

Returns a new instance of ActorTerminated.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+10
+11
+12
+13
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/errors.rb', line 10
+
+def initialize(reference)
+  @reference = Type! reference, Reference
+  super reference.path
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #referenceundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+8
+9
+10
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/errors.rb', line 8
+
+def reference
+  @reference
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #Child!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Child?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #Match!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Match?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #Type!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Type?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour.html b/docs/1.1.10/Concurrent/Actor/Behaviour.html new file mode 100644 index 000000000..12b212edc --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour.html @@ -0,0 +1,830 @@ + + + + + + + Module: Concurrent::Actor::Behaviour + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Actor::Behaviour + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb,
+ lib/concurrent-ruby-edge/concurrent/actor/behaviour/awaits.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/supervising.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/sets_results.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/removes_child.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/executes_context.rb,
lib/concurrent-ruby-edge/concurrent/actor/behaviour/errors_on_unknown_message.rb
+
+
+ +
+ +

Overview

+
+

Actors have modular architecture, which is achieved by combining a light core with chain of +behaviours. Each message or internal event propagates through the chain allowing the +behaviours react based on their responsibility.

+ +
    +
  • Linking:

    + +
    +

    Links the actor to other actors and sends actor's events to them, +like: :terminated, :paused, :resumed, errors, etc. +Linked actor needs to handle those messages.

    + +
    listener = AdHoc.spawn name: :listener do
    +  lambda do |message|
    +    case message
    +    when Reference
    +      if message.ask!(:linked?)
    +        message << :unlink
    +      else
    +        message << :link
    +      end
    +    else
    +      puts "got event #{message.inspect} from #{envelope.sender}"
    +    end
    +  end
    +end
    +
    +an_actor = AdHoc.spawn name: :an_actor, supervise: true, behaviour_definition: Behaviour.restarting_behaviour_definition do
    +  lambda { |message| raise 'failed'}
    +end
    +
    +# link the actor
    +listener.ask(an_actor).wait
    +an_actor.ask(:fail).wait
    +# unlink the actor
    +listener.ask(an_actor).wait
    +an_actor.ask(:fail).wait
    +an_actor << :terminate!
    +
    + +

    produces only two events, other events happened after unlinking

    + +
    got event #<RuntimeError: failed> from #<Concurrent::Actor::Reference /an_actor (Concurrent::Actor::Utils::AdHoc)>
    +got event :reset from #<Concurrent::Actor::Reference /an_actor (Concurrent::Actor::Utils::AdHoc)>
    +
    +

    +
  • +
  • Awaits:

    + +
    +

    Accepts :await messages. Which allows to wait on Actor to process all previously send +messages.

    + +
    actor << :a << :b
    +actor.ask(:await).wait # blocks until :a and :b are processed
    +
    +

    +
  • +
  • Pausing:

    + +
    +

    Allows to pause actors on errors. +When paused all arriving messages are collected and processed after the actor +is resumed or reset. Resume will simply continue with next message. +Reset also reinitialized context.

    +
  • +
  • Supervising:

    + +
    +

    Handles supervised actors. Handle configures what to do with failed child: :terminate!, :resume!, :reset!, +or :restart!. Strategy sets :one_for_one (restarts just failed actor) or :one_for_all (restarts all child actors).

    +
  • +
  • Supervising:

    + +
    +

    Handles supervised actors. Handle configures what to do with failed child: :terminate!, :resume!, :reset!, +or :restart!. Strategy sets :one_for_one (restarts just failed actor) or :one_for_all (restarts all child actors).

    +
  • +
  • ExecutesContext:

    + +
    +

    Delegates messages and events to AbstractContext instance.

    +
  • +
  • ErrorsOnUnknownMessage:

    + +
    +

    Simply fails when message arrives here. It's usually the last behaviour.

    +
  • +
  • Termination:

    + +
    +

    Handles actor termination. Waits until all its children are terminated, +can be configured on behaviour initialization.

    +
  • +
  • RemovesChild:

    + +
    +

    Removes terminated children.

    +
  • +
+ +

If needed new behaviours can be added, or old one removed to get required behaviour.

+ + + + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: Abstract, Awaits, Buffer, ErrorsOnUnknownMessage, ExecutesContext, Linking, Pausing, RemovesChild, SetResults, Supervising, Termination + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
MESSAGE_PROCESSED = +
+
+ + +
+
+
+ + +
+
+
::Object.new
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .base(on_error) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+
    + +
  • its source code
  • + +
+ +
+ + + + +
+
+
+
+105
+106
+107
+108
+109
+110
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb', line 105
+
+def self.base(on_error)
+  [[SetResults, on_error],
+   # has to be before Termination to be able to remove children from terminated actor
+   RemovesChild,
+   Termination]
+end
+
+
+ +
+

+ + .basic_behaviour_definitionundocumented + + + + + +

+
+

Array of behaviours and their construction parameters.

+ +
[[Behaviour::SetResults, :terminate!],
+ [Behaviour::RemovesChild],
+ [Behaviour::Termination],
+ [Behaviour::Linking],
+ [Behaviour::Awaits],
+ [Behaviour::ExecutesContext],
+ [Behaviour::ErrorsOnUnknownMessage]]
+
+ + +
+
+
+ + +

See Also:

+
    + +
  • its source code
  • + +
+ +
+ + + + +
+
+
+
+77
+78
+79
+80
+81
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb', line 77
+
+def self.basic_behaviour_definition
+  [*base(:terminate!),
+   *linking,
+   *user_messages]
+end
+
+
+ +
+

+ + .linkingundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+
    + +
  • its source code
  • + +
+ +
+ + + + +
+
+
+
+113
+114
+115
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb', line 113
+
+def self.linking
+  [Linking]
+end
+
+
+ +
+

+ + .restarting_behaviour_definition(handle = :reset!, strategy = :one_for_one) ⇒ undocumented + + + + + +

+
+

Array of behaviours and their construction parameters.

+ +
[[Behaviour::SetResults, :pause!],
+ [Behaviour::RemovesChild],
+ [Behaviour::Termination],
+ [Behaviour::Linking],
+ [Behaviour::Pausing],
+ [Behaviour::Supervising, :reset!, :one_for_one],
+ [Behaviour::Awaits],
+ [Behaviour::ExecutesContext],
+ [Behaviour::ErrorsOnUnknownMessage]]
+
+ + +
+
+
+ + +

See Also:

+
    + +
  • its source code
  • + +
+ +
+ + + + +
+
+
+
+96
+97
+98
+99
+100
+101
+102
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb', line 96
+
+def self.restarting_behaviour_definition(handle = :reset!, strategy = :one_for_one)
+  [*base(:pause!),
+   *linking,
+   *supervised,
+   *supervising(handle, strategy),
+   *user_messages]
+end
+
+
+ +
+

+ + .supervisedundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+
    + +
  • its source code
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb', line 118
+
+def self.supervised
+  [Pausing]
+end
+
+
+ +
+

+ + .supervising(handle = :reset!, strategy = :one_for_one) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+
    + +
  • its source code
  • + +
+ +
+ + + + +
+
+
+
+123
+124
+125
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb', line 123
+
+def self.supervising(handle = :reset!, strategy = :one_for_one)
+  [[Behaviour::Supervising, handle, strategy]]
+end
+
+
+ +
+

+ + .user_messagesundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+
    + +
  • its source code
  • + +
+ +
+ + + + +
+
+
+
+128
+129
+130
+131
+132
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour.rb', line 128
+
+def self.user_messages
+  [Awaits,
+   ExecutesContext,
+   ErrorsOnUnknownMessage]
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/Abstract.html b/docs/1.1.10/Concurrent/Actor/Behaviour/Abstract.html new file mode 100644 index 000000000..fe70bcf9e --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/Abstract.html @@ -0,0 +1,2019 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::Abstract + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::Abstract + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
InternalDelegations, TypeCheck
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(core, subsequent, core_options) ⇒ Abstract + + + + + +

+
+

Returns a new instance of Abstract.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb', line 12
+
+def initialize(core, subsequent, core_options)
+  @core       = Type! core, Core
+  @subsequent = Type! subsequent, Abstract, NilClass
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #coreundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+10
+11
+12
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb', line 10
+
+def core
+  @core
+end
+
+
+ + + +
+

+ + #subsequentundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+10
+11
+12
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb', line 10
+
+def subsequent
+  @subsequent
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #broadcast(public, event) ⇒ undocumented + + + + + +

+
+

broadcasts event to all behaviours and context

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+37
+38
+39
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb', line 37
+
+def broadcast(public, event)
+  core.broadcast(public, event)
+end
+
+
+ +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ +
+ Note: +

super needs to be called not to break the chain

+
+
+ +

override to add extra behaviour

+ + +
+
+
+ + +
+ + + + +
+
+
+
+19
+20
+21
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb', line 19
+
+def on_envelope(envelope)
+  pass envelope
+end
+
+
+ +
+

+ + #on_event(public, event) ⇒ undocumented + + + + + +

+
+ +
+ Note: +

super needs to be called not to break the chain

+
+
+ +

override to add extra behaviour

+ + +
+
+
+ + +
+ + + + +
+
+
+
+30
+31
+32
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb', line 30
+
+def on_event(public, event)
+  subsequent.on_event public, event if subsequent
+end
+
+
+ +
+

+ + #pass(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+

Parameters:

+ + + +
+ + + + +
+
+
+
+24
+25
+26
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb', line 24
+
+def pass(envelope)
+  subsequent.on_envelope envelope
+end
+
+
+ +
+

+ + #reject_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+41
+42
+43
+44
+45
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/abstract.rb', line 41
+
+def reject_envelope(envelope)
+  envelope.reject! ActorTerminated.new(reference)
+  dead_letter_routing << envelope unless envelope.future
+  log(DEBUG) { "rejected #{envelope.message} from #{envelope.sender_path}"}
+end
+
+
+ +
+

+ + #behaviour(behaviour_class) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+

see Core#behaviour

+ + +
+
+
+ + +
+
+ +
+

+ + #behaviour!(behaviour_class) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+

see Core#behaviour!

+ + +
+
+
+ + +
+
+ +
+

+ + #Child!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Child?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #childrenundocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #contextAbstractContext + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ +

Returns:

+ + +
+
+ +
+

+ + #context_classundocumented + + + + Also known as: + actor_class + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #dead_letter_routingundocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #executorundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #log(level, message = nil, &block) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+

delegates to core.log

+ + +
+
+
+ + +

See Also:

+
    + +
  • Logging#log
  • + +
+ +
+
+ +
+

+ + #Match!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Match?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #nameundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #parentundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #pathundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #redirect(reference, envelope = self.envelope) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #referenceundocumented + + + + Also known as: + ref + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #terminate!(reason = nil) ⇒ undocumented + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+
    + +
  • Termination#terminate!
  • + +
+ +
+
+ +
+

+ + #terminated?Boolean + + + + + + + Originally defined in module + InternalDelegations + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +

See Also:

+
    + +
  • Termination#terminated?
  • + +
+ +
+
+ +
+

+ + #Type!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Type?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/Awaits.html b/docs/1.1.10/Concurrent/Actor/Behaviour/Awaits.html new file mode 100644 index 000000000..287a34b17 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/Awaits.html @@ -0,0 +1,248 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::Awaits + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::Awaits + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/awaits.rb
+
+ +
+ +

Overview

+
+

Accepts :await messages. Which allows to wait on Actor to process all previously send +messages.

+ +
actor << :a << :b
+actor.ask(:await).wait # blocks until :a and :b are processed
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Actor::Behaviour::Abstract

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+11
+12
+13
+14
+15
+16
+17
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/awaits.rb', line 11
+
+def on_envelope(envelope)
+  if envelope.message == :await
+    true
+  else
+    pass envelope
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/Buffer.html b/docs/1.1.10/Concurrent/Actor/Behaviour/Buffer.html new file mode 100644 index 000000000..b541654df --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/Buffer.html @@ -0,0 +1,540 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::Buffer + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::Buffer + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb
+
+ +
+ +

Overview

+
+

Any message reaching this behaviour is buffered. Only one message is is +scheduled at any given time. Others are kept in buffer until another one +can be scheduled. This effectively means that messages handled by +behaviours before buffer have higher priority and they can be processed +before messages arriving into buffer. This allows for the processing of +internal actor messages like (:link, :supervise) first.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(core, subsequent, core_options) ⇒ Buffer + + + + + +

+
+

Returns a new instance of Buffer.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+16
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb', line 12
+
+def initialize(core, subsequent, core_options)
+  super core, subsequent, core_options
+  @buffer                     = []
+  @receive_envelope_scheduled = false
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+18
+19
+20
+21
+22
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb', line 18
+
+def on_envelope(envelope)
+  @buffer.push envelope
+  process_envelopes?
+  MESSAGE_PROCESSED
+end
+
+
+ +
+

+ + #on_event(public, event) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+44
+45
+46
+47
+48
+49
+50
+51
+52
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb', line 44
+
+def on_event(public, event)
+  event_name, _ = event
+  case event_name
+  when :terminated, :restarted
+    @buffer.each { |envelope| reject_envelope envelope }
+    @buffer.clear
+  end
+  super public, event_name
+end
+
+
+ +
+

+ + #process_envelopeundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+35
+36
+37
+38
+39
+40
+41
+42
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb', line 35
+
+def process_envelope
+  envelope = @buffer.shift
+  return nil unless envelope
+  pass envelope
+ensure
+  @receive_envelope_scheduled = false
+  core.schedule_execution { process_envelopes? }
+end
+
+
+ +
+

+ + #process_envelopes?Boolean + + + + + +

+
+

Ensures that only one envelope processing is scheduled with #schedule_execution, +this allows other scheduled blocks to be executed before next envelope processing. +Simply put this ensures that Core is still responsive to internal calls (like add_child) +even though the Actor is flooded with messages.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+28
+29
+30
+31
+32
+33
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/buffer.rb', line 28
+
+def process_envelopes?
+  unless @buffer.empty? || @receive_envelope_scheduled
+    @receive_envelope_scheduled = true
+    process_envelope
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/ErrorsOnUnknownMessage.html b/docs/1.1.10/Concurrent/Actor/Behaviour/ErrorsOnUnknownMessage.html new file mode 100644 index 000000000..ff4cdb015 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/ErrorsOnUnknownMessage.html @@ -0,0 +1,248 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::ErrorsOnUnknownMessage + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::ErrorsOnUnknownMessage + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/errors_on_unknown_message.rb
+
+ +
+ +

Overview

+
+

Simply fails when message arrives here. It's usually the last behaviour.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Actor::Behaviour::Abstract

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/errors_on_unknown_message.rb', line 6
+
+def on_envelope(envelope)
+  raise UnknownMessage, envelope
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/ExecutesContext.html b/docs/1.1.10/Concurrent/Actor/Behaviour/ExecutesContext.html new file mode 100644 index 000000000..0af49dd12 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/ExecutesContext.html @@ -0,0 +1,298 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::ExecutesContext + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::ExecutesContext + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/executes_context.rb
+
+ +
+ +

Overview

+
+

Delegates messages and events to AbstractContext instance.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Actor::Behaviour::Abstract

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/executes_context.rb', line 6
+
+def on_envelope(envelope)
+  context.on_envelope envelope
+end
+
+
+ +
+

+ + #on_event(public, event) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+10
+11
+12
+13
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/executes_context.rb', line 10
+
+def on_event(public, event)
+  context.on_event(event)
+  super public, event
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/Linking.html b/docs/1.1.10/Concurrent/Actor/Behaviour/Linking.html new file mode 100644 index 000000000..fe2e6fcab --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/Linking.html @@ -0,0 +1,553 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::Linking + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::Linking + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb
+
+ +
+ +

Overview

+
+

Links the actor to other actors and sends actor's events to them, +like: :terminated, :paused, :resumed, errors, etc. +Linked actor needs to handle those messages.

+ +
listener = AdHoc.spawn name: :listener do
+  lambda do |message|
+    case message
+    when Reference
+      if message.ask!(:linked?)
+        message << :unlink
+      else
+        message << :link
+      end
+    else
+      puts "got event #{message.inspect} from #{envelope.sender}"
+    end
+  end
+end
+
+an_actor = AdHoc.spawn name: :an_actor, supervise: true, behaviour_definition: Behaviour.restarting_behaviour_definition do
+  lambda { |message| raise 'failed'}
+end
+
+# link the actor
+listener.ask(an_actor).wait
+an_actor.ask(:fail).wait
+# unlink the actor
+listener.ask(an_actor).wait
+an_actor.ask(:fail).wait
+an_actor << :terminate!
+
+ +

produces only two events, other events happened after unlinking

+ +
got event #<RuntimeError: failed> from #<Concurrent::Actor::Reference /an_actor (Concurrent::Actor::Utils::AdHoc)>
+got event :reset from #<Concurrent::Actor::Reference /an_actor (Concurrent::Actor::Utils::AdHoc)>
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(core, subsequent, core_options) ⇒ Linking + + + + + +

+
+

Returns a new instance of Linking.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+43
+44
+45
+46
+47
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 43
+
+def initialize(core, subsequent, core_options)
+  super core, subsequent, core_options
+  @linked = Set.new
+  @linked.add Actor.current if core_options[:link] != false
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+
+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+64
+65
+66
+67
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 64
+
+def link(ref)
+  @linked.add(ref)
+  true
+end
+
+
+ +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 49
+
+def on_envelope(envelope)
+  case envelope.message
+  when :link
+    link envelope.sender
+  when :unlink
+    unlink envelope.sender
+  when :linked?
+    @linked.include? envelope.sender
+  when :linked
+    @linked.to_a
+  else
+    pass envelope
+  end
+end
+
+
+ +
+

+ + #on_event(public, event) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+74
+75
+76
+77
+78
+79
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 74
+
+def on_event(public, event)
+  event_name, _ = event
+  @linked.each { |a| a << event } if public
+  @linked.clear if event_name == :terminated
+  super public, event
+end
+
+
+ +
+
+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+69
+70
+71
+72
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 69
+
+def unlink(ref)
+  @linked.delete(ref)
+  true
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/Pausing.html b/docs/1.1.10/Concurrent/Actor/Behaviour/Pausing.html new file mode 100644 index 000000000..d3f01b8fb --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/Pausing.html @@ -0,0 +1,757 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::Pausing + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::Pausing + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

TODO missing example

+
+
+ +

Allows to pause actors on errors. +When paused all arriving messages are collected and processed after the actor +is resumed or reset. Resume will simply continue with next message. +Reset also reinitialized context.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(core, subsequent, core_options) ⇒ Pausing + + + + + +

+
+

Returns a new instance of Pausing.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+11
+12
+13
+14
+15
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb', line 11
+
+def initialize(core, subsequent, core_options)
+  super core, subsequent, core_options
+  @paused   = false
+  @deferred = []
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb', line 21
+
+def on_envelope(envelope)
+  case envelope.message
+  when :pause!
+    pause!
+  when :paused?
+    paused?
+  when :resume!
+    resume!
+  when :reset!
+    reset!
+  when :restart!
+    restart!
+  else
+    if paused?
+      @deferred << envelope
+      MESSAGE_PROCESSED
+    else
+      pass envelope
+    end
+  end
+end
+
+
+ +
+

+ + #on_event(public, event) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+72
+73
+74
+75
+76
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb', line 72
+
+def on_event(public, event)
+  event_name, _ = event
+  reject_deferred if event_name == :terminated
+  super public, event
+end
+
+
+ +
+

+ + #pause!(error = nil) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+43
+44
+45
+46
+47
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb', line 43
+
+def pause!(error = nil)
+  do_pause
+  broadcast true, error || :paused
+  true
+end
+
+
+ +
+

+ + #paused?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb', line 17
+
+def paused?
+  @paused
+end
+
+
+ +
+

+ + #reset!undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb', line 56
+
+def reset!
+  return false unless paused?
+  broadcast(false, :resetting)
+  do_reset
+  broadcast(true, :reset)
+  true
+end
+
+
+ +
+

+ + #restart!undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+64
+65
+66
+67
+68
+69
+70
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb', line 64
+
+def restart!
+  return false unless paused?
+  broadcast(false, :restarting)
+  do_restart
+  broadcast(true, :restarted)
+  true
+end
+
+
+ +
+

+ + #resume!undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+49
+50
+51
+52
+53
+54
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/pausing.rb', line 49
+
+def resume!
+  return false unless paused?
+  do_resume
+  broadcast(true, :resumed)
+  true
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/RemovesChild.html b/docs/1.1.10/Concurrent/Actor/Behaviour/RemovesChild.html new file mode 100644 index 000000000..8125c1b56 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/RemovesChild.html @@ -0,0 +1,243 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::RemovesChild + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::RemovesChild + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/removes_child.rb
+
+ +
+ +

Overview

+
+

Removes terminated children.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Actor::Behaviour::Abstract

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+9
+10
+11
+12
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/removes_child.rb', line 6
+
+def on_envelope(envelope)
+  if envelope.message == :remove_child
+    core.remove_child envelope.sender
+  else
+    pass envelope
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/SetResults.html b/docs/1.1.10/Concurrent/Actor/Behaviour/SetResults.html new file mode 100644 index 000000000..31456d57b --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/SetResults.html @@ -0,0 +1,414 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::SetResults + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::SetResults + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/sets_results.rb
+
+ +
+ +

Overview

+
+

Collects returning value and sets the ResolvableFuture in the Envelope or error on failure.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(core, subsequent, core_options, error_strategy) ⇒ SetResults + + + + + +

+
+

Returns a new instance of SetResults.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+8
+9
+10
+11
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/sets_results.rb', line 8
+
+def initialize(core, subsequent, core_options, error_strategy)
+  super core, subsequent, core_options
+  @error_strategy = Match! error_strategy, :just_log, :terminate!, :pause!
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #error_strategyundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/sets_results.rb', line 6
+
+def error_strategy
+  @error_strategy
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/sets_results.rb', line 13
+
+def on_envelope(envelope)
+  result = pass envelope
+  if result != MESSAGE_PROCESSED && !envelope.future.nil?
+    envelope.future.fulfill result
+    log(DEBUG) { "finished processing of #{envelope.message.inspect}"}
+  end
+  nil
+rescue => error
+  log ERROR, error
+  case error_strategy
+  when :terminate!
+    terminate!
+  when :pause!
+    behaviour!(Pausing).pause!(error)
+  when :just_log
+    # nothing
+  else
+    raise
+  end
+  envelope.future.reject error unless envelope.future.nil?
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/Supervising.html b/docs/1.1.10/Concurrent/Actor/Behaviour/Supervising.html new file mode 100644 index 000000000..a232b507c --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/Supervising.html @@ -0,0 +1,350 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::Supervising + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::Supervising + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/supervising.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

TODO missing example

+
+
+ +
+ Note: +

this will change in next version to support supervision trees better

+
+
+ +

Handles supervised actors. Handle configures what to do with failed child: :terminate!, :resume!, :reset!, +or :restart!. Strategy sets :one_for_one (restarts just failed actor) or :one_for_all (restarts all child actors).

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(core, subsequent, core_options, handle, strategy) ⇒ Supervising + + + + + +

+
+

Returns a new instance of Supervising.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/supervising.rb', line 10
+
+def initialize(core, subsequent, core_options, handle, strategy)
+  super core, subsequent, core_options
+  @handle   = Match! handle, :terminate!, :resume!, :reset!, :restart!
+  @strategy = case @handle
+              when :terminate!
+                Match! strategy, nil
+              when :resume!
+                Match! strategy, :one_for_one
+              when :reset!, :restart!
+                Match! strategy, :one_for_one, :one_for_all
+              end
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/supervising.rb', line 23
+
+def on_envelope(envelope)
+  case envelope.message
+  when Exception, :paused
+    receivers = if @strategy == :one_for_all
+                  children
+                else
+                  [envelope.sender]
+                end
+    receivers.each { |ch| ch << @handle }
+  else
+    pass envelope
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Behaviour/Termination.html b/docs/1.1.10/Concurrent/Actor/Behaviour/Termination.html new file mode 100644 index 000000000..149614553 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Behaviour/Termination.html @@ -0,0 +1,756 @@ + + + + + + + Class: Concurrent::Actor::Behaviour::Termination + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Behaviour::Termination + + + +

+
+ +
+
Inherits:
+
+ Abstract + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Actor rejects envelopes when terminated.

+
+
+ +
+ Note: +

TODO missing example

+
+
+ +

Handles actor termination. Waits until all its children are terminated, +can be configured on behaviour initialization.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(core, subsequent, core_options, trapping = false, terminate_children = true) ⇒ Termination + + + + + +

+
+

Returns a new instance of Termination.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb', line 15
+
+def initialize(core, subsequent, core_options, trapping = false, terminate_children = true)
+  super core, subsequent, core_options
+  @terminated         = Concurrent::Promises.resolvable_future
+  @public_terminated  = @terminated.with_hidden_resolvable
+  @trapping           = trapping
+  @terminate_children = terminate_children
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #terminatedundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+13
+14
+15
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb', line 13
+
+def terminated
+  @terminated
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb', line 37
+
+def on_envelope(envelope)
+  command, reason = envelope.message
+  case command
+  when :terminated?
+    terminated?
+  when :terminate!
+    if trapping? && reason != :kill
+      pass envelope
+    else
+      terminate! reason, envelope
+    end
+  when :termination_event
+    @public_terminated
+  else
+    if terminated?
+      reject_envelope envelope
+      MESSAGE_PROCESSED
+    else
+      pass envelope
+    end
+  end
+end
+
+
+ +
+

+ + #terminate!(reason = nil, envelope = nil) ⇒ undocumented + + + + + +

+
+

Terminates the actor. Any Envelope received after termination is rejected. +Terminates all its children, does not wait until they are terminated.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb', line 62
+
+def terminate!(reason = nil, envelope = nil)
+  return true if terminated?
+
+  self_termination = Concurrent::Promises.resolved_future(reason.nil?, reason.nil? || nil, reason)
+  all_terminations = if @terminate_children
+                       Concurrent::Promises.zip(*children.map { |ch| ch.ask(:terminate!) }, self_termination)
+                     else
+                       self_termination
+                     end
+
+  all_terminations.chain_resolvable(@terminated)
+  if envelope && envelope.future
+    all_terminations.chain { |fulfilled, _, t_reason| envelope.future.resolve fulfilled, true, t_reason }
+  end
+
+  broadcast(true, [:terminated, reason]) # TODO do not end up in Dead Letter Router
+  parent << :remove_child if parent
+
+  MESSAGE_PROCESSED
+end
+
+
+ +
+

+ + #terminated?true, false + + + + + +

+
+ +
+ Note: +

Actor rejects envelopes when terminated.

+
+
+ +

Returns if actor is terminated.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    if actor is terminated

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb', line 25
+
+def terminated?
+  @terminated.resolved?
+end
+
+
+ +
+

+ + #trapping=(val) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+33
+34
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb', line 33
+
+def trapping=(val)
+  @trapping = !!val
+end
+
+
+ +
+

+ + #trapping?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+29
+30
+31
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/termination.rb', line 29
+
+def trapping?
+  @trapping
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Context.html b/docs/1.1.10/Concurrent/Actor/Context.html new file mode 100644 index 000000000..b9a59a6cc --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Context.html @@ -0,0 +1,239 @@ + + + + + + + Class: Concurrent::Actor::Context + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Context + Abstract + + +

+
+ +
+
Inherits:
+
+ AbstractContext + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/context.rb
+
+ +
+ +

Overview

+
+
+ This class is abstract. + +
+

Basic Context of an Actor. It supports only linking and it simply terminates on error. +Uses Behaviour.basic_behaviour_definition:

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

Utils::AdHoc

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #behaviour_definitionundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+151
+152
+153
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 151
+
+def behaviour_definition
+  Behaviour.basic_behaviour_definition
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Core.html b/docs/1.1.10/Concurrent/Actor/Core.html new file mode 100644 index 000000000..724aa38ad --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Core.html @@ -0,0 +1,2538 @@ + + + + + + + Class: Concurrent::Actor::Core + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Core + + + +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
TypeCheck
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/core.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Whole class should be considered private. An user should use Contexts and References only.

+
+
+ +
+ Note: +

devel: core should not block on anything, e.g. it cannot wait on children to terminate +that would eat up all threads in task pool and deadlock

+
+
+ +

Core of the actor.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(opts = {}, &block) ⇒ Core + + + + + +

+
+

Returns a new instance of Core.

+ + +
+
+
+

Parameters:

+
    + +
  • + + block + + + (Proc) + + + + — +

    for class instantiation

    +
    + +
  • + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    a customizable set of options

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + name + (String) + + + + +
  • + +
  • + actor_class + (Context) + + + + + —

    a class to be instantiated defining Actor's behaviour

    +
    + +
  • + +
  • + args + (Array<Object>) + + + + + —

    arguments for actor_class instantiation

    +
    + +
  • + +
  • + executor, + (Executor) + + + + + —

    default is global_io_executor

    +
    + +
  • + +
  • + link, + (true, false) + + + + + —

    atomically link the actor to its parent (default: true)

    +
    + +
  • + +
  • + reference + (Class) + + + + + —

    a custom descendant of Reference to use

    +
    + +
  • + +
  • + behaviour_definition, + (Array<Array(Behavior::Abstract, Array<Object>)>) + + + + + —

    array of pairs +where each pair is behaviour class and its args, see Behaviour.basic_behaviour_definition

    +
    + +
  • + +
  • + initialized, + (ResolvableFuture, nil) + + + + + —

    if present it'll be set or failed after Concurrent::Actor::Context initialization

    +
    + +
  • + +
  • + parent + (Reference, nil) + + + + + —

    private api parent of the actor (the one spawning )

    +
    + +
  • + +
  • + logger + (Proc, nil) + + + + + —

    a proc accepting (level, progname, message = nil, &block) params, +can be used to hook actor instance to any logging system, see Concern::Logging

    +
    + +
  • + +
+ + + + + +
+ + + + +
+
+
+
+50
+51
+52
+53
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 50
+
+def initialize(opts = {}, &block)
+  super(&nil)
+  synchronize { ns_initialize(opts, &block) }
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #actor_classContext (readonly) + + + + + +

+
+

A subclass of AbstractContext representing Actor's behaviour.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
+
+attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
+
+
+ + + +
+

+ + #behaviour_definitionundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
+
+def behaviour_definition
+  @behaviour_definition
+end
+
+
+ + + +
+

+ + #contextundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
+
+def context
+  @context
+end
+
+
+ + + +
+

+ + #context_classundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
+
+def context_class
+  @context_class
+end
+
+
+ + + +
+

+ + #executorExecutor (readonly) + + + + + +

+
+

Executor which is used to process messages.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Executor) + + + +
  • + +
+ +
+ + + + +
+
+
+
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
+
+attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
+
+
+ + + +
+

+ + #nameString (readonly) + + + + + +

+
+

The name of actor instance, it should be uniq (not enforced). Allows easier orientation +between actor instances.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + +
  • + +
+ +
+ + + + +
+
+
+
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
+
+attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
+
+
+ + + +
+

+ + #pathString (readonly) + + + + + +

+
+

Path of this actor. It is used for easier orientation and logging. +Path is constructed recursively with: parent.path + self.name up to a Concurrent::Actor.root, +e.g. /an_actor/its_child.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + +
  • + +
+ +
+ + + + +
+
+
+
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
+
+attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
+
+
+ + + +
+

+ + #referenceReference (readonly) + + + + + +

+
+

Reference to this actor which can be safely passed around.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
+
+def reference
+  @reference
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #add_child(child) ⇒ undocumented + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+ + +
+
+
+ + +
+ + + + +
+
+
+
+74
+75
+76
+77
+78
+79
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 74
+
+def add_child(child)
+  guard!
+  Type! child, Reference
+  @children.add child
+  nil
+end
+
+
+ +
+

+ + #allocate_contextundocumented + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+ + +
+
+
+ + +
+ + + + +
+
+
+
+150
+151
+152
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 150
+
+def allocate_context
+  @context = @context_class.allocate
+end
+
+
+ +
+

+ + #behaviour(behaviour_class) ⇒ Behaviour::Abstract, nil + + + + + +

+
+

Returns based on behaviour_class.

+ + +
+
+
+

Parameters:

+
    + +
  • + + behaviour_class + + + (Class) + + + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+138
+139
+140
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 138
+
+def behaviour(behaviour_class)
+  @behaviours[behaviour_class]
+end
+
+
+ +
+

+ + #behaviour!(behaviour_class) ⇒ Behaviour::Abstract + + + + + +

+
+

Returns based on behaviour_class.

+ + +
+
+
+

Parameters:

+
    + +
  • + + behaviour_class + + + (Class) + + + +
  • + +
+ +

Returns:

+ +

Raises:

+
    + +
  • + + + (KeyError) + + + + — +

    when no behaviour

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+145
+146
+147
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 145
+
+def behaviour!(behaviour_class)
+  @behaviours.fetch behaviour_class
+end
+
+
+ +
+

+ + #broadcast(public, event) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+131
+132
+133
+134
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 131
+
+def broadcast(public, event)
+  log(DEBUG) { "event: #{event.inspect} (#{public ? 'public' : 'private'})" }
+  @first_behaviour.on_event(public, event)
+end
+
+
+ +
+

+ + #build_contextundocumented + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+ + +
+
+
+ + +
+ + + + +
+
+
+
+155
+156
+157
+158
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 155
+
+def build_context
+  @context.send :initialize_core, self
+  @context.send :initialize, *@args, &@block
+end
+
+
+ +
+

+ + #childrenArray<Reference> + + + + + +

+
+

Returns of children actors.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Array<Reference>) + + + + — +

    of children actors

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+68
+69
+70
+71
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 68
+
+def children
+  guard!
+  @children.to_a
+end
+
+
+ +
+

+ + #dead_letter_routingundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+63
+64
+65
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 63
+
+def dead_letter_routing
+  @context.dead_letter_routing
+end
+
+
+ +
+

+ + #guard!undocumented + + + + + +

+
+

ensures that we are inside of the executor

+ + +
+
+
+ + +
+ + + + +
+
+
+
+102
+103
+104
+105
+106
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 102
+
+def guard!
+  unless Actor.current == reference
+    raise "can be called only inside actor #{reference} but was #{Actor.current}"
+  end
+end
+
+
+ +
+

+ + #log(level, message = nil, &block) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+108
+109
+110
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 108
+
+def log(level, message = nil, &block)
+  super level, @path, message, &block
+end
+
+
+ +
+

+ + #on_envelope(envelope) ⇒ undocumented + + + + + +

+
+

is executed by Reference scheduling processing of new messages +can be called from other alternative Reference implementations

+ + +
+
+
+

Parameters:

+
    + +
  • + + envelope + + + (Envelope) + + + +
  • + +
+ + +
+ + + + +
+
+
+
+92
+93
+94
+95
+96
+97
+98
+99
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 92
+
+def on_envelope(envelope)
+  log(DEBUG) { "is  #{envelope.future ? 'asked' : 'told'} #{envelope.message.inspect} by #{envelope.sender}" }
+  schedule_execution do
+    log(DEBUG) { "was #{envelope.future ? 'asked' : 'told'} #{envelope.message.inspect} by #{envelope.sender} - processing" }
+    process_envelope envelope
+  end
+  nil
+end
+
+
+ +
+

+ + #parentReference, nil + + + + + +

+
+

A parent Actor. When actor is spawned the Concurrent::Actor.current becomes its parent. +When actor is spawned from a thread outside of an actor (Concurrent::Actor.current is nil) Concurrent::Actor.root is assigned.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+58
+59
+60
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 58
+
+def parent
+  @parent_core && @parent_core.reference
+end
+
+
+ +
+

+ + #process_envelope(envelope) ⇒ undocumented + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+ + +
+
+
+ + +
+ + + + +
+
+
+
+161
+162
+163
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 161
+
+def process_envelope(envelope)
+  @first_behaviour.on_envelope envelope
+end
+
+
+ +
+

+ + #remove_child(child) ⇒ undocumented + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+ + +
+
+
+ + +
+ + + + +
+
+
+
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 82
+
+def remove_child(child)
+  guard!
+  Type! child, Reference
+  @children.delete child
+  nil
+end
+
+
+ +
+

+ + #schedule_executionundocumented + + + + + +

+
+

Schedules blocks to be executed on executor sequentially, +sets Actress.current

+ + +
+
+
+ + +
+ + + + +
+
+
+
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 114
+
+def schedule_execution
+  @serialized_execution.post(@executor) do
+    synchronize do
+      begin
+        Thread.current[:__current_actor__] = reference
+        yield
+      rescue => e
+        log FATAL, e
+      ensure
+        Thread.current[:__current_actor__] = nil
+      end
+    end
+  end
+
+  nil
+end
+
+
+ +
+

+ + #Child!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Child?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #Match!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Match?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #Type!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Type?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/DefaultDeadLetterHandler.html b/docs/1.1.10/Concurrent/Actor/DefaultDeadLetterHandler.html new file mode 100644 index 000000000..a90662a3a --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/DefaultDeadLetterHandler.html @@ -0,0 +1,232 @@ + + + + + + + Class: Concurrent::Actor::DefaultDeadLetterHandler + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::DefaultDeadLetterHandler + + + +

+
+ +
+
Inherits:
+
+ RestartingContext + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/default_dead_letter_handler.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #on_message(dead_letter) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+4
+5
+6
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/default_dead_letter_handler.rb', line 4
+
+def on_message(dead_letter)
+  log(INFO) { "got dead letter #{dead_letter.inspect}"}
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Envelope.html b/docs/1.1.10/Concurrent/Actor/Envelope.html new file mode 100644 index 000000000..a54892d73 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Envelope.html @@ -0,0 +1,1113 @@ + + + + + + + Class: Concurrent::Actor::Envelope + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Envelope + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
TypeCheck
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/envelope.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(message, future, sender, address) ⇒ Envelope + + + + + +

+
+

Returns a new instance of Envelope.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+17
+18
+19
+20
+21
+22
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/envelope.rb', line 17
+
+def initialize(message, future, sender, address)
+  @message = message
+  @future  = Type! future, Promises::ResolvableFuture, NilClass
+  @sender  = Type! sender, Reference, Thread
+  @address = Type! address, Reference
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #addressundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+15
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/envelope.rb', line 15
+
+attr_reader :message, :future, :sender, :address
+
+
+ + + +
+

+ + #futureEdge::Future (readonly) + + + + + +

+
+

Returns a future which becomes resolved after message is processed.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Edge::Future) + + + + — +

    a future which becomes resolved after message is processed

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+15
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/envelope.rb', line 15
+
+attr_reader :message, :future, :sender, :address
+
+
+ + + +
+

+ + #messageObject (readonly) + + + + + +

+
+

Returns a message.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    a message

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+15
+16
+17
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/envelope.rb', line 15
+
+def message
+  @message
+end
+
+
+ + + +
+

+ + #senderReference, Thread (readonly) + + + + + +

+
+

Returns an actor or thread sending the message.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Reference, Thread) + + + + — +

    an actor or thread sending the message

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+15
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/envelope.rb', line 15
+
+attr_reader :message, :future, :sender, :address
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #address_pathundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+32
+33
+34
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/envelope.rb', line 32
+
+def address_path
+  address.path
+end
+
+
+ +
+

+ + #reject!(error) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+36
+37
+38
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/envelope.rb', line 36
+
+def reject!(error)
+  future.reject error unless future.nil?
+end
+
+
+ +
+

+ + #sender_pathundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+24
+25
+26
+27
+28
+29
+30
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/envelope.rb', line 24
+
+def sender_path
+  if sender.is_a? Reference
+    sender.path
+  else
+    sender.to_s
+  end
+end
+
+
+ +
+

+ + #Child!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Child?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #Match!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Match?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #Type!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Type?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/InternalDelegations.html b/docs/1.1.10/Concurrent/Actor/InternalDelegations.html new file mode 100644 index 000000000..07ce21807 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/InternalDelegations.html @@ -0,0 +1,1143 @@ + + + + + + + Module: Concurrent::Actor::InternalDelegations + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Actor::InternalDelegations + + + +

+
+ + + + + + +
+
Includes:
+
PublicDelegations, Logger::Severity
+
+ + + + +
+
Included in:
+
AbstractContext, Behaviour::Abstract
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #behaviour(behaviour_class) ⇒ undocumented + + + + + +

+
+

see Core#behaviour

+ + +
+
+
+ + +
+ + + + +
+
+
+
+49
+50
+51
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 49
+
+def behaviour(behaviour_class)
+  core.behaviour(behaviour_class)
+end
+
+
+ +
+

+ + #behaviour!(behaviour_class) ⇒ undocumented + + + + + +

+
+

see Core#behaviour!

+ + +
+
+
+ + +
+ + + + +
+
+
+
+54
+55
+56
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 54
+
+def behaviour!(behaviour_class)
+  core.behaviour!(behaviour_class)
+end
+
+
+ +
+

+ + #childrenundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+8
+9
+10
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 8
+
+def children
+  core.children
+end
+
+
+ +
+

+ + #contextAbstractContext + + + + + +

+
+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+44
+45
+46
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 44
+
+def context
+  core.context
+end
+
+
+ +
+

+ + #dead_letter_routingundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+34
+35
+36
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 34
+
+def dead_letter_routing
+  context.dead_letter_routing
+end
+
+
+ +
+

+ + #log(level, message = nil, &block) ⇒ undocumented + + + + + +

+
+

delegates to core.log

+ + +
+
+
+ + +

See Also:

+
    + +
  • Logging#log
  • + +
+ +
+ + + + +
+
+
+
+29
+30
+31
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 29
+
+def log(level, message = nil, &block)
+  core.log(level, message, &block)
+end
+
+
+ +
+

+ + #redirect(reference, envelope = self.envelope) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+38
+39
+40
+41
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 38
+
+def redirect(reference, envelope = self.envelope)
+  reference.message(envelope.message, envelope.future)
+  Behaviour::MESSAGE_PROCESSED
+end
+
+
+ +
+

+ + #terminate!(reason = nil) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+
    + +
  • Termination#terminate!
  • + +
+ +
+ + + + +
+
+
+
+13
+14
+15
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 13
+
+def terminate!(reason = nil)
+  behaviour!(Behaviour::Termination).terminate!(reason)
+end
+
+
+ +
+

+ + #terminated?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +

See Also:

+
    + +
  • Termination#terminated?
  • + +
+ +
+ + + + +
+
+
+
+18
+19
+20
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/internal_delegations.rb', line 18
+
+def terminated?
+  behaviour!(Behaviour::Termination).terminated?
+end
+
+
+ +
+

+ + #context_classundocumented + + + + Also known as: + actor_class + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #executorundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #nameundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #parentundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #pathundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #referenceundocumented + + + + Also known as: + ref + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/PublicDelegations.html b/docs/1.1.10/Concurrent/Actor/PublicDelegations.html new file mode 100644 index 000000000..a484f5337 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/PublicDelegations.html @@ -0,0 +1,566 @@ + + + + + + + Module: Concurrent::Actor::PublicDelegations + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Actor::PublicDelegations + + + +

+
+ + + + + + + + + +
+
Included in:
+
InternalDelegations, Reference
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb
+
+ +
+ +

Overview

+
+

Provides publicly expose-able methods from Core.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #context_classundocumented + + + + Also known as: + actor_class + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+32
+33
+34
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb', line 32
+
+def context_class
+  core.context_class
+end
+
+
+ +
+

+ + #executorundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb', line 27
+
+def executor
+  core.executor
+end
+
+
+ +
+

+ + #nameundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb', line 7
+
+def name
+  core.name
+end
+
+
+ +
+

+ + #parentundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb', line 17
+
+def parent
+  core.parent
+end
+
+
+ +
+

+ + #pathundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+12
+13
+14
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb', line 12
+
+def path
+  core.path
+end
+
+
+ +
+

+ + #referenceundocumented + + + + Also known as: + ref + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+22
+23
+24
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/public_delegations.rb', line 22
+
+def reference
+  core.reference
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Reference.html b/docs/1.1.10/Concurrent/Actor/Reference.html new file mode 100644 index 000000000..c8bef8ce7 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Reference.html @@ -0,0 +1,1624 @@ + + + + + + + Class: Concurrent::Actor::Reference + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Reference + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
PublicDelegations, TypeCheck
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/reference.rb
+
+ +
+ +

Overview

+
+

Reference is public interface of Actor instances. It is used for sending messages and can +be freely passed around the application. It also provides some basic information about the actor, +see PublicDelegations.

+ +
AdHoc.spawn('printer') { -> message { puts message } }
+# => #<Concurrent::Actor::Reference:0x7fd0d2883218 /printer (Concurrent::Actor::Utils::AdHoc)>
+#                                   ^object_id     ^path     ^context class
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #==(other) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+95
+96
+97
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/reference.rb', line 95
+
+def ==(other)
+  Type? other, self.class and other.send(:core) == core
+end
+
+
+ +
+

+ + #ask(message, future = Concurrent::Promises.resolvable_future) ⇒ Promises::Future + + + + Also known as: + ask_op + + + + +

+
+ +
+ Note: +

it's a good practice to use #tell whenever possible. Results can be sent back with other messages. +Ask should be used only for testing and when it returns very shortly. It can lead to deadlock if all threads in +global_io_executor will block on while asking. It's fine to use it form outside of actors and +global_io_executor.

+
+
+ +

Returns supplied future.

+ + +
+
+
+ +
+

Examples:

+ + +
adder = AdHoc.spawn('adder') { -> message { message + 1 } }
+adder.ask(1).value # => 2
+adder.ask(nil).wait.reason # => #<NoMethodError: undefined method `+' for nil:NilClass>
+ +
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
  • + + future + + + (Promises::Future) + + + (defaults to: Concurrent::Promises.resolvable_future) + + + — +

    to be fulfilled be message's processing result

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+49
+50
+51
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/reference.rb', line 49
+
+def ask(message, future = Concurrent::Promises.resolvable_future)
+  message message, future
+end
+
+
+ +
+

+ + #ask!(message, future = Concurrent::Promises.resolvable_future) ⇒ Object + + + + + +

+
+ +
+ Note: +

it's a good practice to use #tell whenever possible. Results can be sent back with other messages. +Ask should be used only for testing and when it returns very shortly. It can lead to deadlock if all threads in +global_io_executor will block on while asking. It's fine to use it form outside of actors and +global_io_executor.

+
+
+ +

Sends the message synchronously and blocks until the message +is processed. Raises on error.

+ + +
+
+
+ +
+

Examples:

+ + +
adder = AdHoc.spawn('adder') { -> message { message + 1 } }
+adder.ask!(1) # => 2
+ +
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
  • + + future + + + (Promises::Future) + + + (defaults to: Concurrent::Promises.resolvable_future) + + + — +

    to be fulfilled be message's processing result

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    message's processing result

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    future.reason if future is #rejected?

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+70
+71
+72
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/reference.rb', line 70
+
+def ask!(message, future = Concurrent::Promises.resolvable_future)
+  ask(message, future).value!
+end
+
+
+ +
+

+ + #dead_letter_routingundocumented + + + + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+85
+86
+87
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/reference.rb', line 85
+
+def dead_letter_routing
+  core.dead_letter_routing
+end
+
+
+ +
+

+ + #map(messages) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+74
+75
+76
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/reference.rb', line 74
+
+def map(messages)
+  messages.map { |m| self.ask(m) }
+end
+
+
+ +
+

+ + #message(message, future = nil) ⇒ undocumented + + + + + +

+
+

behaves as #tell when no future and as #ask when future

+ + +
+
+
+ + +
+ + + + +
+
+
+
+79
+80
+81
+82
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/reference.rb', line 79
+
+def message(message, future = nil)
+  core.on_envelope Envelope.new(message, future, Actor.current || Thread.current, self)
+  return future ? future.with_hidden_resolvable : self
+end
+
+
+ +
+

+ + #tell(message) ⇒ Reference + + + + Also known as: + << + + + + +

+
+

Sends the message asynchronously to the actor and immediately returns +self (the reference) allowing to chain message telling.

+ + +
+
+
+ +
+

Examples:

+ + +
printer = AdHoc.spawn('printer') { -> message { puts message } }
+printer.tell('ping').tell('pong')
+printer << 'ping' << 'pong'
+# => 'ping'\n'pong'\n'ping'\n'pong'\n
+ +
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Reference) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+32
+33
+34
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/reference.rb', line 32
+
+def tell(message)
+  message message, nil
+end
+
+
+ +
+

+ + #to_sundocumented + + + + Also known as: + inspect + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+89
+90
+91
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/reference.rb', line 89
+
+def to_s
+  format '%s %s (%s)>', super[0..-2], path, actor_class
+end
+
+
+ +
+

+ + #Child!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Child?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #context_classundocumented + + + + Also known as: + actor_class + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #executorundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #Match!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Match?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #nameundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #parentundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #pathundocumented + + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #referenceundocumented + + + + Also known as: + ref + + + + + + Originally defined in module + PublicDelegations + + +

+
+ + +
+
+
+ + +

See Also:

+ + +
+
+ +
+

+ + #Type!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Type?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/RestartingContext.html b/docs/1.1.10/Concurrent/Actor/RestartingContext.html new file mode 100644 index 000000000..92c3841de --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/RestartingContext.html @@ -0,0 +1,239 @@ + + + + + + + Class: Concurrent::Actor::RestartingContext + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::RestartingContext + Abstract + + +

+
+ +
+
Inherits:
+
+ AbstractContext + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/context.rb
+
+ +
+ +

Overview

+
+
+ This class is abstract. + +
+

Context of an Actor for robust systems. It supports supervision, linking, pauses on error. +Uses Behaviour.restarting_behaviour_definition

+ + +
+
+
+ + +
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #behaviour_definitionundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+161
+162
+163
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 161
+
+def behaviour_definition
+  Behaviour.restarting_behaviour_definition
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Root.html b/docs/1.1.10/Concurrent/Actor/Root.html new file mode 100644 index 000000000..3d260d20b --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Root.html @@ -0,0 +1,448 @@ + + + + + + + Class: Concurrent::Actor::Root + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Root + + + +

+
+ +
+
Inherits:
+
+ AbstractContext + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/root.rb
+
+ +
+ +

Overview

+
+

implements the root actor

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initializeRoot + + + + + +

+
+

Returns a new instance of Root.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+9
+10
+11
+12
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/root.rb', line 6
+
+def initialize
+  # noinspection RubyArgCount
+  @dead_letter_router = Core.new(parent:    reference,
+                                 class:     DefaultDeadLetterHandler,
+                                 supervise: true,
+                                 name:      :default_dead_letter_handler).reference
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #behaviour_definitionundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+30
+31
+32
+33
+34
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/root.rb', line 30
+
+def behaviour_definition
+  [*Behaviour.base(:just_log),
+   *Behaviour.supervising,
+   *Behaviour.user_messages]
+end
+
+
+ +
+

+ + #dead_letter_routingundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+26
+27
+28
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/root.rb', line 26
+
+def dead_letter_routing
+  @dead_letter_router
+end
+
+
+ +
+

+ + #on_message(message) ⇒ undocumented + + + + + +

+
+

to allow spawning of new actors, spawn needs to be called inside the parent Actor

+ + +
+
+
+ + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/root.rb', line 15
+
+def on_message(message)
+  case
+  when message.is_a?(::Array) && message.first == :spawn
+    Actor.spawn message[1], &message[2]
+  when message == :dead_letter_routing
+    @dead_letter_router
+  else
+    # ignore
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/TypeCheck.html b/docs/1.1.10/Concurrent/Actor/TypeCheck.html new file mode 100644 index 000000000..70a659dc2 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/TypeCheck.html @@ -0,0 +1,566 @@ + + + + + + + Module: Concurrent::Actor::TypeCheck + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Actor::TypeCheck + + + +

+
+ + + + + + + + + +
+
Included in:
+
AbstractContext, ActorTerminated, Behaviour::Abstract, Core, Envelope, Reference, UnknownMessage
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/type_check.rb
+
+ +
+ +

Overview

+
+

taken from Algebrick +supplies type-checking helpers whenever included

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #Child!(value, *types) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+33
+34
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/type_check.rb', line 33
+
+def Child!(value, *types)
+  Child?(value, *types) or
+      TypeCheck.error(value, 'is not child', types)
+  value
+end
+
+
+ +
+

+ + #Child?(value, *types) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+28
+29
+30
+31
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/type_check.rb', line 28
+
+def Child?(value, *types)
+  Type?(value, Class) &&
+      types.any? { |t| value <= t }
+end
+
+
+ +
+

+ + #Match!(value, *types) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+22
+23
+24
+25
+26
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/type_check.rb', line 22
+
+def Match!(value, *types)
+  Match?(value, *types) or
+      TypeCheck.error(value, 'is not matching', types)
+  value
+end
+
+
+ +
+

+ + #Match?(value, *types) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+18
+19
+20
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/type_check.rb', line 18
+
+def Match?(value, *types)
+  types.any? { |t| t === value }
+end
+
+
+ +
+

+ + #Type!(value, *types) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+16
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/type_check.rb', line 12
+
+def Type!(value, *types)
+  Type?(value, *types) or
+      TypeCheck.error(value, 'is not', types)
+  value
+end
+
+
+ +
+

+ + #Type?(value, *types) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+8
+9
+10
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/type_check.rb', line 8
+
+def Type?(value, *types)
+  types.any? { |t| value.is_a? t }
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/UnknownMessage.html b/docs/1.1.10/Concurrent/Actor/UnknownMessage.html new file mode 100644 index 000000000..11dd5c0ef --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/UnknownMessage.html @@ -0,0 +1,669 @@ + + + + + + + Class: Concurrent::Actor::UnknownMessage + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::UnknownMessage + + + +

+
+ +
+
Inherits:
+
+ Error + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
TypeCheck
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/errors.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(envelope) ⇒ UnknownMessage + + + + + +

+
+

Returns a new instance of UnknownMessage.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+21
+22
+23
+24
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/errors.rb', line 21
+
+def initialize(envelope)
+  @envelope = Type! envelope, Envelope
+  super "#{envelope.message.inspect} from #{envelope.sender_path}"
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #envelopeundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+19
+20
+21
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/errors.rb', line 19
+
+def envelope
+  @envelope
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #Child!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Child?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #Match!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Match?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #Type!(value, *types) ⇒ undocumented + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #Type?(value, *types) ⇒ Boolean + + + + + + + Originally defined in module + TypeCheck + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Utils.html b/docs/1.1.10/Concurrent/Actor/Utils.html new file mode 100644 index 000000000..449c35ff4 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Utils.html @@ -0,0 +1,137 @@ + + + + + + + Module: Concurrent::Actor::Utils + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Actor::Utils + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/utils.rb,
+ lib/concurrent-ruby-edge/concurrent/actor/utils/pool.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/ad_hoc.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/balancer.rb,
lib/concurrent-ruby-edge/concurrent/actor/utils/broadcast.rb
+
+
+ +
+ +
+
+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: AsAdHoc + + + + Classes: AdHoc, Balancer, Broadcast, Pool + + +

+ + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Utils/AdHoc.html b/docs/1.1.10/Concurrent/Actor/Utils/AdHoc.html new file mode 100644 index 000000000..ee286e496 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Utils/AdHoc.html @@ -0,0 +1,299 @@ + + + + + + + Class: Concurrent::Actor::Utils::AdHoc + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Utils::AdHoc + + + +

+
+ +
+
Inherits:
+
+ Context + + + show all + +
+
+ + + + + + +
+
Includes:
+
AsAdHoc
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/utils/ad_hoc.rb
+
+ +
+ +

Overview

+
+

Allows quick creation of actors with behaviour defined by blocks.

+ + +
+
+
+ +
+

Examples:

+ + +

ping

+

+ +
AdHoc.spawn :forward, an_actor do |where|
+  # this block has to return proc defining #on_message behaviour
+  -> message { where.tell message  }
+end
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #initialize(*args, &initializer) ⇒ undocumented + + + + + + + Originally defined in module + AsAdHoc + + +

+
+ + +
+
+
+ + +
+
+ +
+

+ + #on_message(message) ⇒ undocumented + + + + + + + Originally defined in module + AsAdHoc + + +

+
+ + +
+
+
+ + +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Utils/AsAdHoc.html b/docs/1.1.10/Concurrent/Actor/Utils/AsAdHoc.html new file mode 100644 index 000000000..3fa9d1b38 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Utils/AsAdHoc.html @@ -0,0 +1,267 @@ + + + + + + + Module: Concurrent::Actor::Utils::AsAdHoc + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Actor::Utils::AsAdHoc + + + +

+
+ + + + + + + + + +
+
Included in:
+
AdHoc
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/utils/ad_hoc.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #initialize(*args, &initializer) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/ad_hoc.rb', line 6
+
+def initialize(*args, &initializer)
+  @on_message = Type! initializer.call(*args), Proc
+end
+
+
+ +
+

+ + #on_message(message) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+10
+11
+12
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/ad_hoc.rb', line 10
+
+def on_message(message)
+  instance_exec message, &@on_message
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Utils/Balancer.html b/docs/1.1.10/Concurrent/Actor/Utils/Balancer.html new file mode 100644 index 000000000..f60a03efa --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Utils/Balancer.html @@ -0,0 +1,408 @@ + + + + + + + Class: Concurrent::Actor::Utils::Balancer + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Utils::Balancer + + + +

+
+ +
+
Inherits:
+
+ RestartingContext + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/utils/balancer.rb
+
+ +
+ +

Overview

+
+

Distributes messages between subscribed actors. Each actor'll get only one message then +it's unsubscribed. The actor needs to resubscribe when it's ready to receive next message. +It will buffer the messages if there is no worker registered.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initializeBalancer + + + + + +

+
+

Returns a new instance of Balancer.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+11
+12
+13
+14
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/balancer.rb', line 11
+
+def initialize
+  @receivers = []
+  @buffer    = []
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #distributeundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+35
+36
+37
+38
+39
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/balancer.rb', line 35
+
+def distribute
+  while !@receivers.empty? && !@buffer.empty?
+    redirect @receivers.shift, @buffer.shift
+  end
+end
+
+
+ +
+

+ + #on_message(message) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/balancer.rb', line 16
+
+def on_message(message)
+  command, who = message
+  case command
+  when :subscribe
+    @receivers << (who || envelope.sender)
+    distribute
+    true
+  when :unsubscribe
+    @receivers.delete(who || envelope.sender)
+    true
+  when :subscribed?
+    @receivers.include?(who || envelope.sender)
+  else
+    @buffer << envelope
+    distribute
+    Behaviour::MESSAGE_PROCESSED
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Utils/Broadcast.html b/docs/1.1.10/Concurrent/Actor/Utils/Broadcast.html new file mode 100644 index 000000000..9a50246a0 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Utils/Broadcast.html @@ -0,0 +1,414 @@ + + + + + + + Class: Concurrent::Actor::Utils::Broadcast + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Utils::Broadcast + + + +

+
+ +
+
Inherits:
+
+ RestartingContext + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/utils/broadcast.rb
+
+ +
+ +

Overview

+
+

Allows to build pub/sub easily.

+ + +
+
+
+ +
+

Examples:

+ + +

news

+

+ +
news_channel = Concurrent::Actor::Utils::Broadcast.spawn :news
+
+2.times do |i|
+  Concurrent::Actor::Utils::AdHoc.spawn "listener-#{i}" do
+    news_channel << :subscribe
+    -> message { puts message }
+  end
+end
+
+news_channel << 'Ruby rocks!'
+# prints: 'Ruby rocks!' twice
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initializeBroadcast + + + + + +

+
+

Returns a new instance of Broadcast.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+22
+23
+24
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/broadcast.rb', line 22
+
+def initialize
+  @receivers = Set.new
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #filtered_receiversundocumented + + + + + +

+
+

override to define different behaviour, filtering etc

+ + +
+
+
+ + +
+ + + + +
+
+
+
+45
+46
+47
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/broadcast.rb', line 45
+
+def filtered_receivers
+  @receivers
+end
+
+
+ +
+

+ + #on_message(message) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/broadcast.rb', line 26
+
+def on_message(message)
+  case message
+  when :subscribe
+    if envelope.sender.is_a? Reference
+      @receivers.add envelope.sender
+      true
+    else
+      false
+    end
+  when :unsubscribe
+    !!@receivers.delete(envelope.sender)
+  when :subscribed?
+    @receivers.include? envelope.sender
+  else
+    filtered_receivers.each { |r| r << message }
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Actor/Utils/Pool.html b/docs/1.1.10/Concurrent/Actor/Utils/Pool.html new file mode 100644 index 000000000..6f2be5df4 --- /dev/null +++ b/docs/1.1.10/Concurrent/Actor/Utils/Pool.html @@ -0,0 +1,420 @@ + + + + + + + Class: Concurrent::Actor::Utils::Pool + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Actor::Utils::Pool + + + +

+
+ +
+
Inherits:
+
+ RestartingContext + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/actor/utils/pool.rb
+
+ +
+ +

Overview

+
+

Allows to create a pool of workers and distribute work between them

+ + +
+
+
+ +
+

Examples:

+ + +
class Worker < Concurrent::Actor::RestartingContext
+  def on_message(message)
+    p message * 5
+  end
+end
+
+pool = Concurrent::Actor::Utils::Pool.spawn! 'pool', 5 do |index|
+  Worker.spawn name: "worker-#{index}", supervise: true, args: []
+end
+
+pool << 'asd' << 2
+# prints:
+# "asdasdasdasdasd"
+# 10
+ +
+ +

Yields:

+
    + +
  • + + + (balancer, index) + + + + — +

    a block spawning an worker instance. called +size+ times. +The worker should be descendant of AbstractWorker and supervised, see example.

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + balancer + + + (Balancer) + + + + — +

    to pass to the worker

    +
    + +
  • + +
  • + + index + + + (Integer) + + + + — +

    of the worker, usually used in its name

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Reference) + + + + — +

    the reference of newly created worker

    +
    + +
  • + +
+ +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(size, &worker_initializer) ⇒ Pool + + + + + +

+
+

Returns a new instance of Pool.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+30
+31
+32
+33
+34
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/pool.rb', line 30
+
+def initialize(size, &worker_initializer)
+  @balancer = Balancer.spawn name: :balancer, supervise: true
+  @workers  = ::Array.new(size, &worker_initializer)
+  @workers.each do |worker|
+    Type! worker, Reference
+    @balancer << [:subscribe, worker]
+  end
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #on_message(message) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+
+
# File 'lib/concurrent-ruby-edge/concurrent/actor/utils/pool.rb', line 39
+
+def on_message(message)
+  command, _ = message
+  return if [:restarted, :reset, :resumed, :terminated].include? command # ignore events from supervised actors
+
+  envelope_to_redirect = if envelope.future
+                           envelope
+                         else
+                           Envelope.new(envelope.message, Promises.resolvable_future, envelope.sender, envelope.address)
+                         end
+  envelope_to_redirect.future.on_fulfillment! { @balancer << :subscribe } # TODO check safety of @balancer reading
+  redirect @balancer, envelope_to_redirect
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Agent.html b/docs/1.1.10/Concurrent/Agent.html new file mode 100644 index 000000000..17d3a32c9 --- /dev/null +++ b/docs/1.1.10/Concurrent/Agent.html @@ -0,0 +1,3768 @@ + + + + + + + Class: Concurrent::Agent + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Agent + + + +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Concern::Observable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/agent.rb
+
+ +
+ +

Overview

+
+

Agent is inspired by Clojure's agent +function. An agent is a shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately. Agent is (mostly) +functionally equivalent to Clojure's agent, except where the runtime +prevents parity.

+ +

Agents are reactive, not autonomous - there is no imperative message loop +and no blocking receive. The state of an Agent should be itself immutable +and the #value of an Agent is always immediately available for reading by +any thread without any messages, i.e. observation does not require +cooperation or coordination.

+ +

Agent action dispatches are made using the various #send methods. These +methods always return immediately. At some point later, in another thread, +the following will happen:

+ +
    +
  1. The given action will be applied to the state of the Agent and the +args, if any were supplied.
  2. +
  3. The return value of action will be passed to the validator lambda, +if one has been set on the Agent.
  4. +
  5. If the validator succeeds or if no validator was given, the return value +of the given action will become the new #value of the Agent. See +#initialize for details.
  6. +
  7. If any observers were added to the Agent, they will be notified. See +#add_observer for details.
  8. +
  9. If during the action execution any other dispatches are made (directly +or indirectly), they will be held until after the #value of the Agent +has been changed.
  10. +
+ +

If any exceptions are thrown by an action function, no nested dispatches +will occur, and the exception will be cached in the Agent itself. When an +Agent has errors cached, any subsequent interactions will immediately throw +an exception, until the agent's errors are cleared. Agent errors can be +examined with #error and the agent restarted with #restart.

+ +

The actions of all Agents get interleaved amongst threads in a thread pool. +At any point in time, at most one action for each Agent is being executed. +Actions dispatched to an agent from another single agent or thread will +occur in the order they were sent, potentially interleaved with actions +dispatched to the same agent from other sources. The #send method should +be used for actions that are CPU limited, while the #send_off method is +appropriate for actions that may block on IO.

+ +

Unlike in Clojure, Agent cannot participate in Concurrent::TVar transactions.

+ +

Example

+ +
def next_fibonacci(set = nil)
+  return [0, 1] if set.nil?
+  set + [set[-2..-1].reduce{|sum,x| sum + x }]
+end
+
+# create an agent with an initial value
+agent = Concurrent::Agent.new(next_fibonacci)
+
+# send a few update requests
+5.times do
+  agent.send{|set| next_fibonacci(set) }
+end
+
+# wait for them to complete
+agent.await
+
+# get the current value
+agent.value #=> [0, 1, 1, 2, 3, 5, 8]
+
+ +

Observation

+ +

Agents support observers through the Observable mixin module. +Notification of observers occurs every time an action dispatch returns and +the new value is successfully validated. Observation will not occur if the +action raises an exception, if validation fails, or when a #restart occurs.

+ +

When notified the observer will receive three arguments: time, old_value, +and new_value. The time argument is the time at which the value change +occurred. The old_value is the value of the Agent when the action began +processing. The new_value is the value to which the Agent was set when the +action completed. Note that old_value and new_value may be the same. +This is not an error. It simply means that the action returned the same +value.

+ +

Nested Actions

+ +

It is possible for an Agent action to post further actions back to itself. +The nested actions will be enqueued normally then processed after the +outer action completes, in the order they were sent, possibly interleaved +with action dispatches from other threads. Nested actions never deadlock +with one another and a failure in a nested action will never affect the +outer action.

+ +

Nested actions can be called using the Agent reference from the enclosing +scope or by passing the reference in as a "send" argument. Nested actions +cannot be post using self from within the action block/proc/lambda; self +in this context will not reference the Agent. The preferred method for +dispatching nested actions is to pass the Agent as an argument. This allows +Ruby to more effectively manage the closing scope.

+ +

Prefer this:

+ +
agent = Concurrent::Agent.new(0)
+agent.send(agent) do |value, this|
+  this.send {|v| v + 42 }
+  3.14
+end
+agent.value #=> 45.14
+
+ +

Over this:

+ +
agent = Concurrent::Agent.new(0)
+agent.send do |value|
+  agent.send {|v| v + 42 }
+  3.14
+end
+
+ +

NOTE Never, under any circumstances, call any of the "await" methods +(#await, #await_for, #await_for!, and #wait) from within an action +block/proc/lambda. The call will block the Agent and will always fail. +Calling either #await or #wait (with a timeout of nil) will +hopelessly deadlock the Agent with no possibility of recovery.

+ +

Thread-safe Variable Classes

+ +

Each of the thread-safe variable classes is designed to solve a different +problem. In general:

+ +
    +
  • Agent: Shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately.
  • +
  • Atom: Shared, mutable variable providing independent, +uncoordinated, synchronous change of individual values. Best used when +the value will undergo frequent reads but only occasional, though complex, +updates. Suitable when the result of an update must be known immediately.
  • +
  • AtomicReference: A simple object reference that can be updated +atomically. Updates are synchronous but fast. Best used when updates a +simple set operations. Not suitable when updates are complex. +AtomicBoolean and AtomicFixnum are similar +but optimized for the given data type.
  • +
  • Exchanger: Shared, stateless synchronization point. Used +when two or more threads need to exchange data. The threads will pair then +block on each other until the exchange is complete.
  • +
  • MVar: Shared synchronization point. Used when one thread +must give a value to another, which must take the value. The threads will +block on each other until the exchange is complete.
  • +
  • ThreadLocalVar: Shared, mutable, isolated variable which +holds a different value for each thread which has access. Often used as +an instance variable in objects which must maintain different state +for different threads.
  • +
  • TVar: Shared, mutable variables which provide +coordinated, synchronous, change of many stated. Used when multiple +value must change together, in an all-or-nothing transaction.
  • +
+ + +
+
+

Defined Under Namespace

+

+ + + + + Classes: Error, ValidationError + + +

+ + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(initial, opts = {}) ⇒ Agent + + + + + +

+
+

Create a new Agent with the given initial value and options.

+ +

The :validator option must be nil or a side-effect free proc/lambda +which takes one argument. On any intended value change the validator, if +provided, will be called. If the new value is invalid the validator should +return false or raise an error.

+ +

The :error_handler option must be nil or a proc/lambda which takes two +arguments. When an action raises an error or validation fails, either by +returning false or raising an error, the error handler will be called. The +arguments to the error handler will be a reference to the agent itself and +the error object which was raised.

+ +

The :error_mode may be either :continue (the default if an error +handler is given) or :fail (the default if error handler nil or not +given).

+ +

If an action being run by the agent throws an error or doesn't pass +validation the error handler, if present, will be called. After the +handler executes if the error mode is :continue the Agent will continue +as if neither the action that caused the error nor the error itself ever +happened.

+ +

If the mode is :fail the Agent will become #failed? and will stop +accepting new action dispatches. Any previously queued actions will be +held until #restart is called. The #value method will still work, +returning the value of the Agent before the error.

+ + +
+
+
+

Parameters:

+
    + +
  • + + initial + + + (Object) + + + + — +

    the initial value

    +
    + +
  • + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the configuration options

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :error_mode + (Symbol) + + + + + —

    either :continue or :fail

    +
    + +
  • + +
  • + :error_handler + (nil, Proc) + + + + + —

    the (optional) error handler

    +
    + +
  • + +
  • + :validator + (nil, Proc) + + + + + —

    the (optional) validation procedure

    +
    + +
  • + +
+ + + +
+ + + + +
+
+
+
+219
+220
+221
+222
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 219
+
+def initialize(initial, opts = {})
+  super()
+  synchronize { ns_initialize(initial, opts) }
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #error_modeundocumented (readonly) + + + + + +

+
+

The error mode this Agent is operating in. See #initialize for details.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+183
+184
+185
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 183
+
+def error_mode
+  @error_mode
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .await(*agents) ⇒ Boolean + + + + + +

+
+

Blocks the current thread (indefinitely!) until all actions dispatched +thus far to all the given Agents, from this thread or nested by the +given Agents, have occurred. Will block when any of the agents are +failed. Will never return if a failed Agent is restart with +:clear_actions true.

+ +

NOTE Never, under any circumstances, call any of the "await" methods +(#await, #await_for, #await_for!, and #wait) from within an action +block/proc/lambda. The call will block the Agent and will always fail. +Calling either #await or #wait (with a timeout of nil) will +hopelessly deadlock the Agent with no possibility of recovery.

+ + +
+
+
+

Parameters:

+ + +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+448
+449
+450
+451
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 448
+
+def await(*agents)
+  agents.each { |agent| agent.await }
+  true
+end
+
+
+ +
+

+ + .await_for(timeout, *agents) ⇒ Boolean + + + + + +

+
+

Blocks the current thread until all actions dispatched thus far to all +the given Agents, from this thread or nested by the given Agents, have +occurred, or the timeout (in seconds) has elapsed.

+ +

NOTE Never, under any circumstances, call any of the "await" methods +(#await, #await_for, #await_for!, and #wait) from within an action +block/proc/lambda. The call will block the Agent and will always fail. +Calling either #await or #wait (with a timeout of nil) will +hopelessly deadlock the Agent with no possibility of recovery.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Float) + + + + — +

    the maximum number of seconds to wait

    +
    + +
  • + +
  • + + agents + + + (Array<Concurrent::Agent>) + + + + — +

    the Agents on which to wait

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if all actions complete before timeout else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+462
+463
+464
+465
+466
+467
+468
+469
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 462
+
+def await_for(timeout, *agents)
+  end_at = Concurrent.monotonic_time + timeout.to_f
+  ok     = agents.length.times do |i|
+    break false if (delay = end_at - Concurrent.monotonic_time) < 0
+    break false unless agents[i].await_for(delay)
+  end
+  !!ok
+end
+
+
+ +
+

+ + .await_for!(timeout, *agents) ⇒ Boolean + + + + + +

+
+

Blocks the current thread until all actions dispatched thus far to all +the given Agents, from this thread or nested by the given Agents, have +occurred, or the timeout (in seconds) has elapsed.

+ +

NOTE Never, under any circumstances, call any of the "await" methods +(#await, #await_for, #await_for!, and #wait) from within an action +block/proc/lambda. The call will block the Agent and will always fail. +Calling either #await or #wait (with a timeout of nil) will +hopelessly deadlock the Agent with no possibility of recovery.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Float) + + + + — +

    the maximum number of seconds to wait

    +
    + +
  • + +
  • + + agents + + + (Array<Concurrent::Agent>) + + + + — +

    the Agents on which to wait

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if all actions complete before timeout

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+481
+482
+483
+484
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 481
+
+def await_for!(timeout, *agents)
+  raise Concurrent::TimeoutError unless await_for(timeout, *agents)
+  true
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #<<(action) ⇒ Concurrent::Agent + + + + + +

+
+

Dispatches an action to the Agent and returns immediately. Subsequently, +in a thread from a thread pool, the #value will be set to the return +value of the action. Appropriate for actions that may block on IO.

+ + +
+
+
+

Parameters:

+
    + +
  • + + action + + + (Proc) + + + + — +

    the action dispatch to be enqueued

    +
    + +
  • + +
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+330
+331
+332
+333
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 330
+
+def <<(action)
+  send_off(&action)
+  self
+end
+
+
+ +
+

+ + #awaitBoolean + + + + + +

+
+

Blocks the current thread (indefinitely!) until all actions dispatched +thus far, from this thread or nested by the Agent, have occurred. Will +block when #failed?. Will never return if a failed Agent is #restart +with :clear_actions true.

+ +

Returns a reference to self to support method chaining:

+ +
current_value = agent.await.value
+
+ +

NOTE Never, under any circumstances, call any of the "await" methods +(#await, #await_for, #await_for!, and #wait) from within an action +block/proc/lambda. The call will block the Agent and will always fail. +Calling either #await or #wait (with a timeout of nil) will +hopelessly deadlock the Agent with no possibility of recovery.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+349
+350
+351
+352
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 349
+
+def await
+  wait(nil)
+  self
+end
+
+
+ +
+

+ + #await_for(timeout) ⇒ Boolean + + + + + +

+
+

Blocks the current thread until all actions dispatched thus far, from this +thread or nested by the Agent, have occurred, or the timeout (in seconds) +has elapsed.

+ +

NOTE Never, under any circumstances, call any of the "await" methods +(#await, #await_for, #await_for!, and #wait) from within an action +block/proc/lambda. The call will block the Agent and will always fail. +Calling either #await or #wait (with a timeout of nil) will +hopelessly deadlock the Agent with no possibility of recovery.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Float) + + + + — +

    the maximum number of seconds to wait

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if all actions complete before timeout else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+362
+363
+364
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 362
+
+def await_for(timeout)
+  wait(timeout.to_f)
+end
+
+
+ +
+

+ + #await_for!(timeout) ⇒ Boolean + + + + + +

+
+

Blocks the current thread until all actions dispatched thus far, from this +thread or nested by the Agent, have occurred, or the timeout (in seconds) +has elapsed.

+ +

NOTE Never, under any circumstances, call any of the "await" methods +(#await, #await_for, #await_for!, and #wait) from within an action +block/proc/lambda. The call will block the Agent and will always fail. +Calling either #await or #wait (with a timeout of nil) will +hopelessly deadlock the Agent with no possibility of recovery.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Float) + + + + — +

    the maximum number of seconds to wait

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if all actions complete before timeout

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+376
+377
+378
+379
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 376
+
+def await_for!(timeout)
+  raise Concurrent::TimeoutError unless wait(timeout.to_f)
+  true
+end
+
+
+ +
+

+ + #errornil, Error + + + + Also known as: + reason + + + + +

+
+

When #failed? and #error_mode is :fail, returns the error object +which caused the failure, else nil. When #error_mode is :continue +will always return nil.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (nil, Error) + + + + — +

    the error which caused the failure when #failed?

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+239
+240
+241
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 239
+
+def error
+  @error.value
+end
+
+
+ +
+

+ + #failed?Boolean + + + + Also known as: + stopped? + + + + +

+
+

Is the Agent in a failed state?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+401
+402
+403
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 401
+
+def failed?
+  !@error.value.nil?
+end
+
+
+ +
+

+ + #restart(new_value, opts = {}) ⇒ Boolean + + + + + +

+
+

When an Agent is #failed?, changes the Agent #value to new_value +then un-fails the Agent so that action dispatches are allowed again. If +the :clear_actions option is give and true, any actions queued on the +Agent that were being held while it was failed will be discarded, +otherwise those held actions will proceed. The new_value must pass the +validator if any, or restart will raise an exception and the Agent will +remain failed with its old #value and #error. Observers, if any, will +not be notified of the new state.

+ + +
+
+
+

Parameters:

+
    + +
  • + + new_value + + + (Object) + + + + — +

    the new value for the Agent once restarted

    +
    + +
  • + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the configuration options

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :clear_actions + (Symbol) + + + + + —

    true if all enqueued but unprocessed +actions should be discarded on restart, else false (default: false)

    +
    + +
  • + +
+ + +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Concurrent:AgentError) + + + + — +

    when not failed

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 423
+
+def restart(new_value, opts = {})
+  clear_actions = opts.fetch(:clear_actions, false)
+  synchronize do
+    raise Error.new('agent is not failed') unless failed?
+    raise ValidationError unless ns_validate(new_value)
+    @current.value = new_value
+    @error.value   = nil
+    @queue.clear if clear_actions
+    ns_post_next_job unless @queue.empty?
+  end
+  true
+end
+
+
+ +
+

+ + #send(*args, &action) {|agent, value, *args| ... } ⇒ Boolean + + + + + +

+
+

Dispatches an action to the Agent and returns immediately. Subsequently, +in a thread from a thread pool, the #value will be set to the return +value of the action. Action dispatches are only allowed when the Agent +is not #failed?.

+ +

The action must be a block/proc/lambda which takes 1 or more arguments. +The first argument is the current #value of the Agent. Any arguments +passed to the send method via the args parameter will be passed to the +action as the remaining arguments. The action must return the new value +of the Agent.

+ + + + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to be passed to +the action

    +
    + +
  • + +
  • + + action + + + (Proc) + + + + — +

    the action dispatch to be enqueued

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (agent, value, *args) + + + + — +

    process the old value and return the new

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the current #value of the Agent

    +
    + +
  • + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to pass to the +action

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value of the Agent

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the action is successfully enqueued, false if +the Agent is #failed?

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+277
+278
+279
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 277
+
+def send(*args, &action)
+  enqueue_action_job(action, args, Concurrent.global_fast_executor)
+end
+
+
+ +
+

+ + #send!(*args, &action) {|agent, value, *args| ... } ⇒ Boolean + + + + + +

+
+

Dispatches an action to the Agent and returns immediately. Subsequently, +in a thread from a thread pool, the #value will be set to the return +value of the action. Action dispatches are only allowed when the Agent +is not #failed?.

+ +

The action must be a block/proc/lambda which takes 1 or more arguments. +The first argument is the current #value of the Agent. Any arguments +passed to the send method via the args parameter will be passed to the +action as the remaining arguments. The action must return the new value +of the Agent.

+ + + + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to be passed to +the action

    +
    + +
  • + +
  • + + action + + + (Proc) + + + + — +

    the action dispatch to be enqueued

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (agent, value, *args) + + + + — +

    process the old value and return the new

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the current #value of the Agent

    +
    + +
  • + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to pass to the +action

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value of the Agent

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the action is successfully enqueued

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+286
+287
+288
+289
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 286
+
+def send!(*args, &action)
+  raise Error.new unless send(*args, &action)
+  true
+end
+
+
+ +
+

+ + #send_off(*args, &action) {|agent, value, *args| ... } ⇒ Boolean + + + + Also known as: + post + + + + +

+
+

Dispatches an action to the Agent and returns immediately. Subsequently, +in a thread from a thread pool, the #value will be set to the return +value of the action. Action dispatches are only allowed when the Agent +is not #failed?.

+ +

The action must be a block/proc/lambda which takes 1 or more arguments. +The first argument is the current #value of the Agent. Any arguments +passed to the send method via the args parameter will be passed to the +action as the remaining arguments. The action must return the new value +of the Agent.

+ + + + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to be passed to +the action

    +
    + +
  • + +
  • + + action + + + (Proc) + + + + — +

    the action dispatch to be enqueued

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (agent, value, *args) + + + + — +

    process the old value and return the new

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the current #value of the Agent

    +
    + +
  • + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to pass to the +action

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value of the Agent

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the action is successfully enqueued, false if +the Agent is #failed?

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+293
+294
+295
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 293
+
+def send_off(*args, &action)
+  enqueue_action_job(action, args, Concurrent.global_io_executor)
+end
+
+
+ +
+

+ + #send_off!(*args, &action) {|agent, value, *args| ... } ⇒ Boolean + + + + + +

+
+

Dispatches an action to the Agent and returns immediately. Subsequently, +in a thread from a thread pool, the #value will be set to the return +value of the action. Action dispatches are only allowed when the Agent +is not #failed?.

+ +

The action must be a block/proc/lambda which takes 1 or more arguments. +The first argument is the current #value of the Agent. Any arguments +passed to the send method via the args parameter will be passed to the +action as the remaining arguments. The action must return the new value +of the Agent.

+ + + + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to be passed to +the action

    +
    + +
  • + +
  • + + action + + + (Proc) + + + + — +

    the action dispatch to be enqueued

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (agent, value, *args) + + + + — +

    process the old value and return the new

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the current #value of the Agent

    +
    + +
  • + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to pass to the +action

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value of the Agent

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the action is successfully enqueued

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+301
+302
+303
+304
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 301
+
+def send_off!(*args, &action)
+  raise Error.new unless send_off(*args, &action)
+  true
+end
+
+
+ +
+

+ + #send_via(executor, *args, &action) {|agent, value, *args| ... } ⇒ Boolean + + + + + +

+
+

Dispatches an action to the Agent and returns immediately. Subsequently, +in a thread from a thread pool, the #value will be set to the return +value of the action. Action dispatches are only allowed when the Agent +is not #failed?.

+ +

The action must be a block/proc/lambda which takes 1 or more arguments. +The first argument is the current #value of the Agent. Any arguments +passed to the send method via the args parameter will be passed to the +action as the remaining arguments. The action must return the new value +of the Agent.

+ + + + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to be passed to +the action

    +
    + +
  • + +
  • + + action + + + (Proc) + + + + — +

    the action dispatch to be enqueued

    +
    + +
  • + +
  • + + executor + + + (Concurrent::ExecutorService) + + + + — +

    the executor on which the +action is to be dispatched

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (agent, value, *args) + + + + — +

    process the old value and return the new

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the current #value of the Agent

    +
    + +
  • + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to pass to the +action

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value of the Agent

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the action is successfully enqueued, false if +the Agent is #failed?

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+310
+311
+312
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 310
+
+def send_via(executor, *args, &action)
+  enqueue_action_job(action, args, executor)
+end
+
+
+ +
+

+ + #send_via!(executor, *args, &action) {|agent, value, *args| ... } ⇒ Boolean + + + + + +

+
+

Dispatches an action to the Agent and returns immediately. Subsequently, +in a thread from a thread pool, the #value will be set to the return +value of the action. Action dispatches are only allowed when the Agent +is not #failed?.

+ +

The action must be a block/proc/lambda which takes 1 or more arguments. +The first argument is the current #value of the Agent. Any arguments +passed to the send method via the args parameter will be passed to the +action as the remaining arguments. The action must return the new value +of the Agent.

+ + + + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to be passed to +the action

    +
    + +
  • + +
  • + + action + + + (Proc) + + + + — +

    the action dispatch to be enqueued

    +
    + +
  • + +
  • + + executor + + + (Concurrent::ExecutorService) + + + + — +

    the executor on which the +action is to be dispatched

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (agent, value, *args) + + + + — +

    process the old value and return the new

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the current #value of the Agent

    +
    + +
  • + +
  • + + args + + + (Array<Object>) + + + + — +

    zero or more arguments to pass to the +action

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value of the Agent

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the action is successfully enqueued

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+318
+319
+320
+321
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 318
+
+def send_via!(executor, *args, &action)
+  raise Error.new unless send_via(executor, *args, &action)
+  true
+end
+
+
+ +
+

+ + #valueObject + + + + Also known as: + deref + + + + +

+
+

The current value (state) of the Agent, irrespective of any pending or +in-progress actions. The value is always available and is non-blocking.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+228
+229
+230
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 228
+
+def value
+  @current.value # TODO (pitr 12-Sep-2015): broken unsafe read?
+end
+
+
+ +
+

+ + #wait(timeout = nil) ⇒ Boolean + + + + + +

+
+

Blocks the current thread until all actions dispatched thus far, from this +thread or nested by the Agent, have occurred, or the timeout (in seconds) +has elapsed. Will block indefinitely when timeout is nil or not given.

+ +

Provided mainly for consistency with other classes in this library. Prefer +the various await methods instead.

+ +

NOTE Never, under any circumstances, call any of the "await" methods +(#await, #await_for, #await_for!, and #wait) from within an action +block/proc/lambda. The call will block the Agent and will always fail. +Calling either #await or #wait (with a timeout of nil) will +hopelessly deadlock the Agent with no possibility of recovery.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Float) + + + (defaults to: nil) + + + — +

    the maximum number of seconds to wait

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if all actions complete before timeout else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+392
+393
+394
+395
+396
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 392
+
+def wait(timeout = nil)
+  latch = Concurrent::CountDownLatch.new(1)
+  enqueue_await_job(latch)
+  latch.wait(timeout)
+end
+
+
+ +
+

+ + #add_observer(observer = nil, func = :update, &block) ⇒ Object + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Adds an observer to this set. If a block is passed, the observer will be +created by this method and no other params should be passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification. +Default is :update

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the added observer

    +
    + +
  • + +
+ +
+
+ +
+

+ + #count_observersInteger + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Return the number of observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the observers count

    +
    + +
  • + +
+ +
+
+ +
+

+ + #delete_observer(observer) ⇒ Object + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Remove observer as an observer on this object so that it will no +longer receive notifications.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + + — +

    the observer to remove

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the deleted observer

    +
    + +
  • + +
+ +
+
+ +
+

+ + #delete_observersObservable + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Remove all observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+

+ + #with_observer(observer = nil, func = :update, &block) ⇒ Observable + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

As #add_observer but can be used for chaining.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Agent/Error.html b/docs/1.1.10/Concurrent/Agent/Error.html new file mode 100644 index 000000000..95409d771 --- /dev/null +++ b/docs/1.1.10/Concurrent/Agent/Error.html @@ -0,0 +1,229 @@ + + + + + + + Exception: Concurrent::Agent::Error + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Exception: Concurrent::Agent::Error + + + +

+
+ +
+
Inherits:
+
+ StandardError + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/agent.rb
+
+ +
+ +

Overview

+
+

Raised during action processing or any other time in an Agent's lifecycle.

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

ValidationError

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Constructor Details

+ +
+

+ + #initialize(message = nil) ⇒ Error + + + + + +

+
+

Returns a new instance of Error.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+167
+168
+169
+170
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 167
+
+def initialize(message = nil)
+  message ||= 'agent must be restarted before jobs can post'
+  super(message)
+end
+
+
+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Agent/ValidationError.html b/docs/1.1.10/Concurrent/Agent/ValidationError.html new file mode 100644 index 000000000..572a051d2 --- /dev/null +++ b/docs/1.1.10/Concurrent/Agent/ValidationError.html @@ -0,0 +1,230 @@ + + + + + + + Exception: Concurrent::Agent::ValidationError + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Exception: Concurrent::Agent::ValidationError + + + +

+
+ +
+
Inherits:
+
+ Error + +
    +
  • Object
  • + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/agent.rb
+
+ +
+ +

Overview

+
+

Raised when a new value obtained during action processing or at #restart +fails validation.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(message = nil) ⇒ ValidationError + + + + + +

+
+

Returns a new instance of ValidationError.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+176
+177
+178
+179
+
+
# File 'lib/concurrent-ruby/concurrent/agent.rb', line 176
+
+def initialize(message = nil)
+  message ||= 'invalid value'
+  super(message)
+end
+
+
+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Array.html b/docs/1.1.10/Concurrent/Array.html new file mode 100644 index 000000000..7aa94f6e4 --- /dev/null +++ b/docs/1.1.10/Concurrent/Array.html @@ -0,0 +1,161 @@ + + + + + + + Class: Concurrent::Array + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Array + + + +

+
+ +
+
Inherits:
+
+ ArrayImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/array.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

a += b is not a thread-safe operation on +Concurrent::Array. It reads array a, then it creates new Concurrent::Array +which is concatenation of a and b, then it writes the concatenation to a. +The read and write are independent operations they do not form a single atomic +operation therefore when two += operations are executed concurrently updates +may be lost. Use #concat instead.

+
+
+ +

A thread-safe subclass of Array. This version locks against the object +itself for every method call, ensuring only one thread can be reading +or writing at a time. This includes iteration methods like #each.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Async.html b/docs/1.1.10/Concurrent/Async.html new file mode 100644 index 000000000..f1200de17 --- /dev/null +++ b/docs/1.1.10/Concurrent/Async.html @@ -0,0 +1,755 @@ + + + + + + + Module: Concurrent::Async + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Async + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/async.rb
+
+ +
+ +

Overview

+
+

A mixin module that provides simple asynchronous behavior to a class, +turning it into a simple actor. Loosely based on Erlang's +gen_server, but without +supervision or linking.

+ +

A more feature-rich Actor is also available when the +capabilities of Async are too limited.

+ +
Feature:
+  As a stateful, plain old Ruby class
+  I want safe, asynchronous behavior
+  So my long-running methods don't block the main thread
+
+ +

The Async module is a way to mix simple yet powerful asynchronous +capabilities into any plain old Ruby object or class, turning each object +into a simple Actor. Method calls are processed on a background thread. The +caller is free to perform other actions while processing occurs in the +background.

+ +

Method calls to the asynchronous object are made via two proxy methods: +async (alias cast) and await (alias call). These proxy methods post +the method call to the object's background thread and return a "future" +which will eventually contain the result of the method call.

+ +

This behavior is loosely patterned after Erlang's gen_server behavior. +When an Erlang module implements the gen_server behavior it becomes +inherently asynchronous. The start or start_link function spawns a +process (similar to a thread but much more lightweight and efficient) and +returns the ID of the process. Using the process ID, other processes can +send messages to the gen_server via the cast and call methods. Unlike +Erlang's gen_server, however, Async classes do not support linking or +supervision trees.

+ +

Basic Usage

+ +

When this module is mixed into a class, objects of the class become inherently +asynchronous. Each object gets its own background thread on which to post +asynchronous method calls. Asynchronous method calls are executed in the +background one at a time in the order they are received.

+ +

To create an asynchronous class, simply mix in the Concurrent::Async module:

+ +
class Hello
+  include Concurrent::Async
+
+  def hello(name)
+    "Hello, #{name}!"
+  end
+end
+
+ +

Mixing this module into a class provides each object two proxy methods: +async and await. These methods are thread safe with respect to the +enclosing object. The former proxy allows methods to be called +asynchronously by posting to the object's internal thread. The latter proxy +allows a method to be called synchronously but does so safely with respect +to any pending asynchronous method calls and ensures proper ordering. Both +methods return a IVar which can be inspected for the result +of the proxied method call. Calling a method with async will return a +:pending IVar whereas await will return a :complete IVar.

+ +
class Echo
+  include Concurrent::Async
+
+  def echo(msg)
+    print "#{msg}\n"
+  end
+end
+
+horn = Echo.new
+horn.echo('zero')      # synchronous, not thread-safe
+                       # returns the actual return value of the method
+
+horn.async.echo('one') # asynchronous, non-blocking, thread-safe
+                       # returns an IVar in the :pending state
+
+horn.await.echo('two') # synchronous, blocking, thread-safe
+                       # returns an IVar in the :complete state
+
+ +

Let It Fail

+ +

The async and await proxy methods have built-in error protection based +on Erlang's famous "let it fail" philosophy. Instance methods should not be +programmed defensively. When an exception is raised by a delegated method +the proxy will rescue the exception, expose it to the caller as the reason +attribute of the returned future, then process the next method call.

+ +

Calling Methods Internally

+ +

External method calls should always use the async and await proxy +methods. When one method calls another method, the async proxy should +rarely be used and the await proxy should never be used.

+ +

When an object calls one of its own methods using the await proxy the +second call will be enqueued behind the currently running method call. +Any attempt to wait on the result will fail as the second call will never +run until after the current call completes.

+ +

Calling a method using the await proxy from within a method that was +itself called using async or await will irreversibly deadlock the +object. Do not do this, ever.

+ +

Instance Variables and Attribute Accessors

+ +

Instance variables do not need to be thread-safe so long as they are private. +Asynchronous method calls are processed in the order they are received and +are processed one at a time. Therefore private instance variables can only +be accessed by one thread at a time. This is inherently thread-safe.

+ +

When using private instance variables within asynchronous methods, the best +practice is to read the instance variable into a local variable at the start +of the method then update the instance variable at the end of the method. +This way, should an exception be raised during method execution the internal +state of the object will not have been changed.

+ +

Reader Attributes

+ +

The use of attr_reader is discouraged. Internal state exposed externally, +when necessary, should be done through accessor methods. The instance +variables exposed by these methods must be thread-safe, or they must be +called using the async and await proxy methods. These two approaches are +subtly different.

+ +

When internal state is accessed via the async and await proxy methods, +the returned value represents the object's state at the time the call is +processed, which may not be the state of the object at the time the call +is made.

+ +

To get the state at the current time, irrespective of an enqueued method +calls, a reader method must be called directly. This is inherently unsafe +unless the instance variable is itself thread-safe, preferably using one +of the thread-safe classes within this library. Because the thread-safe +classes within this library are internally-locking or non-locking, they can +be safely used from within asynchronous methods without causing deadlocks.

+ +

Generally speaking, the best practice is to not expose internal state via +reader methods. The best practice is to simply use the method's return value.

+ +

Writer Attributes

+ +

Writer attributes should never be used with asynchronous classes. Changing +the state externally, even when done in the thread-safe way, is not logically +consistent. Changes to state need to be timed with respect to all asynchronous +method calls which my be in-process or enqueued. The only safe practice is to +pass all necessary data to each method as arguments and let the method update +the internal state as necessary.

+ +

Class Constants, Variables, and Methods

+ +

Class Constants

+ +

Class constants do not need to be thread-safe. Since they are read-only and +immutable they may be safely read both externally and from within +asynchronous methods.

+ +

Class Variables

+ +

Class variables should be avoided. Class variables represent shared state. +Shared state is anathema to concurrency. Should there be a need to share +state using class variables they must be thread-safe, preferably +using the thread-safe classes within this library. When updating class +variables, never assign a new value/object to the variable itself. Assignment +is not thread-safe in Ruby. Instead, use the thread-safe update functions +of the variable itself to change the value.

+ +

The best practice is to never use class variables with Async classes.

+ +

Class Methods

+ +

Class methods which are pure functions are safe. Class methods which modify +class variables should be avoided, for all the reasons listed above.

+ +

An Important Note About Thread Safe Guarantees

+ +
+

Thread safe guarantees can only be made when asynchronous method calls +are not mixed with direct method calls. Use only direct method calls +when the object is used exclusively on a single thread. Use only +async and await when the object is shared between threads. Once you +call a method using async or await, you should no longer call methods +directly on the object. Use async and await exclusively from then on.

+
+ + +
+
+
+ +
+

Examples:

+ + +

+class Echo
+  include Concurrent::Async
+
+  def echo(msg)
+    print "#{msg}\n"
+  end
+end
+
+horn = Echo.new
+horn.echo('zero')      # synchronous, not thread-safe
+                       # returns the actual return value of the method
+
+horn.async.echo('one') # asynchronous, non-blocking, thread-safe
+                       # returns an IVar in the :pending state
+
+horn.await.echo('two') # synchronous, blocking, thread-safe
+                       # returns an IVar in the :complete state
+ +
+ + +

See Also:

+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .new(*args, &block) ⇒ Object + + + + + +

+
+

Instanciate a new object and ensure proper initialization of the +synchronization mechanisms.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    Zero or more arguments to be passed to the +object's initializer.

    +
    + +
  • + +
  • + + block + + + (Proc) + + + + — +

    Optional block to pass to the object's initializer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    A properly initialized object of the asynchronous class.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/async.rb', line 219
+
+
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #asyncConcurrent::IVar + + + + Also known as: + cast + + + + +

+
+ +
+ Note: +

The method call is guaranteed to be thread safe with respect to +all other method calls against the same object that are called with +either async or await. The mutable nature of Ruby references +(and object orientation in general) prevent any other thread safety +guarantees. Do NOT mix direct method calls with delegated method calls. +Use only delegated method calls when sharing the object between threads.

+
+
+ +

Causes the chained method call to be performed asynchronously on the +object's thread. The delegated method will return a future in the +:pending state and the method call will have been scheduled on the +object's thread. The final disposition of the method call can be obtained +by inspecting the returned future.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Concurrent::IVar) + + + + — +

    the pending result of the asynchronous operation

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NameError) + + + + — +

    the object does not respond to the requested method

    +
    + +
  • + +
  • + + + (ArgumentError) + + + + — +

    the given args do not match the arity of +the requested method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+412
+413
+414
+
+
# File 'lib/concurrent-ruby/concurrent/async.rb', line 412
+
+def async
+  @__async_delegator__
+end
+
+
+ +
+

+ + #awaitConcurrent::IVar + + + + Also known as: + call + + + + +

+
+ +
+ Note: +

The method call is guaranteed to be thread safe with respect to +all other method calls against the same object that are called with +either async or await. The mutable nature of Ruby references +(and object orientation in general) prevent any other thread safety +guarantees. Do NOT mix direct method calls with delegated method calls. +Use only delegated method calls when sharing the object between threads.

+
+
+ +

Causes the chained method call to be performed synchronously on the +current thread. The delegated will return a future in either the +:fulfilled or :rejected state and the delegated method will have +completed. The final disposition of the delegated method can be obtained +by inspecting the returned future.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Concurrent::IVar) + + + + — +

    the completed result of the synchronous operation

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NameError) + + + + — +

    the object does not respond to the requested method

    +
    + +
  • + +
  • + + + (ArgumentError) + + + + — +

    the given args do not match the arity of the +requested method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+430
+431
+432
+
+
# File 'lib/concurrent-ruby/concurrent/async.rb', line 430
+
+def await
+  @__await_delegator__
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Atom.html b/docs/1.1.10/Concurrent/Atom.html new file mode 100644 index 000000000..457a8c6d4 --- /dev/null +++ b/docs/1.1.10/Concurrent/Atom.html @@ -0,0 +1,1473 @@ + + + + + + + Class: Concurrent::Atom + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Atom + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + +
+
Includes:
+
Concern::Observable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atom.rb
+
+ +
+ +

Overview

+
+

Atoms provide a way to manage shared, synchronous, independent state.

+ +

An atom is initialized with an initial value and an optional validation +proc. At any time the value of the atom can be synchronously and safely +changed. If a validator is given at construction then any new value +will be checked against the validator and will be rejected if the +validator returns false or raises an exception.

+ +

There are two ways to change the value of an atom: #compare_and_set and +#swap. The former will set the new value if and only if it validates and +the current value matches the new value. The latter will atomically set the +new value to the result of running the given block if and only if that +value validates.

+ +

Example

+ +
def next_fibonacci(set = nil)
+  return [0, 1] if set.nil?
+  set + [set[-2..-1].reduce{|sum,x| sum + x }]
+end
+
+# create an atom with an initial value
+atom = Concurrent::Atom.new(next_fibonacci)
+
+# send a few update requests
+5.times do
+  atom.swap{|set| next_fibonacci(set) }
+end
+
+# get the current value
+atom.value #=> [0, 1, 1, 2, 3, 5, 8]
+
+ +

Observation

+ +

Atoms support observers through the Observable mixin module. +Notification of observers occurs every time the value of the Atom changes. +When notified the observer will receive three arguments: time, old_value, +and new_value. The time argument is the time at which the value change +occurred. The old_value is the value of the Atom when the change began +The new_value is the value to which the Atom was set when the change +completed. Note that old_value and new_value may be the same. This is +not an error. It simply means that the change operation returned the same +value.

+ +

Unlike in Clojure, Atom cannot participate in TVar transactions.

+ +

Thread-safe Variable Classes

+ +

Each of the thread-safe variable classes is designed to solve a different +problem. In general:

+ +
    +
  • Agent: Shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately.
  • +
  • Atom: Shared, mutable variable providing independent, +uncoordinated, synchronous change of individual values. Best used when +the value will undergo frequent reads but only occasional, though complex, +updates. Suitable when the result of an update must be known immediately.
  • +
  • AtomicReference: A simple object reference that can be updated +atomically. Updates are synchronous but fast. Best used when updates a +simple set operations. Not suitable when updates are complex. +AtomicBoolean and AtomicFixnum are similar +but optimized for the given data type.
  • +
  • Exchanger: Shared, stateless synchronization point. Used +when two or more threads need to exchange data. The threads will pair then +block on each other until the exchange is complete.
  • +
  • MVar: Shared synchronization point. Used when one thread +must give a value to another, which must take the value. The threads will +block on each other until the exchange is complete.
  • +
  • ThreadLocalVar: Shared, mutable, isolated variable which +holds a different value for each thread which has access. Often used as +an instance variable in objects which must maintain different state +for different threads.
  • +
  • TVar: Shared, mutable variables which provide +coordinated, synchronous, change of many stated. Used when multiple +value must change together, in an all-or-nothing transaction.
  • +
+ + +
+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(value, opts = {}) ⇒ Atom + + + + + +

+
+

Create a new atom with the given initial value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    The initial value

    +
    + +
  • + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    The options used to configure the atom

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :validator + (Proc) + + + — default: + nil + + + + —

    Optional proc used to validate new +values. It must accept one and only one argument which will be the +intended new value. The validator will return true if the new value +is acceptable else return false (preferrably) or raise an exception.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from #value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from #value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the #value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
+ + +

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if the validator is not a Proc (when given)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+121
+122
+123
+124
+125
+126
+
+
# File 'lib/concurrent-ruby/concurrent/atom.rb', line 121
+
+def initialize(value, opts = {})
+  super()
+  @Validator     = opts.fetch(:validator, -> v { true })
+  self.observers = Collection::CopyOnNotifyObserverSet.new
+  self.value     = value
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #compare_and_set(old_value, new_value) ⇒ Boolean + + + + + +

+
+

Atomically sets the value of atom to the new value if and only if the +current value of the atom is identical to the old value and the new +value successfully validates against the (optional) validator given +at construction.

+ + +
+
+
+

Parameters:

+
    + +
  • + + old_value + + + (Object) + + + + — +

    The expected current value.

    +
    + +
  • + +
  • + + new_value + + + (Object) + + + + — +

    The intended new value.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if the value is changed else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+181
+182
+183
+184
+185
+186
+187
+188
+
+
# File 'lib/concurrent-ruby/concurrent/atom.rb', line 181
+
+def compare_and_set(old_value, new_value)
+  if valid?(new_value) && compare_and_set_value(old_value, new_value)
+    observers.notify_observers(Time.now, old_value, new_value)
+    true
+  else
+    false
+  end
+end
+
+
+ +
+

+ + #reset(new_value) ⇒ Object + + + + + +

+
+

Atomically sets the value of atom to the new value without regard for the +current value so long as the new value successfully validates against the +(optional) validator given at construction.

+ + +
+
+
+

Parameters:

+
    + +
  • + + new_value + + + (Object) + + + + — +

    The intended new value.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    The final value of the atom after all operations and +validations are complete.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+
+
# File 'lib/concurrent-ruby/concurrent/atom.rb', line 198
+
+def reset(new_value)
+  old_value = value
+  if valid?(new_value)
+    self.value = new_value
+    observers.notify_observers(Time.now, old_value, new_value)
+    new_value
+  else
+    old_value
+  end
+end
+
+
+ +
+

+ + #swap(*args) {|value, args| ... } ⇒ Object + + + + + +

+
+ +
+ Note: +

The given block may be called multiple times, and thus should be free +of side effects.

+
+
+ +

Atomically swaps the value of atom using the given block. The current +value will be passed to the block, as will any arguments passed as +arguments to the function. The new value will be validated against the +(optional) validator proc given at construction. If validation fails the +value will not be changed.

+ +

Internally, #swap reads the current value, applies the block to it, and +attempts to compare-and-set it in. Since another thread may have changed +the value in the intervening time, it may have to retry, and does so in a +spin loop. The net effect is that the value will always be the result of +the application of the supplied block to a current value, atomically. +However, because the block might be called multiple times, it must be free +of side effects.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    Zero or more arguments passed to the block.

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (value, args) + + + + — +

    Calculates a new value for the atom based on the +current value and any supplied arguments.

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    The current value of the atom.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    All arguments passed to the function, in order.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    The intended new value of the atom.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    The final value of the atom after all operations and +validations are complete.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    When no block is given.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+
+
# File 'lib/concurrent-ruby/concurrent/atom.rb', line 157
+
+def swap(*args)
+  raise ArgumentError.new('no block given') unless block_given?
+
+  loop do
+    old_value = value
+    new_value = yield(old_value, *args)
+    begin
+      break old_value unless valid?(new_value)
+      break new_value if compare_and_set(old_value, new_value)
+    rescue
+      break old_value
+    end
+  end
+end
+
+
+ +
+

+ + #valueObject + + + + Also known as: + deref + + + + +

+
+

The current value of the atom.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    The current value.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/atom.rb', line 104
+
+
+
+
+ +
+

+ + #add_observer(observer = nil, func = :update, &block) ⇒ Object + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Adds an observer to this set. If a block is passed, the observer will be +created by this method and no other params should be passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification. +Default is :update

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the added observer

    +
    + +
  • + +
+ +
+
+ +
+

+ + #count_observersInteger + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Return the number of observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the observers count

    +
    + +
  • + +
+ +
+
+ +
+

+ + #delete_observer(observer) ⇒ Object + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Remove observer as an observer on this object so that it will no +longer receive notifications.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + + — +

    the observer to remove

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the deleted observer

    +
    + +
  • + +
+ +
+
+ +
+

+ + #delete_observersObservable + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Remove all observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+

+ + #with_observer(observer = nil, func = :update, &block) ⇒ Observable + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

As #add_observer but can be used for chaining.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/AtomicBoolean.html b/docs/1.1.10/Concurrent/AtomicBoolean.html new file mode 100644 index 000000000..7933592a6 --- /dev/null +++ b/docs/1.1.10/Concurrent/AtomicBoolean.html @@ -0,0 +1,959 @@ + + + + + + + Class: Concurrent::AtomicBoolean + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::AtomicBoolean + + + +

+
+ +
+
Inherits:
+
+ AtomicBooleanImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb
+
+ +
+ +

Overview

+
+

A boolean value that can be updated atomically. Reads and writes to an atomic +boolean and thread-safe and guaranteed to succeed. Reads and writes may block +briefly but no explicit locking is required.

+ +

Thread-safe Variable Classes

+ +

Each of the thread-safe variable classes is designed to solve a different +problem. In general:

+ +
    +
  • Agent: Shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately.
  • +
  • Atom: Shared, mutable variable providing independent, +uncoordinated, synchronous change of individual values. Best used when +the value will undergo frequent reads but only occasional, though complex, +updates. Suitable when the result of an update must be known immediately.
  • +
  • AtomicReference: A simple object reference that can be updated +atomically. Updates are synchronous but fast. Best used when updates a +simple set operations. Not suitable when updates are complex. +AtomicBoolean and AtomicFixnum are similar +but optimized for the given data type.
  • +
  • Exchanger: Shared, stateless synchronization point. Used +when two or more threads need to exchange data. The threads will pair then +block on each other until the exchange is complete.
  • +
  • MVar: Shared synchronization point. Used when one thread +must give a value to another, which must take the value. The threads will +block on each other until the exchange is complete.
  • +
  • ThreadLocalVar: Shared, mutable, isolated variable which +holds a different value for each thread which has access. Often used as +an instance variable in objects which must maintain different state +for different threads.
  • +
  • TVar: Shared, mutable variables which provide +coordinated, synchronous, change of many stated. Used when multiple +value must change together, in an all-or-nothing transaction. +Performance:
  • +
+ +
Testing with ruby 2.1.2
+Testing with Concurrent::MutexAtomicBoolean...
+  2.790000   0.000000   2.790000 (  2.791454)
+Testing with Concurrent::CAtomicBoolean...
+  0.740000   0.000000   0.740000 (  0.740206)
+
+Testing with jruby 1.9.3
+Testing with Concurrent::MutexAtomicBoolean...
+  5.240000   2.520000   7.760000 (  3.683000)
+Testing with Concurrent::JavaAtomicBoolean...
+  3.340000   0.010000   3.350000 (  0.855000)
+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(initial = false) ⇒ undocumented + + + + + +

+
+

Creates a new AtomicBoolean with the given initial value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + initial + + + (Boolean) + + + (defaults to: false) + + + — +

    the initial value

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+118
+119
+120
+121
+122
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb', line 118
+
+class AtomicBoolean < AtomicBooleanImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #false?Boolean + + + + + +

+
+

Is the current value false

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the current value is false, else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+121
+122
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb', line 118
+
+class AtomicBoolean < AtomicBooleanImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #make_falseBoolean + + + + + +

+
+

Explicitly sets the value to false.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if value has changed, otherwise false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+121
+122
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb', line 118
+
+class AtomicBoolean < AtomicBooleanImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #make_trueBoolean + + + + + +

+
+

Explicitly sets the value to true.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if value has changed, otherwise false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+121
+122
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb', line 118
+
+class AtomicBoolean < AtomicBooleanImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    Short string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+120
+121
+122
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb', line 120
+
+def to_s
+  format '%s value:%s>', super[0..-2], value
+end
+
+
+ +
+

+ + #true?Boolean + + + + + +

+
+

Is the current value true

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the current value is true, else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+121
+122
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb', line 118
+
+class AtomicBoolean < AtomicBooleanImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #valueBoolean + + + + + +

+
+

Retrieves the current Boolean value.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    the current value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+121
+122
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb', line 118
+
+class AtomicBoolean < AtomicBooleanImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #value=(value) ⇒ Boolean + + + + + +

+
+

Explicitly sets the value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Boolean) + + + + — +

    the new value to be set

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    the current value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+121
+122
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb', line 118
+
+class AtomicBoolean < AtomicBooleanImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/AtomicFixnum.html b/docs/1.1.10/Concurrent/AtomicFixnum.html new file mode 100644 index 000000000..109ae5902 --- /dev/null +++ b/docs/1.1.10/Concurrent/AtomicFixnum.html @@ -0,0 +1,1109 @@ + + + + + + + Class: Concurrent::AtomicFixnum + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::AtomicFixnum + + + +

+
+ +
+
Inherits:
+
+ AtomicFixnumImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb
+
+ +
+ +

Overview

+
+

A numeric value that can be updated atomically. Reads and writes to an atomic +fixnum and thread-safe and guaranteed to succeed. Reads and writes may block +briefly but no explicit locking is required.

+ +

Thread-safe Variable Classes

+ +

Each of the thread-safe variable classes is designed to solve a different +problem. In general:

+ +
    +
  • Agent: Shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately.
  • +
  • Atom: Shared, mutable variable providing independent, +uncoordinated, synchronous change of individual values. Best used when +the value will undergo frequent reads but only occasional, though complex, +updates. Suitable when the result of an update must be known immediately.
  • +
  • AtomicReference: A simple object reference that can be updated +atomically. Updates are synchronous but fast. Best used when updates a +simple set operations. Not suitable when updates are complex. +AtomicBoolean and AtomicFixnum are similar +but optimized for the given data type.
  • +
  • Exchanger: Shared, stateless synchronization point. Used +when two or more threads need to exchange data. The threads will pair then +block on each other until the exchange is complete.
  • +
  • MVar: Shared synchronization point. Used when one thread +must give a value to another, which must take the value. The threads will +block on each other until the exchange is complete.
  • +
  • ThreadLocalVar: Shared, mutable, isolated variable which +holds a different value for each thread which has access. Often used as +an instance variable in objects which must maintain different state +for different threads.
  • +
  • TVar: Shared, mutable variables which provide +coordinated, synchronous, change of many stated. Used when multiple +value must change together, in an all-or-nothing transaction. +Performance:
  • +
+ +
Testing with ruby 2.1.2
+Testing with Concurrent::MutexAtomicFixnum...
+  3.130000   0.000000   3.130000 (  3.136505)
+Testing with Concurrent::CAtomicFixnum...
+  0.790000   0.000000   0.790000 (  0.785550)
+
+Testing with jruby 1.9.3
+Testing with Concurrent::MutexAtomicFixnum...
+  5.460000   2.460000   7.920000 (  3.715000)
+Testing with Concurrent::JavaAtomicFixnum...
+  4.520000   0.030000   4.550000 (  1.187000)
+
+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(initial = 0) ⇒ undocumented + + + + + +

+
+

Creates a new AtomicFixnum with the given initial value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + initial + + + (Fixnum) + + + (defaults to: 0) + + + — +

    the initial value

    +
    + +
  • + +
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if the initial value is not a Fixnum

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb', line 135
+
+class AtomicFixnum < AtomicFixnumImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #compare_and_set(expect, update) ⇒ Boolean + + + + + +

+
+

Atomically sets the value to the given updated value if the current +value == the expected value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + expect + + + (Fixnum) + + + + — +

    the expected value

    +
    + +
  • + +
  • + + update + + + (Fixnum) + + + + — +

    the new value

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the value was updated else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb', line 135
+
+class AtomicFixnum < AtomicFixnumImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #decrement(delta = 1) ⇒ Fixnum + + + + + +

+
+

Decreases the current value by the given amount (defaults to 1).

+ + +
+
+
+

Parameters:

+
    + +
  • + + delta + + + (Fixnum) + + + (defaults to: 1) + + + — +

    the amount by which to decrease the current value

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    the current value after decrementation

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb', line 135
+
+class AtomicFixnum < AtomicFixnumImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #increment(delta = 1) ⇒ Fixnum + + + + + +

+
+

Increases the current value by the given amount (defaults to 1).

+ + +
+
+
+

Parameters:

+
    + +
  • + + delta + + + (Fixnum) + + + (defaults to: 1) + + + — +

    the amount by which to increase the current value

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    the current value after incrementation

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb', line 135
+
+class AtomicFixnum < AtomicFixnumImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    Short string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+137
+138
+139
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb', line 137
+
+def to_s
+  format '%s value:%s>', super[0..-2], value
+end
+
+
+ +
+

+ + #update {|Object| ... } ⇒ Object + + + + + +

+
+

Pass the current value to the given block, replacing it +with the block's result. May retry if the value changes +during the block's execution.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (Object) + + + + — +

    Calculate a new value for the atomic reference using +given (old) value

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_value + + + (Object) + + + + — +

    the starting value of the atomic reference

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb', line 135
+
+class AtomicFixnum < AtomicFixnumImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #valueFixnum + + + + + +

+
+

Retrieves the current Fixnum value.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    the current value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb', line 135
+
+class AtomicFixnum < AtomicFixnumImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #value=(value) ⇒ Fixnum + + + + + +

+
+

Explicitly sets the value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Fixnum) + + + + — +

    the new value to be set

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    the current value

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if the new value is not a Fixnum

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb', line 135
+
+class AtomicFixnum < AtomicFixnumImplementation
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], value
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/AtomicMarkableReference.html b/docs/1.1.10/Concurrent/AtomicMarkableReference.html new file mode 100644 index 000000000..c9caa0ac8 --- /dev/null +++ b/docs/1.1.10/Concurrent/AtomicMarkableReference.html @@ -0,0 +1,1268 @@ + + + + + + + Class: Concurrent::AtomicMarkableReference + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::AtomicMarkableReference + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb
+
+ +
+ +

Overview

+
+

An atomic reference which maintains an object reference along with a mark bit +that can be updated atomically.

+ + +
+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(value = nil, mark = false) ⇒ AtomicMarkableReference + + + + + +

+
+

Returns a new instance of AtomicMarkableReference.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 12
+
+def initialize(value = nil, mark = false)
+  super()
+  self.reference = immutable_array(value, mark)
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #compare_and_set(expected_val, new_val, expected_mark, new_mark) ⇒ Boolean + + + + Also known as: + compare_and_swap + + + + +

+
+

Atomically sets the value and mark to the given updated value and +mark given both:

+ +
    +
  • the current value == the expected value &&
  • +
  • the current mark == the expected mark
  • +
+ +

that the actual value was not equal to the expected value or the +actual mark was not equal to the expected mark

+ + +
+
+
+

Parameters:

+
    + +
  • + + expected_val + + + (Object) + + + + — +

    the expected value

    +
    + +
  • + +
  • + + new_val + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
  • + + expected_mark + + + (Boolean) + + + + — +

    the expected mark

    +
    + +
  • + +
  • + + new_mark + + + (Boolean) + + + + — +

    the new mark

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if successful. A false return indicates

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 30
+
+def compare_and_set(expected_val, new_val, expected_mark, new_mark)
+  # Memoize a valid reference to the current AtomicReference for
+  # later comparison.
+  current             = reference
+  curr_val, curr_mark = current
+
+  # Ensure that that the expected marks match.
+  return false unless expected_mark == curr_mark
+
+  if expected_val.is_a? Numeric
+    # If the object is a numeric, we need to ensure we are comparing
+    # the numerical values
+    return false unless expected_val == curr_val
+  else
+    # Otherwise, we need to ensure we are comparing the object identity.
+    # Theoretically, this could be incorrect if a user monkey-patched
+    # `Object#equal?`, but they should know that they are playing with
+    # fire at that point.
+    return false unless expected_val.equal? curr_val
+  end
+
+  prospect = immutable_array(new_val, new_mark)
+
+  compare_and_set_reference current, prospect
+end
+
+
+ +
+

+ + #getArray + + + + + +

+
+

Gets the current reference and marked values.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Array) + + + + — +

    the current reference and marked values

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+61
+62
+63
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 61
+
+def get
+  reference
+end
+
+
+ +
+

+ + #markBoolean + + + + Also known as: + marked? + + + + +

+
+

Gets the current marked value

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    the current marked value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+75
+76
+77
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 75
+
+def mark
+  reference[1]
+end
+
+
+ +
+

+ + #set(new_val, new_mark) ⇒ Array + + + + + +

+
+

Unconditionally sets to the given value of both the reference and +the mark.

+ + +
+
+
+

Parameters:

+
    + +
  • + + new_val + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
  • + + new_mark + + + (Boolean) + + + + — +

    the new mark

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Array) + + + + — +

    both the new value and the new mark

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+88
+89
+90
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 88
+
+def set(new_val, new_mark)
+  self.reference = immutable_array(new_val, new_mark)
+end
+
+
+ +
+

+ + #try_update {|Object| ... } ⇒ Array + + + + + +

+
+

Pass the current value to the given block, replacing it with the +block's result. Simply return nil if update fails.

+ +

the update failed

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (Object) + + + + — +

    Calculate a new value and marked state for the atomic +reference using given (old) value and (old) marked

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_val + + + (Object) + + + + — +

    the starting value of the atomic reference

    +
    + +
  • + +
  • + + old_mark + + + (Boolean) + + + + — +

    the starting state of marked

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Array) + + + + — +

    the new value and marked state, or nil if

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+149
+150
+151
+152
+153
+154
+155
+156
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 149
+
+def try_update
+  old_val, old_mark = reference
+  new_val, new_mark = yield old_val, old_mark
+
+  return unless compare_and_set old_val, new_val, old_mark, new_mark
+
+  immutable_array(new_val, new_mark)
+end
+
+
+ +
+

+ + #try_update! {|Object| ... } ⇒ Array + + + + + +

+
+

Pass the current value to the given block, replacing it +with the block's result. Raise an exception if the update +fails.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (Object) + + + + — +

    Calculate a new value and marked state for the atomic +reference using given (old) value and (old) marked

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_val + + + (Object) + + + + — +

    the starting value of the atomic reference

    +
    + +
  • + +
  • + + old_mark + + + (Boolean) + + + + — +

    the starting state of marked

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Array) + + + + — +

    the new value and marked state

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 125
+
+def try_update!
+  old_val, old_mark = reference
+  new_val, new_mark = yield old_val, old_mark
+
+  unless compare_and_set old_val, new_val, old_mark, new_mark
+    fail ::Concurrent::ConcurrentUpdateError,
+         'AtomicMarkableReference: Update failed due to race condition.',
+         'Note: If you would like to guarantee an update, please use ' +
+             'the `AtomicMarkableReference#update` method.'
+  end
+
+  immutable_array(new_val, new_mark)
+end
+
+
+ +
+

+ + #update {|Object| ... } ⇒ Array + + + + + +

+
+

Pass the current value and marked state to the given block, replacing it +with the block's results. May retry if the value changes during the +block's execution.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (Object) + + + + — +

    Calculate a new value and marked state for the atomic +reference using given (old) value and (old) marked

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_val + + + (Object) + + + + — +

    the starting value of the atomic reference

    +
    + +
  • + +
  • + + old_mark + + + (Boolean) + + + + — +

    the starting state of marked

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Array) + + + + — +

    the new value and new mark

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 102
+
+def update
+  loop do
+    old_val, old_mark = reference
+    new_val, new_mark = yield old_val, old_mark
+
+    if compare_and_set old_val, new_val, old_mark, new_mark
+      return immutable_array(new_val, new_mark)
+    end
+  end
+end
+
+
+ +
+

+ + #valueObject + + + + + +

+
+

Gets the current value of the reference

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of the reference

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+68
+69
+70
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb', line 68
+
+def value
+  reference[0]
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/AtomicReference.html b/docs/1.1.10/Concurrent/AtomicReference.html new file mode 100644 index 000000000..3c5966883 --- /dev/null +++ b/docs/1.1.10/Concurrent/AtomicReference.html @@ -0,0 +1,1258 @@ + + + + + + + Class: Concurrent::AtomicReference + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::AtomicReference + + + +

+
+ +
+
Inherits:
+
+ AtomicReferenceImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb
+
+ +
+ +

Overview

+
+

An object reference that may be updated atomically. All read and write +operations have java volatile semantic.

+ +

Thread-safe Variable Classes

+ +

Each of the thread-safe variable classes is designed to solve a different +problem. In general:

+ +
    +
  • Agent: Shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately.
  • +
  • Atom: Shared, mutable variable providing independent, +uncoordinated, synchronous change of individual values. Best used when +the value will undergo frequent reads but only occasional, though complex, +updates. Suitable when the result of an update must be known immediately.
  • +
  • AtomicReference: A simple object reference that can be updated +atomically. Updates are synchronous but fast. Best used when updates a +simple set operations. Not suitable when updates are complex. +AtomicBoolean and AtomicFixnum are similar +but optimized for the given data type.
  • +
  • Exchanger: Shared, stateless synchronization point. Used +when two or more threads need to exchange data. The threads will pair then +block on each other until the exchange is complete.
  • +
  • MVar: Shared synchronization point. Used when one thread +must give a value to another, which must take the value. The threads will +block on each other until the exchange is complete.
  • +
  • ThreadLocalVar: Shared, mutable, isolated variable which +holds a different value for each thread which has access. Often used as +an instance variable in objects which must maintain different state +for different threads.
  • +
  • TVar: Shared, mutable variables which provide +coordinated, synchronous, change of many stated. Used when multiple +value must change together, in an all-or-nothing transaction.
  • +
+ + +
+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(value = nil) ⇒ undocumented + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + (defaults to: nil) + + + — +

    The initial value.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 196
+
+class AtomicReference < AtomicReferenceImplementation
+
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], get
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #compare_and_set(old_value, new_value) ⇒ Boolean + + + + + +

+
+

Atomically sets the value to the given updated value if +the current value == the expected value.

+ +

that the actual value was not equal to the expected value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + old_value + + + (Object) + + + + — +

    the expected value

    +
    + +
  • + +
  • + + new_value + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if successful. A false return indicates

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 196
+
+class AtomicReference < AtomicReferenceImplementation
+
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], get
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #getObject + + + + + +

+
+

Gets the current value.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 196
+
+class AtomicReference < AtomicReferenceImplementation
+
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], get
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #get_and_set(new_value) ⇒ Object + + + + + +

+
+

Atomically sets to the given value and returns the old value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + new_value + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the old value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 196
+
+class AtomicReference < AtomicReferenceImplementation
+
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], get
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #set(new_value) ⇒ Object + + + + + +

+
+

Sets to the given value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + new_value + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 196
+
+class AtomicReference < AtomicReferenceImplementation
+
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], get
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    Short string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+199
+200
+201
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 199
+
+def to_s
+  format '%s value:%s>', super[0..-2], get
+end
+
+
+ +
+

+ + #try_update {|Object| ... } ⇒ Object + + + + + +

+
+ +
+ Note: +

This method was altered to avoid raising an exception by default. +Instead, this method now returns nil in case of failure. For more info, +please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336

+
+
+ +

Pass the current value to the given block, replacing it +with the block's result. Return nil if the update fails.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (Object) + + + + — +

    Calculate a new value for the atomic reference using +given (old) value

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_value + + + (Object) + + + + — +

    the starting value of the atomic reference

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value, or nil if update failed

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 196
+
+class AtomicReference < AtomicReferenceImplementation
+
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], get
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #try_update! {|Object| ... } ⇒ Object + + + + + +

+
+ +
+ Note: +

This behavior mimics the behavior of the original +AtomicReference#try_update API. The reason this was changed was to +avoid raising exceptions (which are inherently slow) by default. For more +info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336

+
+
+ +

Pass the current value to the given block, replacing it +with the block's result. Raise an exception if the update +fails.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (Object) + + + + — +

    Calculate a new value for the atomic reference using +given (old) value

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_value + + + (Object) + + + + — +

    the starting value of the atomic reference

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 196
+
+class AtomicReference < AtomicReferenceImplementation
+
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], get
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+

+ + #update {|Object| ... } ⇒ Object + + + + + +

+
+

Pass the current value to the given block, replacing it +with the block's result. May retry if the value changes +during the block's execution.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (Object) + + + + — +

    Calculate a new value for the atomic reference using +given (old) value

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_value + + + (Object) + + + + — +

    the starting value of the atomic reference

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+196
+197
+198
+199
+200
+201
+202
+203
+204
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb', line 196
+
+class AtomicReference < AtomicReferenceImplementation
+
+  # @return [String] Short string representation.
+  def to_s
+    format '%s value:%s>', super[0..-2], get
+  end
+
+  alias_method :inspect, :to_s
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/CachedThreadPool.html b/docs/1.1.10/Concurrent/CachedThreadPool.html new file mode 100644 index 000000000..654d44f45 --- /dev/null +++ b/docs/1.1.10/Concurrent/CachedThreadPool.html @@ -0,0 +1,389 @@ + + + + + + + Class: Concurrent::CachedThreadPool + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::CachedThreadPool + + + +

+
+ +
+
Inherits:
+
+ ThreadPoolExecutor + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Failure to properly shutdown a thread pool can lead to unpredictable results. +Please read Shutting Down Thread Pools for more information.

+
+
+ +

A thread pool that dynamically grows and shrinks to fit the current workload. +New threads are created as needed, existing threads are reused, and threads +that remain idle for too long are killed and removed from the pool. These +pools are particularly suited to applications that perform a high volume of +short-lived tasks.

+ +

On creation a CachedThreadPool has zero running threads. New threads are +created on the pool as new operations are #post. The size of the pool +will grow until #max_length threads are in the pool or until the number +of threads exceeds the number of running and pending operations. When a new +operation is post to the pool the first available idle thread will be tasked +with the new operation.

+ +

Should a thread crash for any reason the thread will immediately be removed +from the pool. Similarly, threads which remain idle for an extended period +of time will be killed and reclaimed. Thus these thread pools are very +efficient at reclaiming unused resources.

+ +

The API and behavior of this class are based on Java's CachedThreadPool

+ +

Thread Pool Options

+ +

Thread pools support several configuration options:

+ +
    +
  • idletime: The number of seconds that a thread may be idle before being reclaimed.
  • +
  • name: The name of the executor (optional). Printed in the executor's #to_s output and +a <name>-worker-<id> name is given to its threads if supported by used Ruby +implementation. <id> is uniq for each thread.
  • +
  • max_queue: The maximum number of tasks that may be waiting in the work queue at +any one time. When the queue size reaches max_queue and no new threads can be created, +subsequent tasks will be rejected in accordance with the configured fallback_policy.
  • +
  • auto_terminate: When true (default), the threads started will be marked as daemon.
  • +
  • fallback_policy: The policy defining how rejected tasks are handled.
  • +
+ +

Three fallback policies are supported:

+ +
    +
  • :abort: Raise a RejectedExecutionError exception and discard the task.
  • +
  • :discard: Discard the task and return false.
  • +
  • :caller_runs: Execute the task on the calling thread.
  • +
+ +

Shutting Down Thread Pools

+ +

Killing a thread pool while tasks are still being processed, either by calling +the #kill method or at application exit, will have unpredictable results. There +is no way for the thread pool to know what resources are being used by the +in-progress tasks. When those tasks are killed the impact on those resources +cannot be predicted. The best practice is to explicitly shutdown all thread +pools using the provided methods:

+ +
    +
  • Call #shutdown to initiate an orderly termination of all in-progress tasks
  • +
  • Call #wait_for_termination with an appropriate timeout interval an allow +the orderly shutdown to complete
  • +
  • Call #kill only when the thread pool fails to shutdown in the allotted time
  • +
+ +

On some runtime platforms (most notably the JVM) the application will not +exit until all thread pools have been shutdown. To prevent applications from +"hanging" on exit, all threads can be marked as daemon according to the +:auto_terminate option.

+ +
pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon
+pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon
+
+ + +
+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(opts = {}) ⇒ CachedThreadPool + + + + + +

+
+

Create a new thread pool.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options defining pool behavior.

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :fallback_policy + (Symbol) + + + — default: + `:abort` + + + + —

    the fallback policy

    +
    + +
  • + +
+ + +

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if fallback_policy is not a known policy

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb', line 39
+
+def initialize(opts = {})
+  defaults  = { idletime: DEFAULT_THREAD_IDLETIMEOUT }
+  overrides = { min_threads: 0,
+                max_threads: DEFAULT_MAX_POOL_SIZE,
+                max_queue:   DEFAULT_MAX_QUEUE_SIZE }
+  super(defaults.merge(opts).merge(overrides))
+end
+
+
+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Cancellation.html b/docs/1.1.10/Concurrent/Cancellation.html new file mode 100644 index 000000000..43d69c121 --- /dev/null +++ b/docs/1.1.10/Concurrent/Cancellation.html @@ -0,0 +1,1137 @@ + + + + + + + Class: Concurrent::Cancellation + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Cancellation + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

The Cancellation abstraction provides cooperative cancellation.

+ +

The standard methods Thread#raise of Thread#kill available in Ruby +are very dangerous (see linked the blog posts bellow). +Therefore concurrent-ruby provides an alternative.

+ + + +

It provides an object which represents a task which can be executed, +the task has to get the reference to the object and periodically cooperatively check that it is not cancelled. +Good practices to make tasks cancellable:

+ +
    +
  • check cancellation every cycle of a loop which does significant work,
  • +
  • do all blocking actions in a loop with a timeout then on timeout check cancellation +and if ok block again with the timeout
  • +
+ +

The idea was inspired by https://msdn.microsoft.com/en-us/library/dd537607(v=vs.110).aspx +

Examples

+ +

Run async task until cancelled

+ +

Create cancellation and then run work in a background thread until it is cancelled.

+ +
cancellation, origin = Concurrent::Cancellation.new
+# => #
+# - origin is used for cancelling, resolve it to cancel 
+# - cancellation is passed down to tasks for cooperative cancellation
+async_task = Concurrent::Promises.future(cancellation) do |cancellation|
+  # Do work repeatedly until it is cancelled
+  do_stuff until cancellation.canceled?
+  :stopped_gracefully
+end
+# => #
+
+sleep 0.01                               # => 0
+# Wait a bit then stop the thread by resolving the origin of the cancellation
+origin.resolve 
+# => #
+async_task.value!                        # => :stopped_gracefully
+
+ +

Or let it raise an error.

+ +
cancellation, origin = Concurrent::Cancellation.new
+# => #
+async_task = Concurrent::Promises.future(cancellation) do |cancellation|
+  # Do work repeatedly until it is cancelled
+  while true
+    cancellation.check!     
+    do_stuff 
+  end
+end
+# => #
+
+sleep 0.01                               # => 0
+# Wait a bit then stop the thread by resolving the origin of the cancellation
+origin.resolve 
+# => #
+async_task.result
+# => [false,
+#     nil,
+#     #]
+
+ +

Run additional tasks on Cancellation

+ +

Cancellation can also be used to log or plan re-execution.

+ +
cancellation.origin.chain do
+  # This block is executed after the Cancellation is cancelled  
+  # It can then log cancellation or e.g. plan new re-execution
+end
+# => #
+
+ +

Run only for limited time – Timeout replacement

+ +

Execute task for a given time then finish. +Instead of letting Cancellation crate its own origin, it can be passed in as argument. +The passed in origin is scheduled to be resolved in given time which then cancels the Cancellation.

+ +
timeout = Concurrent::Cancellation.new Concurrent::Promises.schedule(0.02)
+# => #
+# or using shortcut helper method
+timeout = Concurrent::Cancellation.timeout 0.02 
+# => #
+count   = Concurrent::AtomicFixnum.new
+# => #
+Concurrent.global_io_executor.post(timeout) do |timeout|
+  # do stuff until cancelled  
+  count.increment until timeout.canceled?
+end 
+
+timeout.origin.wait
+# => #
+count.value                              # => 177576
+
+ +

Parallel background processing with single cancellation

+ +

Each task tries to count to 1000 but there is a randomly failing test. The +tasks share single cancellation, when one of them fails it cancels the others. +The failing tasks ends with an error, the other tasks are gracefully cancelled.

+ +
cancellation, origin = Concurrent::Cancellation.new
+# => #
+tasks = 4.times.map do |i|
+  Concurrent::Promises.future(cancellation, origin, i) do |cancellation, origin, i|
+    count = 0
+    100.times do
+      break count = :cancelled if cancellation.canceled?
+      count += 1
+      sleep 0.001
+      if rand > 0.95
+        origin.resolve # cancel
+        raise 'random error'
+      end
+      count
+    end
+  end
+end
+# => [#,
+#     #,
+#     #,
+#     #]
+Concurrent::Promises.zip(*tasks).result 
+# => [false,
+#     [:cancelled, nil, :cancelled, :cancelled],
+#     [nil, #, nil, nil]]
+
+ +

Without the randomly failing part it produces following.

+ +
cancellation, origin = Concurrent::Cancellation.new
+# => #
+tasks = 4.times.map do |i|
+  Concurrent::Promises.future(cancellation, origin, i) do |cancellation, origin, i|
+    count = 0
+    100.times do
+      break count = :cancelled if cancellation.canceled?
+      count += 1
+      sleep 0.001
+      # if rand > 0.95
+      #   origin.resolve
+      #   raise 'random error'
+      # end
+      count
+    end
+  end
+end
+# => [#,
+#     #,
+#     #,
+#     #]
+Concurrent::Promises.zip(*tasks).result
+# => [true, [100, 100, 100, 100], nil]
+
+ +

Combine cancellations

+ +

The combination created by joining two cancellations cancels when the first or the other does.

+ +
cancellation_a, origin_a = Concurrent::Cancellation.new
+# => #
+cancellation_b, origin_b = Concurrent::Cancellation.new
+# => #
+combined_cancellation    = cancellation_a.join(cancellation_b)
+# => #
+
+origin_a.resolve
+# => #
+
+cancellation_a.canceled?                 # => true
+cancellation_b.canceled?                 # => false
+combined_cancellation.canceled?          # => true
+
+ +

If a different rule for joining is needed, the source can be combined manually. +The manually created cancellation cancels when both the first and the other cancels.

+ +
cancellation_a, origin_a = Concurrent::Cancellation.new
+# => #
+cancellation_b, origin_b = Concurrent::Cancellation.new
+# => #
+# cancels only when both a and b is cancelled
+combined_cancellation    = Concurrent::Cancellation.new origin_a & origin_b
+# => #
+
+origin_a.resolve
+# => #
+
+cancellation_a.canceled?        #=> true
+cancellation_b.canceled?        #=> false
+combined_cancellation.canceled? #=> false
+
+origin_b.resolve
+# => #
+combined_cancellation.canceled? #=> true
+
+

+ + +
+
+
+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(origin = Promises.resolvable_event) ⇒ Cancellation + + + + + +

+
+

Creates the cancellation object.

+ + +
+
+
+ +
+

Examples:

+ + +
cancellation, origin = Concurrent::Cancellation.new
+ +
+

Parameters:

+
    + +
  • + + origin + + + (Promises::Future, Promises::Event) + + + (defaults to: Promises.resolvable_event) + + + — +

    of the cancellation. +When it is resolved the cancellation is canceled.

    +
    + +
  • + +
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+52
+53
+54
+55
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb', line 52
+
+def initialize(origin = Promises.resolvable_event)
+  super()
+  @Origin = origin
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .timeout(intended_time) ⇒ Cancellation + + + + + +

+
+

Create Cancellation which will cancel itself in given time

+ + +
+
+
+

Parameters:

+
    + +
  • + + intended_time + + + (Numeric, Time) + + + + — +

    Numeric means to run in intended_time seconds. +Time means to run on intended_time.

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+41
+42
+43
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb', line 41
+
+def self.timeout(intended_time)
+  new Concurrent::Promises.schedule(intended_time)
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #canceled?true, false + + + + + +

+
+

Is the cancellation cancelled? +Respective, was the origin of the cancellation resolved.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+75
+76
+77
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb', line 75
+
+def canceled?
+  @Origin.resolved?
+end
+
+
+ +
+

+ + #check!(error = CancelledOperationError) ⇒ self + + + + + +

+
+

Raise error when cancelled

+ + +
+
+
+

Parameters:

+
    + +
  • + + error + + + (#exception) + + + (defaults to: CancelledOperationError) + + + — +

    to be risen

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+

Raises:

+
    + +
  • + + + + + + + +

    the error

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+83
+84
+85
+86
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb', line 83
+
+def check!(error = CancelledOperationError)
+  raise error if canceled?
+  self
+end
+
+
+ +
+

+ + #join(*cancellations) ⇒ Cancellation + + + + + +

+
+

Creates a new Cancellation which is cancelled when first +of the supplied cancellations or self is cancelled.

+ + +
+
+
+

Parameters:

+
    + +
  • + + cancellations + + + (Cancellation) + + + + — +

    to combine

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Cancellation) + + + + — +

    new cancellation

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+93
+94
+95
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb', line 93
+
+def join(*cancellations)
+  Cancellation.new Promises.any_event(*[@Origin, *cancellations.map(&:origin)])
+end
+
+
+ +
+

+ + #originPromises::Future, Promises::Event + + + + + +

+
+

The event or future which is the origin of the cancellation

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+68
+69
+70
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb', line 68
+
+def origin
+  @Origin
+end
+
+
+ +
+

+ + #to_aryArray(Cancellation, Promises::Future), Array(Cancellation, Promises::Event) + + + + + +

+
+

Allow to multi-assign the Cancellation object

+ + +
+
+
+ +
+

Examples:

+ + +
cancellation         = Concurrent::Cancellation.new
+cancellation, origin = Concurrent::Cancellation.new
+ +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+62
+63
+64
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb', line 62
+
+def to_ary
+  [self, @Origin]
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + +
  • + +
+ +
+ + + + +
+
+
+
+99
+100
+101
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/cancellation.rb', line 99
+
+def to_s
+  format '%s %s>', super[0..-2], canceled? ? 'canceled' : 'pending'
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel.html b/docs/1.1.10/Concurrent/Channel.html new file mode 100644 index 000000000..fec25f5f6 --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel.html @@ -0,0 +1,2325 @@ + + + + + + + Class: Concurrent::Channel + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + +
+
Extended by:
+
Forwardable
+
+ + + +
+
Includes:
+
Enumerable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel.rb,
+ lib/concurrent-ruby-edge/concurrent/channel/tick.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/ticker.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/put_clause.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/take_clause.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/after_clause.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/error_clause.rb,
lib/concurrent-ruby-edge/concurrent/channel/selector/default_clause.rb
+
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Channels and Goroutines

+ +

Channels, popularized by the Go programming language, are a modern variation of communicating sequential processes (CSP). CSP was first proposed by C. A. R. Hoare in 1978. The Go philosophy on concurrency is:

+ +
+

Do not communicate by sharing memory; instead, share memory by communicating.

+
+ +

As Rob Pike eloquently explains in his Concurrency Is Not Parallelism conference talk, concurrency is the "composition of independently executing things." Combining these two ideas, channels are a queue-like mechanism that can be used to communicate between independently executing things.

+ +

The channel implementation in this library was highly influenced by Go, but also incorporates ideas from Clojure's core.async library. Runtime differences aside, this channel library is functionally equivalent to Go and even includes a few features Go does not.

+ +

Example Programs

+ +

Every code example in the channel chapters of both A Tour of Go and Go By Example has been reproduced in Ruby. The code can be found in the examples directory of the source repository. Many of those examples appear in the documentation below, but many do not. They are a valuable resource for learning how to use channels.

+ +

Additional Resources

+ + + +

Goroutines

+ +

The Go programming language uses "goroutines" as the core concurrency mechanism. A goroutine is little more than an independently executing function, multiplexed with all other goroutines onto a thread pool managed by the runtime. Ruby has a very different runtime so true goroutines are not possible. Instead, a Channel.go method is provided for running a block asynchronously, multiplexed onto a special thread pool reserved just for Channel operations. This is similar to what Clojure does with the go function from the core.async library.

+ +
puts "Main thread: #{Thread.current}"
+
+Concurrent::Channel.go do
+  puts "Goroutine thread: #{Thread.current}"
+end
+
+# Main thread: #
+# Goroutine thread: #
+
+ +

Although it is possible to use Channel.go independent of channels or to use channels with other asynchronous processing tools (such as Future and Actor), mixing the tools is not advised. Most high-level asynchronous processing tools already have a queue-like mechanism built in. Adding channels to the mix may indicate a design flaw. Conversely, Channel.go provides no mechanism for coordination and communication. That's what channels are for. Additionally, strictly using Channel.go along with channels provides an opportunity for future optimizations, such as Clojure's inversion of control (IOC) threads.

+ +

Channel Basics

+ +

Channels are "pipes" through which values can be sent. They are thread safe and naturally concurrent. When shared between goroutines they provide a communication mechanism for coordinating asynchronous actions.

+ +

The core channel operations are #put and #take (aliased as #send and #receive, respectively). The former function inserts a value into a channel where the latter removes a value. By default these are blocking operations. A call to put will block until the channel is ready to receive the value. Similarly, a call to take will block until a value is available to be removed.

+ +

The following, simple example creates a channel, launches a goroutine from which a value is placed into the channel, then reads that value from the channel. When run this example will display "ping" in the console.

+ +
messages = Concurrent::Channel.new
+
+Concurrent::Channel.go do
+  messages.put 'ping'
+end
+
+msg = messages.take
+puts msg
+
+ +

By default, channels are unbuffered, meaning that they have a capacity of zero and only accept puts and takes when both a putting and a taking thread are available. If a put is started when there is no taker thread the call will block. As soon as another thread calls take the exchange will occur and both calls will return on their respective threads. Similarly, if a take is started when there is no putting thread the call will block until another thread calls put.

+ +

The following, slightly more complex example, concurrently sums two different halves of a list then combines the results. It uses an unbuffered channel to pass the results from the two goroutines back to the main thread. The main thread blocks on the two take calls until the worker goroutines are done. This example also uses the convenience aliases #<< and #~. Since channels in Go are part of the language, channel operations are performed using special channel operators rather than functions. These operators help clearly indicate that channel operations are being performed. The operator overloads << for put and ~ for take help reinforce this idea in Ruby.

+ +
def sum(a, c)
+  sum = a.reduce(0, &:+)
+  c << sum # `<<` is an alias for `put` or `send`
+end
+
+a = [7, 2, 8, -9, 4, 0]
+l = a.length / 2
+c = Concurrent::Channel.new
+
+Concurrent::Channel.go { sum(a[-l, l], c) }
+Concurrent::Channel.go { sum(a[0, l], c) }
+x, y = ~c, ~c # `~` is an alias for `take` or `receive`
+
+puts [x, y, x+y].join(' ')
+
+ +

Channel Buffering

+ +

One common channel variation is a buffered channel. A buffered channel has a finite number of slots in the buffer which can be filled. Putting threads can put values into the channel even if there is no taking threads, up to the point where the buffer is filled. Once a buffer becomes full the normal blocking behavior resumes. A buffered channel is created by giving a :capacity option on channel creation:

+ +

The following example creates a buffered channel with two slots. It then makes two put calls, adding values to the channel. These calls do not block because the buffer has room. Were a third put call to be made before an take calls, the third put would block.

+ +
ch = Concurrent::Channel.new(capacity: 2)
+ch << 1
+ch << 2
+
+puts ~ch
+puts ~ch
+
+ +

Channel Synchronization

+ +

The main purpose of channels is to synchronize operations across goroutines. One common pattern for this is to create a capacity: 1 buffered channel which is used to signal that work is complete. The following example calls a worker function on a goroutine and passes it a "done" channel. The main thread then calls take on the "done" channel and blocks until signaled.

+ +
def worker(done_channel)
+  print "working...\n"
+  sleep(1)
+  print "done\n"
+
+  done_channel << true
+end
+
+done = Concurrent::Channel.new(capacity: 1)
+Concurrent::Channel.go{ worker(done) }
+
+~done # block until signaled
+
+ +

Multichannel Select

+ +

Often it is necessary for a single thread to operate on more than one channel. The Channel.select method facilitates multivariate channel operations. The select method takes a block and passes through a special "selector" object as the first block parameter. The selector can then be used to specify various channel operations. The select call will block until one of the operations occurs. If a block is provided for the triggered clause (required for some clauses, optional for others) the block will then be called. Finally, the select call will immediately exit, guaranteeing that only one of the select clauses will trigger.

+ +

The following example spawns two goroutines, each of which goes to sleep before putting a value onto a channel. The main thread loops twice over a select and, in each loop, takes a value off of whichever channel returns one first.

+ +
c1 = Concurrent::Channel.new
+c2 = Concurrent::Channel.new
+
+Concurrent::Channel.go do
+  sleep(1)
+  c1 << 'one'
+end
+
+Concurrent::Channel.go do
+  sleep(2)
+  c1 << 'two'
+end
+
+2.times do
+  Concurrent::Channel.select do |s|
+    s.take(c1) { |msg| print "received #{msg}\n" }
+    s.take(c2) { |msg| print "received #{msg}\n" }
+  end
+end
+
+ +

The output from the above example is:

+ +
received one
+received two
+
+ +

The next example calculates the first 10 fibonacci numbers, passing them to the main thread via a channel. The fibonacci function puts each calculated value onto a channel while simultaneously listening to a different channel for the signal to stop. This example uses the case method on the selector object. This is just a convenience method for put and take, allowing the Ruby code to look more like Go.

+ +
def fibonacci(c, quit)
+  x, y = 0, 1
+  loop do
+    Concurrent::Channel.select do |s|
+      s.case(c, :<<, x) { x, y = y, x+y; x } # alias for `s.put`
+      s.case(quit, :~) do                    # alias for `s.take`
+        puts 'quit'
+        return
+      end
+    end
+  end
+end
+
+c = Concurrent::Channel.new
+quit = Concurrent::Channel.new
+
+Concurrent::Channel.go do
+  10.times { puts ~c }
+  quit << 0
+end
+
+fibonacci(c, quit)
+
+ +

Closing and Iterating Over Channels

+ +

Newly created channels are in an "open" state. Open channels can receive values via put operations. When a program is done with a channel it can be closed by calling the #close method. Once a channel is closed it will no longer allow values to be put. If the channel is buffered and values are in the buffer when the channel is closed, the remaining values can still be removed via take operations.

+ +

The Channel class implements an #each method which can be used to retrieve successive values from the channel. The each method is a blocking method. When the channel is open and there are no values in the buffer, each will block until a new item is put. The each method will not exit until the channel is closed.

+ +

The following example launches a goroutine which calculates several fibonacci values and puts them into a channel. The main thread uses the each method to retrieve all the values successively and display them in the console. Once the fibonacci goroutine is done it closes the channel which subsequently causes the each iteration to end, unblocking the main thread.

+ +
def fibonacci(n, c)
+  x, y = 0, 1
+  (1..n).each do
+    c << x
+    x, y = y, x+y
+  end
+  c.close
+end
+
+chan = Concurrent::Channel.new(capacity: 10)
+Concurrent::Channel.go { fibonacci(chan.capacity, chan) }
+chan.each { |i| puts i }
+
+ +

Channel also includes Ruby's Enumerable mixin, allowing for a wide range of list comprehensions. Since the Enumerable methods iterate over the entire set of objects they can only complete once the channel is closed. Calling a method from Enumerable on an open channel will cause the method to block until the channel is closed.

+ +

Timers and Tickers

+ +

A Channel.timer is a specialized channel which triggers at a predefined time, specified as a number of seconds in the future. It is similar in concept to a ScheduledTask but operates as a channel and can fully participate in all channel operations.

+ +

The following code example creates two timers with different delay values. The first timer is allowed to expire (trigger) by having the main thread perform a take on it. When the timer expires it puts a Tick object into its buffer and closes. The second timer is listened to on a goroutine but the it never expires: the main thread stops (closes) the timer before it expires. Note that the goroutine in this example blocks forever and never exits. Since the timer is closed it never puts the Tick into its buffer.

+ +
timer1 = Concurrent::Channel.timer(2)
+
+~timer1
+puts 'Timer 1 expired'
+
+timer2 = Concurrent::Channel.timer(1)
+Concurrent::Channel.go do
+  ~timer2
+  print "Timer 2 expired\n"
+end
+
+stop2 = timer2.stop # alias for `close`
+print "Timer 2 stopped\n" if stop2
+
+ +

A Channel.ticker is a specialized channel which triggers over and over again at a predefined interval, specified as a number of seconds between ticks. It is similar in concept to a TimerTask but operates as a channel and can fully participate in all channel operations.

+ +

The following example creates a ticker which triggers every half-second. A goroutine iterates over the ticker using the each method, printing the tick at every interval. When the main thread stops (closes) the ticker the each call ends and the goroutine exits.

+ +
ticker = Concurrent::Channel.ticker(0.5)
+Concurrent::Channel.go do
+  ticker.each do |tick|
+    print "Tick at #{tick}\n"
+  end
+end
+
+sleep(1.6)
+ticker.stop # alias for `close`
+print "Ticker stopped\n"
+
+ +

Default Selection

+ +

As with a Ruby case statement, a Channel.select statement will accept a default clause which will trigger if none of the other clauses trigger. Not surprisingly, the default clause must be the last clause in a select block.

+ +
tick = Concurrent::Channel.tick(0.1)  # alias for `ticker`
+boom = Concurrent::Channel.after(0.5) # alias for `timer`
+
+loop do
+  Concurrent::Channel.select do |s|
+    s.take(tick) { print "tick.\n" }
+    s.take(boom) do
+      print "BOOM!\n"
+      exit
+    end
+    s.default do
+      print "    .\n"
+      sleep(0.05)
+    end
+  end
+end
+
+ +

The output of this code example is:

+ +
.
+.
+tick.
+.
+.
+tick.
+.
+.
+tick.
+.
+.
+tick.
+.
+.
+tick.
+BOOM!
+
+

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: Buffer + + + + Classes: Tick, ValidationError + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
Error = +
+
+ + +
+
+
+ + +
+
+
Class.new(StandardError)
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(opts = {}) ⇒ Channel + + + + + +

+
+

Returns a new instance of Channel.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 47
+
+def initialize(opts = {})
+  # undocumented -- for internal use only
+  if opts.is_a? Buffer::Base
+    self.buffer = opts
+    return
+  end
+
+  capacity = opts[:capacity] || opts[:size]
+  buffer = opts[:buffer]
+
+  if capacity && buffer == :unbuffered
+    raise ArgumentError.new('unbuffered channels cannot have a capacity')
+  elsif capacity.nil? && buffer.nil?
+    self.buffer = BUFFER_TYPES[:unbuffered].new
+  elsif capacity == 0 && buffer == :buffered
+    self.buffer = BUFFER_TYPES[:unbuffered].new
+  elsif buffer == :unbuffered
+    self.buffer = BUFFER_TYPES[:unbuffered].new
+  elsif capacity.nil? || capacity < 1
+    raise ArgumentError.new('capacity must be at least 1 for this buffer type')
+  else
+    buffer ||= :buffered
+    self.buffer = BUFFER_TYPES[buffer].new(capacity)
+  end
+
+  self.validator = opts.fetch(:validator, DEFAULT_VALIDATOR)
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .go(*args, &block) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+224
+225
+226
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 224
+
+def go(*args, &block)
+  go_via(GOROUTINES, *args, &block)
+end
+
+
+ +
+

+ + .go_loop(*args, &block) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+233
+234
+235
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 233
+
+def go_loop(*args, &block)
+  go_loop_via(GOROUTINES, *args, &block)
+end
+
+
+ +
+

+ + .go_loop_via(executor, *args, &block) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+237
+238
+239
+240
+241
+242
+243
+244
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 237
+
+def go_loop_via(executor, *args, &block)
+  raise ArgumentError.new('no block given') unless block_given?
+  executor.post(block, *args) do
+    loop do
+      break unless block.call(*args)
+    end
+  end
+end
+
+
+ +
+

+ + .go_via(executor, *args, &block) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+228
+229
+230
+231
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 228
+
+def go_via(executor, *args, &block)
+  raise ArgumentError.new('no block given') unless block_given?
+  executor.post(*args, &block)
+end
+
+
+ +
+

+ + .select(*args) {|selector, args| ... } ⇒ undocumented + + + + Also known as: + alt + + + + +

+
+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (selector, args) + + + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+216
+217
+218
+219
+220
+221
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 216
+
+def select(*args)
+  raise ArgumentError.new('no block given') unless block_given?
+  selector = Selector.new
+  yield(selector, *args)
+  selector.execute
+end
+
+
+ +
+

+ + .ticker(interval) ⇒ undocumented + + + + Also known as: + tick + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+211
+212
+213
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 211
+
+def ticker(interval)
+  Channel.new(Buffer::Ticker.new(interval))
+end
+
+
+ +
+

+ + .timer(seconds) ⇒ undocumented + + + + Also known as: + after + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+206
+207
+208
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 206
+
+def timer(seconds)
+  Channel.new(Buffer::Timer.new(seconds))
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #eachundocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 193
+
+def each
+  raise ArgumentError.new('no block given') unless block_given?
+  loop do
+    item, more = do_next
+    if item != Concurrent::NULL
+      yield(item)
+    elsif !more
+      break
+    end
+  end
+end
+
+
+ +
+

+ + #nextundocumented + + + + + +

+
+ + +
+
+
+ +
+

Examples:

+ + +

+jobs = Channel.new
+
+Channel.go do
+  loop do
+    j, more = jobs.next
+    if more
+      print "received job #{j}\n"
+    else
+      print "received all jobs\n"
+      break
+    end
+  end
+end
+ +
+ + +
+ + + + +
+
+
+
+159
+160
+161
+162
+163
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 159
+
+def next
+  item, more = do_next
+  item = nil if item == Concurrent::NULL
+  return item, more
+end
+
+
+ +
+

+ + #next?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+165
+166
+167
+168
+169
+170
+171
+172
+173
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 165
+
+def next?
+  item, more = do_next
+  item = if item == Concurrent::NULL
+           Concurrent::Maybe.nothing
+         else
+           Concurrent::Maybe.just(item)
+         end
+  return item, more
+end
+
+
+ +
+

+ + #offer(item) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+99
+100
+101
+102
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 99
+
+def offer(item)
+  return false unless validate(item, false, false)
+  do_offer(item)
+end
+
+
+ +
+

+ + #offer!(item) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (Error) + + + +
  • + +
+ +
+ + + + +
+
+
+
+104
+105
+106
+107
+108
+109
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 104
+
+def offer!(item)
+  validate(item, false, true)
+  ok = do_offer(item)
+  raise Error if !ok
+  ok
+end
+
+
+ +
+

+ + #offer?(item) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+111
+112
+113
+114
+115
+116
+117
+118
+119
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 111
+
+def offer?(item)
+  if !validate(item, true, false)
+    Concurrent::Maybe.nothing('invalid value')
+  elsif do_offer(item)
+    Concurrent::Maybe.just(true)
+  else
+    Concurrent::Maybe.nothing
+  end
+end
+
+
+ +
+

+ + #pollundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+175
+176
+177
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 175
+
+def poll
+  (item = do_poll) == Concurrent::NULL ? nil : item
+end
+
+
+ +
+

+ + #poll!undocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (Error) + + + +
  • + +
+ +
+ + + + +
+
+
+
+179
+180
+181
+182
+183
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 179
+
+def poll!
+  item = do_poll
+  raise Error if item == Concurrent::NULL
+  item
+end
+
+
+ +
+

+ + #poll?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+185
+186
+187
+188
+189
+190
+191
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 185
+
+def poll?
+  if (item = do_poll) == Concurrent::NULL
+    Concurrent::Maybe.nothing
+  else
+    Concurrent::Maybe.just(item)
+  end
+end
+
+
+ +
+

+ + #put(item) ⇒ undocumented + + + + Also known as: + send, << + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+75
+76
+77
+78
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 75
+
+def put(item)
+  return false unless validate(item, false, false)
+  do_put(item)
+end
+
+
+ +
+

+ + #put!(item) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (Error) + + + +
  • + +
+ +
+ + + + +
+
+
+
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 82
+
+def put!(item)
+  validate(item, false, true)
+  ok = do_put(item)
+  raise Error if !ok
+  ok
+end
+
+
+ +
+

+ + #put?(item) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+89
+90
+91
+92
+93
+94
+95
+96
+97
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 89
+
+def put?(item)
+  if !validate(item, true, false)
+    Concurrent::Maybe.nothing('invalid value')
+  elsif do_put(item)
+    Concurrent::Maybe.just(true)
+  else
+    Concurrent::Maybe.nothing
+  end
+end
+
+
+ +
+

+ + #takeundocumented + + + + Also known as: + receive, ~ + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+121
+122
+123
+124
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 121
+
+def take
+  item = do_take
+  item == Concurrent::NULL ? nil : item
+end
+
+
+ +
+

+ + #take!undocumented + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (Error) + + + +
  • + +
+ +
+ + + + +
+
+
+
+128
+129
+130
+131
+132
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 128
+
+def take!
+  item = do_take
+  raise Error if item == Concurrent::NULL
+  item
+end
+
+
+ +
+

+ + #take?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+134
+135
+136
+137
+138
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 134
+
+def take?
+  item = do_take
+  item = if item == Concurrent::NULL
+           Concurrent::Maybe.nothing
+         else
+           Concurrent::Maybe.just(item)
+         end
+  item
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Buffer.html b/docs/1.1.10/Concurrent/Channel/Buffer.html new file mode 100644 index 000000000..73a9eb535 --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Buffer.html @@ -0,0 +1,135 @@ + + + + + + + Module: Concurrent::Channel::Buffer + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Channel::Buffer + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb,
+ lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/ticker.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb,
lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb
+
+
+ +
+ +
+
+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: Base, Buffered, Dropping, Sliding, Ticker, Timer, Unbuffered + + +

+ + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Buffer/Base.html b/docs/1.1.10/Concurrent/Channel/Buffer/Base.html new file mode 100644 index 000000000..e32cd1ef5 --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Buffer/Base.html @@ -0,0 +1,1399 @@ + + + + + + + Class: Concurrent::Channel::Buffer::Base + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Buffer::Base + + + +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb
+
+ +
+ +

Overview

+
+

Abstract base class for all Channel buffers.

+ +

Concurrent::Channel objects maintain an internal, queue-like +object called a buffer. It's the storage bin for values put onto or +taken from the channel. Different buffer types have different +characteristics. Subsequently, the behavior of any given channel is +highly dependent uping the type of its buffer. This is the base class +which defines the common buffer interface. Any class intended to be +used as a channel buffer should extend this class.

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

Buffered, Timer, Unbuffered

+
+ + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(*args) ⇒ Base + + + + + +

+
+

Creates a new buffer.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 27
+
+def initialize(*args)
+  super()
+  synchronize do
+    @closed = false
+    @size = 0
+    @capacity = 0
+    @buffer = nil
+    ns_initialize(*args)
+  end
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #capacityundocumented + + + + + +

+
+

The maximum number of values which can be #put onto the buffer +it becomes full.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+22
+23
+24
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 22
+
+def capacity
+  @capacity
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #blocking?Boolean + + + + + +

+
+

Predicate indicating if this buffer will block #put operations +once it reaches its maximum capacity.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer blocks else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+44
+45
+46
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 44
+
+def blocking?
+  true
+end
+
+
+ +
+

+ + #closeBoolean + + + + + +

+
+

Close the buffer, preventing new items from being added. Once a +buffer is closed it cannot be opened again.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the buffer was open and successfully +closed else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+176
+177
+178
+179
+180
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 176
+
+def close
+  synchronize do
+    @closed ? false : @closed = true
+  end
+end
+
+
+ +
+

+ + #closed?Boolea + + + + + +

+
+

Predicate indicating is this buffer closed.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolea) + + + + — +

    true when closed else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+187
+188
+189
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 187
+
+def closed?
+  synchronize { ns_closed? }
+end
+
+
+ +
+

+ + #empty?Boolean + + + + + +

+
+

Predicate indicating if the buffer is empty.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer is empty else false

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    until overridden in a subclass.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+62
+63
+64
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 62
+
+def empty?
+  synchronize { ns_empty? }
+end
+
+
+ +
+

+ + #full?Boolean + + + + + +

+
+

Predicate indicating if the buffer is full.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer is full else false

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    until overridden in a subclass.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+73
+74
+75
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 73
+
+def full?
+  synchronize { ns_full? }
+end
+
+
+ +
+

+ + #nextObject, Boolean + + + + + +

+
+

Take the next "item" from the buffer and also return a boolean +indicating if "more" items can be taken. Used for iterating +over a buffer until it is closed and empty.

+ +

If the buffer is open but no items remain the calling thread will +block until an item is available. The second of the two return +values, "more" (a boolean), will always be true when the buffer is +open. The "more" value will be false when the channel has been +closed and all values have already been received. When "more" is +false the returned item will be Concurrent::NULL.

+ +

Note that when multiple threads access the same channel a race +condition can occur when using this method. A call to next from +one thread may return true for the second return value, but +another thread may take the last value before the original +thread makes another call. Code which iterates over a channel +must be programmed to properly handle these race conditions.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object, Boolean) + + + + — +

    the first return value will be the item +taken from the buffer and the second return value will be a +boolean indicating whether or not more items remain.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    until overridden in a subclass.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+151
+152
+153
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 151
+
+def next
+  raise NotImplementedError
+end
+
+
+ +
+

+ + #offer(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open but +unable to add an item, probably due to being full, the method will +return immediately. Similarly, the method will return immediately +when the buffer is closed. A return value of false does not +necessarily indicate that the buffer is closed, just that the item +could not be added.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    until overridden in a subclass.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+106
+107
+108
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 106
+
+def offer(item)
+  raise NotImplementedError
+end
+
+
+ +
+

+ + #pollObject + + + + + +

+
+

Take the next item from the buffer if one is available else return +immediately. Failing to return a value does not necessarily +indicate that the buffer is closed, just that it is empty.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the next item from the buffer or Concurrent::NULL if +the buffer is empty.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    until overridden in a subclass.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+165
+166
+167
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 165
+
+def poll
+  raise NotImplementedError
+end
+
+
+ +
+

+ + #put(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open +but not able to accept the item the calling thread will block +until the item can be put onto the buffer.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    until overridden in a subclass.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+88
+89
+90
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 88
+
+def put(item)
+  raise NotImplementedError
+end
+
+
+ +
+

+ + #sizeundocumented + + + + + +

+
+

The number of items currently in the buffer.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+51
+52
+53
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 51
+
+def size
+  synchronize { ns_size }
+end
+
+
+ +
+

+ + #takeObject + + + + + +

+
+

Take an item from the buffer if one is available. If the buffer +is open and no item is available the calling thread will block +until an item is available. If the buffer is closed but items +are available the remaining items can still be taken. Once the +buffer closes, no remaining items can be taken.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the item removed from the buffer; Concurrent::NULL once +the buffer has closed.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    until overridden in a subclass.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+122
+123
+124
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/base.rb', line 122
+
+def take
+  raise NotImplementedError
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Buffer/Buffered.html b/docs/1.1.10/Concurrent/Channel/Buffer/Buffered.html new file mode 100644 index 000000000..9aeb684ad --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Buffer/Buffered.html @@ -0,0 +1,727 @@ + + + + + + + Class: Concurrent::Channel::Buffer::Buffered + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Buffer::Buffered + + + +

+
+ +
+
Inherits:
+
+ Base + +
    +
  • Object
  • + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb
+
+ +
+ +

Overview

+
+

A buffer with a fixed internal capacity. Items can be put onto the +buffer without blocking until the internal capacity is reached. Once +the buffer is at capacity, subsequent calls to #put will block until +an item is removed from the buffer, creating spare capacity.

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

Dropping, Sliding

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Channel::Buffer::Base

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #nextObject, Boolean + + + + + +

+
+

Take the next "item" from the buffer and also return a boolean +indicating if "more" items can be taken. Used for iterating +over a buffer until it is closed and empty.

+ +

If the buffer is open but no items remain the calling thread will +block until an item is available. The second of the two return +values, "more" (a boolean), will always be true when the buffer is +open. The "more" value will be false when the channel has been +closed and all values have already been received. When "more" is +false the returned item will be Concurrent::NULL.

+ +

Note that when multiple threads access the same channel a race +condition can occur when using this method. A call to next from +one thread may return true for the second return value, but +another thread may take the last value before the original +thread makes another call. Code which iterates over a channel +must be programmed to properly handle these race conditions.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object, Boolean) + + + + — +

    the first return value will be the item +taken from the buffer and the second return value will be a +boolean indicating whether or not more items remain.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb', line 56
+
+def next
+  loop do
+    synchronize do
+      if ns_closed? && ns_empty?
+        return Concurrent::NULL, false
+      elsif !ns_empty?
+        item = buffer.shift
+        return item, true
+      end
+    end
+    Thread.pass
+  end
+end
+
+
+ +
+

+ + #offer(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open but +unable to add an item, probably due to being full, the method will +return immediately. Similarly, the method will return immediately +when the buffer is closed. A return value of false does not +necessarily indicate that the buffer is closed, just that the item +could not be added.

+ +

New items can be put onto the buffer until the number of items in +the buffer reaches the Concurrent::Channel::Buffer::Base#size value specified during +initialization.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb', line 38
+
+def offer(item)
+  synchronize do
+    if ns_closed? || ns_full?
+      return false
+    else
+      ns_put_onto_buffer(item)
+      return true
+    end
+  end
+end
+
+
+ +
+

+ + #pollObject + + + + + +

+
+

Take the next item from the buffer if one is available else return +immediately. Failing to return a value does not necessarily +indicate that the buffer is closed, just that it is empty.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the next item from the buffer or Concurrent::NULL if +the buffer is empty.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+71
+72
+73
+74
+75
+76
+77
+78
+79
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb', line 71
+
+def poll
+  synchronize do
+    if ns_empty?
+      Concurrent::NULL
+    else
+      buffer.shift
+    end
+  end
+end
+
+
+ +
+

+ + #put(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open +but not able to accept the item the calling thread will block +until the item can be put onto the buffer.

+ +

New items can be put onto the buffer until the number of items in +the buffer reaches the Concurrent::Channel::Buffer::Base#size value specified during +initialization.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb', line 19
+
+def put(item)
+  loop do
+    synchronize do
+      if ns_closed?
+        return false
+      elsif !ns_full?
+        ns_put_onto_buffer(item)
+        return true
+      end
+    end
+    Thread.pass
+  end
+end
+
+
+ +
+

+ + #takeObject + + + + + +

+
+

Take an item from the buffer if one is available. If the buffer +is open and no item is available the calling thread will block +until an item is available. If the buffer is closed but items +are available the remaining items can still be taken. Once the +buffer closes, no remaining items can be taken.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the item removed from the buffer; Concurrent::NULL once +the buffer has closed.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+50
+51
+52
+53
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/buffered.rb', line 50
+
+def take
+  item, _ = self.next
+  item
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Buffer/Dropping.html b/docs/1.1.10/Concurrent/Channel/Buffer/Dropping.html new file mode 100644 index 000000000..3c4b1f51d --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Buffer/Dropping.html @@ -0,0 +1,546 @@ + + + + + + + Class: Concurrent::Channel::Buffer::Dropping + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Buffer::Dropping + + + +

+
+ +
+
Inherits:
+
+ Buffered + +
    +
  • Object
  • + + + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb
+
+ +
+ +

Overview

+
+

A non-blocking, buffered buffer of fixed maximum capacity. When the +maximum capacity is reached subsequent #put and #offer operations +will complete but the put item will be discarded; no transfer will +occur.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Channel::Buffer::Base

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #blocking?Boolean + + + + + +

+
+

Predicate indicating if this buffer will block #put operations +once it reaches its maximum capacity.

+ +

Always returns false.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer blocks else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb', line 35
+
+def blocking?
+  false
+end
+
+
+ +
+

+ + #full?Boolean + + + + + +

+
+

Predicate indicating if the buffer is full.

+ +

Always returns false.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer is full else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb', line 27
+
+
+
+
+ +
+

+ + #offer(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open but +unable to add an item, probably due to being full, the method will +return immediately. Similarly, the method will return immediately +when the buffer is closed. A return value of false does not +necessarily indicate that the buffer is closed, just that the item +could not be added.

+ +

When the buffer is full, this method will return true +immediately but the item will be discarded. The item will not +be placed into the buffer (no transfer will occur).

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb', line 20
+
+
+
+
+ +
+

+ + #put(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open +but not able to accept the item the calling thread will block +until the item can be put onto the buffer.

+ +

When the buffer is full, this method will return true +immediately but the item will be discarded. The item will not +be placed into the buffer (no transfer will occur).

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/dropping.rb', line 13
+
+
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Buffer/Sliding.html b/docs/1.1.10/Concurrent/Channel/Buffer/Sliding.html new file mode 100644 index 000000000..e72611e5a --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Buffer/Sliding.html @@ -0,0 +1,546 @@ + + + + + + + Class: Concurrent::Channel::Buffer::Sliding + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Buffer::Sliding + + + +

+
+ +
+
Inherits:
+
+ Buffered + +
    +
  • Object
  • + + + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb
+
+ +
+ +

Overview

+
+

A non-blocking, buffered buffer of fixed maximum capacity. When the +maximum capacity is reached subsequent #put and #offer operations +will complete and the item will be put, but the oldest elements in +the buffer will be discarded (not transferred).

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Channel::Buffer::Base

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #blocking?Boolean + + + + + +

+
+

Predicate indicating if this buffer will block #put operations +once it reaches its maximum capacity.

+ +

Always returns false.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer blocks else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb', line 35
+
+def blocking?
+  false
+end
+
+
+ +
+

+ + #full?Boolean + + + + + +

+
+

Predicate indicating if the buffer is full.

+ +

Always returns false.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer is full else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb', line 27
+
+
+
+
+ +
+

+ + #offer(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open but +unable to add an item, probably due to being full, the method will +return immediately. Similarly, the method will return immediately +when the buffer is closed. A return value of false does not +necessarily indicate that the buffer is closed, just that the item +could not be added.

+ +

When the buffer is full, this method will return true +immediately and the item will be inserted, but the oldest +elements in the buffer will be discarded (not transferred).

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb', line 20
+
+
+
+
+ +
+

+ + #put(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open +but not able to accept the item the calling thread will block +until the item can be put onto the buffer.

+ +

When the buffer is full, this method will return true +immediately and the item will be inserted, but the oldest +elements in the buffer will be discarded (not transferred).

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/sliding.rb', line 13
+
+
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Buffer/Ticker.html b/docs/1.1.10/Concurrent/Channel/Buffer/Ticker.html new file mode 100644 index 000000000..c4ec94fa6 --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Buffer/Ticker.html @@ -0,0 +1,157 @@ + + + + + + + Class: Concurrent::Channel::Buffer::Ticker + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Buffer::Ticker + + + +

+
+ +
+
Inherits:
+
+ Timer + +
    +
  • Object
  • + + + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/buffer/ticker.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Channel::Buffer::Base

+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Buffer/Timer.html b/docs/1.1.10/Concurrent/Channel/Buffer/Timer.html new file mode 100644 index 000000000..49f762eee --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Buffer/Timer.html @@ -0,0 +1,505 @@ + + + + + + + Class: Concurrent::Channel::Buffer::Timer + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Buffer::Timer + + + +

+
+ +
+
Inherits:
+
+ Base + +
    +
  • Object
  • + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+

Direct Known Subclasses

+

Ticker

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Channel::Buffer::Base

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #nextundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+31
+32
+33
+34
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb', line 31
+
+def next
+  loop do
+    tick, more = do_poll
+    return tick, more if tick
+    Thread.pass
+  end
+end
+
+
+ +
+

+ + #offer(item) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb', line 16
+
+def offer(item)
+  false
+end
+
+
+ +
+

+ + #pollundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+39
+40
+41
+42
+43
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb', line 39
+
+def poll
+  tick, _ = do_poll
+  tick = Concurrent::NULL unless tick
+  tick
+end
+
+
+ +
+

+ + #put(item) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+12
+13
+14
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb', line 12
+
+def put(item)
+  false
+end
+
+
+ +
+

+ + #takeundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/timer.rb', line 20
+
+def take
+  loop do
+    tick, _ = do_poll
+    if tick
+      return tick
+    else
+      Thread.pass
+    end
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Buffer/Unbuffered.html b/docs/1.1.10/Concurrent/Channel/Buffer/Unbuffered.html new file mode 100644 index 000000000..933f75f25 --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Buffer/Unbuffered.html @@ -0,0 +1,1011 @@ + + + + + + + Class: Concurrent::Channel::Buffer::Unbuffered + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Buffer::Unbuffered + + + +

+
+ +
+
Inherits:
+
+ Base + +
    +
  • Object
  • + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb
+
+ +
+ +

Overview

+
+

A blocking buffer with a size of zero. An item can only be put onto +the buffer when a thread is waiting to take. Similarly, an item can +only be put onto the buffer when a thread is waiting to put. When +either #put or #take is called and there is no corresponding call +in progress, the call will block indefinitely. Any other calls to the +same method will queue behind the first call and block as well. As +soon as a corresponding put/take call is made an exchange will occur +and the first blocked call will return.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Channel::Buffer::Base

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #empty?Boolean + + + + + +

+
+

Predicate indicating if the buffer is empty.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer is empty else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb', line 27
+
+def empty?
+  size == 0
+end
+
+
+ +
+

+ + #full?Boolean + + + + + +

+
+

Predicate indicating if the buffer is full.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if this buffer is full else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+32
+33
+34
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb', line 32
+
+def full?
+  !empty?
+end
+
+
+ +
+

+ + #nextObject, Boolean + + + + + +

+
+

Take the next "item" from the buffer and also return a boolean +indicating if "more" items can be taken. Used for iterating +over a buffer until it is closed and empty.

+ +

If the buffer is open but no items remain the calling thread will +block until an item is available. The second of the two return +values, "more" (a boolean), will always be true when the buffer is +open. The "more" value will be false when the channel has been +closed and all values have already been received. When "more" is +false the returned item will be Concurrent::NULL.

+ +

Note that when multiple threads access the same channel a race +condition can occur when using this method. A call to next from +one thread may return true for the second return value, but +another thread may take the last value before the original +thread makes another call. Code which iterates over a channel +must be programmed to properly handle these race conditions.

+ +

Items can only be taken from the buffer when one or more threads are +waiting to #put items onto the buffer. This method exhibits the +same blocking behavior as #take.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object, Boolean) + + + + — +

    the first return value will be the item +taken from the buffer and the second return value will be a +boolean indicating whether or not more items remain.

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb', line 135
+
+def next
+  item = take
+  more = (item != Concurrent::NULL)
+  return item, more
+end
+
+
+ +
+

+ + #offer(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open but +unable to add an item, probably due to being full, the method will +return immediately. Similarly, the method will return immediately +when the buffer is closed. A return value of false does not +necessarily indicate that the buffer is closed, just that the item +could not be added.

+ +

Items can only be put onto the buffer when one or more threads are +waiting to #take items off the buffer. When there is a thread +waiting to take an item this method will give its item and return +true immediately. When there are no threads waiting to take or the +buffer is closed, this method will return false immediately.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+71
+72
+73
+74
+75
+76
+77
+78
+79
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb', line 71
+
+def offer(item)
+  synchronize do
+    return false if ns_closed? || taking.empty?
+
+    taken = taking.shift
+    taken.value = item
+    true
+  end
+end
+
+
+ +
+

+ + #pollObject + + + + + +

+
+

Take the next item from the buffer if one is available else return +immediately. Failing to return a value does not necessarily +indicate that the buffer is closed, just that it is empty.

+ +

Items can only be taken off the buffer when one or more threads are +waiting to #put items onto the buffer. When there is a thread +waiting to put an item this method will take the item and return +it immediately. When there are no threads waiting to put or the +buffer is closed, this method will return Concurrent::NULL immediately.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the next item from the buffer or Concurrent::NULL if +the buffer is empty.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb', line 117
+
+def poll
+  synchronize do
+    return Concurrent::NULL if putting.empty?
+
+    put = putting.shift
+    value = put.value
+    put.value = nil
+    value
+  end
+end
+
+
+ +
+

+ + #put(item) ⇒ Boolean + + + + + +

+
+

Put an item onto the buffer if possible. If the buffer is open +but not able to accept the item the calling thread will block +until the item can be put onto the buffer.

+ +

Items can only be put onto the buffer when one or more threads are +waiting to #take items off the buffer. When there is a thread +waiting to take an item this method will give its item and return +immediately. When there are no threads waiting to take, this method +will block. As soon as a thread calls take the exchange will +occur and this method will return.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item/value to put onto the buffer.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the item was added to the buffer else +false (always false when closed).

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb', line 44
+
+def put(item)
+  mine = synchronize do
+    return false if ns_closed?
+
+    ref = Concurrent::AtomicReference.new(item)
+    if taking.empty?
+      putting.push(ref)
+    else
+      taken = taking.shift
+      taken.value = item
+      ref.value = nil
+    end
+    ref
+  end
+  loop do
+    return true if mine.value.nil?
+    Thread.pass
+  end
+end
+
+
+ +
+

+ + #sizeundocumented + + + + + +

+
+

The number of items currently in the buffer.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+20
+21
+22
+23
+24
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb', line 20
+
+def size
+  synchronize do
+    putting.empty? ? 0 : 1
+  end
+end
+
+
+ +
+

+ + #takeObject + + + + + +

+
+

Take an item from the buffer if one is available. If the buffer +is open and no item is available the calling thread will block +until an item is available. If the buffer is closed but items +are available the remaining items can still be taken. Once the +buffer closes, no remaining items can be taken.

+ +

Items can only be taken from the buffer when one or more threads are +waiting to #put items onto the buffer. When there is a thread +waiting to put an item this method will take that item and return it +immediately. When there are no threads waiting to put, this method +will block. As soon as a thread calls pur the exchange will occur +and this method will return.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the item removed from the buffer; Concurrent::NULL once +the buffer has closed.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/buffer/unbuffered.rb', line 89
+
+def take
+  mine = synchronize do
+    return Concurrent::NULL if ns_closed? && putting.empty?
+
+    ref = Concurrent::AtomicReference.new(nil)
+    if putting.empty?
+      taking.push(ref)
+    else
+      put = putting.shift
+      ref.value = put.value
+      put.value = nil
+    end
+    ref
+  end
+  loop do
+    item = mine.value
+    return item if item
+    Thread.pass
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Selector/AfterClause.html b/docs/1.1.10/Concurrent/Channel/Selector/AfterClause.html new file mode 100644 index 000000000..4af01e06d --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Selector/AfterClause.html @@ -0,0 +1,313 @@ + + + + + + + Class: Concurrent::Channel::Selector::AfterClause + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Selector::AfterClause + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/selector/after_clause.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(seconds, block) ⇒ AfterClause + + + + + +

+
+

Returns a new instance of AfterClause.

+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+10
+11
+12
+13
+14
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/after_clause.rb', line 10
+
+def initialize(seconds, block)
+  raise ArgumentError.new('timeout must 0.0 or more') if seconds.to_f < 0.0
+  @end = Concurrent.monotonic_time + seconds.to_f
+  @block = block
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #executeundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+19
+20
+21
+22
+23
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/after_clause.rb', line 16
+
+def execute
+  if Concurrent.monotonic_time > @end
+    result = @block ? @block.call : nil
+    Concurrent::Maybe.just(result)
+  else
+    Concurrent::Maybe.nothing
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Selector/DefaultClause.html b/docs/1.1.10/Concurrent/Channel/Selector/DefaultClause.html new file mode 100644 index 000000000..f91dbd70f --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Selector/DefaultClause.html @@ -0,0 +1,286 @@ + + + + + + + Class: Concurrent::Channel::Selector::DefaultClause + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Selector::DefaultClause + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/selector/default_clause.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(block) ⇒ DefaultClause + + + + + +

+
+

Returns a new instance of DefaultClause.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/default_clause.rb', line 9
+
+def initialize(block)
+  @block = block
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #executeundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+13
+14
+15
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/default_clause.rb', line 13
+
+def execute
+  Concurrent::Maybe.just(@block.call)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Selector/ErrorClause.html b/docs/1.1.10/Concurrent/Channel/Selector/ErrorClause.html new file mode 100644 index 000000000..0fd050b3f --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Selector/ErrorClause.html @@ -0,0 +1,294 @@ + + + + + + + Class: Concurrent::Channel::Selector::ErrorClause + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Selector::ErrorClause + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/selector/error_clause.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(block) ⇒ ErrorClause + + + + + +

+
+

Returns a new instance of ErrorClause.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/error_clause.rb', line 7
+
+def initialize(block)
+  @block = block
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #execute(error) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+11
+12
+13
+14
+15
+16
+17
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/error_clause.rb', line 11
+
+def execute(error)
+  @block.call(error)
+rescue
+  # suppress and move on
+ensure
+  return nil
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Selector/PutClause.html b/docs/1.1.10/Concurrent/Channel/Selector/PutClause.html new file mode 100644 index 000000000..15c3efac1 --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Selector/PutClause.html @@ -0,0 +1,300 @@ + + + + + + + Class: Concurrent::Channel::Selector::PutClause + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Selector::PutClause + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/selector/put_clause.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(channel, message, block) ⇒ PutClause + + + + + +

+
+

Returns a new instance of PutClause.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+12
+13
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/put_clause.rb', line 9
+
+def initialize(channel, message, block)
+  @channel = channel
+  @message = message
+  @block = block
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #executeundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+22
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/put_clause.rb', line 15
+
+def execute
+  if @channel.offer?(@message).just?
+    result = @block ? @block.call : nil
+    Concurrent::Maybe.just(result)
+  else
+    Concurrent::Maybe.nothing
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Selector/TakeClause.html b/docs/1.1.10/Concurrent/Channel/Selector/TakeClause.html new file mode 100644 index 000000000..8401c47ec --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Selector/TakeClause.html @@ -0,0 +1,296 @@ + + + + + + + Class: Concurrent::Channel::Selector::TakeClause + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Selector::TakeClause + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/selector/take_clause.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(channel, block) ⇒ TakeClause + + + + + +

+
+

Returns a new instance of TakeClause.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+12
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/take_clause.rb', line 9
+
+def initialize(channel, block)
+  @channel = channel
+  @block = block
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #executeundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+17
+18
+19
+20
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/selector/take_clause.rb', line 14
+
+def execute
+  if (result = @channel.poll?).just?
+    Concurrent::Maybe.just(@block.call(result.value))
+  else
+    Concurrent::Maybe.nothing
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/Tick.html b/docs/1.1.10/Concurrent/Channel/Tick.html new file mode 100644 index 000000000..08ee460e0 --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/Tick.html @@ -0,0 +1,624 @@ + + + + + + + Class: Concurrent::Channel::Tick + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::Tick + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + +
+
Includes:
+
Comparable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel/tick.rb
+
+ +
+ +

Overview

+
+

A convenience class representing a single moment in monotonic time. +Returned by Concurrent::Channel tickers and timers when they +resolve.

+ +

Includes Comparable and can be compared to monotonic_time, UTC +time, or epoch time.

+ + +
+
+
+ + +

See Also:

+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
STRING_FORMAT = +
+
+ + +
+
+
+ + +
+
+
'%F %T.%6N %z %Z'.freeze
+ +
+ + + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(tick = Concurrent.monotonic_time) ⇒ Tick + + + + + +

+
+

Returns a new instance of Tick.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+25
+26
+27
+28
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/tick.rb', line 25
+
+def initialize(tick = Concurrent.monotonic_time)
+  @monotonic = tick
+  @utc = monotonic_to_utc(tick).freeze
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #monotonicundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+23
+24
+25
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/tick.rb', line 23
+
+def monotonic
+  @monotonic
+end
+
+
+ + + +
+

+ + #utcundocumented (readonly) + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+23
+24
+25
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/tick.rb', line 23
+
+def utc
+  @utc
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #<=>(other) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/tick.rb', line 38
+
+def <=>(other)
+  if other.is_a? Numeric
+    @monotonic <=> other
+  elsif other.is_a? Time
+    @utc <=> other.utc
+  elsif other.is_a? Tick
+    @monotonic <=> other.monotonic
+  else
+    nil
+  end
+end
+
+
+ +
+

+ + #epochundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+30
+31
+32
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/tick.rb', line 30
+
+def epoch
+  @utc.to_f
+end
+
+
+ +
+

+ + #to_sundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+34
+35
+36
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel/tick.rb', line 34
+
+def to_s
+  @utc.strftime(STRING_FORMAT)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Channel/ValidationError.html b/docs/1.1.10/Concurrent/Channel/ValidationError.html new file mode 100644 index 000000000..2119f4365 --- /dev/null +++ b/docs/1.1.10/Concurrent/Channel/ValidationError.html @@ -0,0 +1,219 @@ + + + + + + + Class: Concurrent::Channel::ValidationError + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Channel::ValidationError + + + +

+
+ +
+
Inherits:
+
+ Error + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/channel.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(message = nil) ⇒ ValidationError + + + + + +

+
+

Returns a new instance of ValidationError.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby-edge/concurrent/channel.rb', line 35
+
+def initialize(message = nil)
+  message ||= 'invalid value'
+end
+
+
+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Collection/CopyOnNotifyObserverSet.html b/docs/1.1.10/Concurrent/Collection/CopyOnNotifyObserverSet.html new file mode 100644 index 000000000..15f27b043 --- /dev/null +++ b/docs/1.1.10/Concurrent/Collection/CopyOnNotifyObserverSet.html @@ -0,0 +1,893 @@ + + + + + + + Class: Concurrent::Collection::CopyOnNotifyObserverSet + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Collection::CopyOnNotifyObserverSet + + + Private +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb
+
+ +
+ +

Overview

+
+

+ This class is part of a private API. + You should avoid using this class if possible, as it may be removed or be changed in the future. +

+

A thread safe observer set implemented using copy-on-read approach: +observers are added and removed from a thread safe collection; every time +a notification is required the internal data structure is copied to +prevent concurrency issues

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initializeCopyOnNotifyObserverSet + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Returns a new instance of CopyOnNotifyObserverSet.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+17
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb', line 14
+
+def initialize
+  super()
+  synchronize { ns_initialize }
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #add_observer(observer = nil, func = :update, &block) ⇒ Object + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Adds an observer to this set. If a block is passed, the observer will be +created by this method and no other params should be passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification. +Default is :update

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the added observer

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb', line 20
+
+def add_observer(observer = nil, func = :update, &block)
+  if observer.nil? && block.nil?
+    raise ArgumentError, 'should pass observer as a first argument or block'
+  elsif observer && block
+    raise ArgumentError.new('cannot provide both an observer and a block')
+  end
+
+  if block
+    observer = block
+    func     = :call
+  end
+
+  synchronize do
+    @observers[observer] = func
+    observer
+  end
+end
+
+
+ +
+

+ + #count_observersInteger + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Return the number of observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the observers count

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+55
+56
+57
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb', line 55
+
+def count_observers
+  synchronize { @observers.count }
+end
+
+
+ +
+

+ + #delete_observer(observer) ⇒ Object + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Remove observer as an observer on this object so that it will no +longer receive notifications.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + + — +

    the observer to remove

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the deleted observer

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+39
+40
+41
+42
+43
+44
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb', line 39
+
+def delete_observer(observer)
+  synchronize do
+    @observers.delete(observer)
+    observer
+  end
+end
+
+
+ +
+

+ + #delete_observersObservable + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Remove all observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+47
+48
+49
+50
+51
+52
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb', line 47
+
+def delete_observers
+  synchronize do
+    @observers.clear
+    self
+  end
+end
+
+
+ +
+

+ + #notify_and_delete_observers(*args, &block) ⇒ CopyOnWriteObserverSet + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Notifies all registered observers with optional args and deletes them.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    arguments to be passed to each observer

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+72
+73
+74
+75
+76
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb', line 72
+
+def notify_and_delete_observers(*args, &block)
+  observers = duplicate_and_clear_observers
+  notify_to(observers, *args, &block)
+  self
+end
+
+
+ +
+

+ + #notify_observers(*args, &block) ⇒ CopyOnWriteObserverSet + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Notifies all registered observers with optional args

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    arguments to be passed to each observer

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+62
+63
+64
+65
+66
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb', line 62
+
+def notify_observers(*args, &block)
+  observers = duplicate_observers
+  notify_to(observers, *args, &block)
+  self
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Collection/CopyOnWriteObserverSet.html b/docs/1.1.10/Concurrent/Collection/CopyOnWriteObserverSet.html new file mode 100644 index 000000000..01126723b --- /dev/null +++ b/docs/1.1.10/Concurrent/Collection/CopyOnWriteObserverSet.html @@ -0,0 +1,894 @@ + + + + + + + Class: Concurrent::Collection::CopyOnWriteObserverSet + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Collection::CopyOnWriteObserverSet + + + Private +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb
+
+ +
+ +

Overview

+
+

+ This class is part of a private API. + You should avoid using this class if possible, as it may be removed or be changed in the future. +

+

A thread safe observer set implemented using copy-on-write approach: +every time an observer is added or removed the whole internal data structure is +duplicated and replaced with a new one.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initializeCopyOnWriteObserverSet + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Returns a new instance of CopyOnWriteObserverSet.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+13
+14
+15
+16
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb', line 13
+
+def initialize
+  super()
+  synchronize { ns_initialize }
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #add_observer(observer = nil, func = :update, &block) ⇒ Object + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Adds an observer to this set. If a block is passed, the observer will be +created by this method and no other params should be passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification. +Default is :update

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the added observer

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb', line 19
+
+def add_observer(observer = nil, func = :update, &block)
+  if observer.nil? && block.nil?
+    raise ArgumentError, 'should pass observer as a first argument or block'
+  elsif observer && block
+    raise ArgumentError.new('cannot provide both an observer and a block')
+  end
+
+  if block
+    observer = block
+    func = :call
+  end
+
+  synchronize do
+    new_observers = @observers.dup
+    new_observers[observer] = func
+    @observers = new_observers
+    observer
+  end
+end
+
+
+ +
+

+ + #count_observersInteger + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Return the number of observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the observers count

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb', line 56
+
+def count_observers
+  observers.count
+end
+
+
+ +
+

+ + #delete_observer(observer) ⇒ Object + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Remove observer as an observer on this object so that it will no +longer receive notifications.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + + — +

    the observer to remove

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the deleted observer

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+40
+41
+42
+43
+44
+45
+46
+47
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb', line 40
+
+def delete_observer(observer)
+  synchronize do
+    new_observers = @observers.dup
+    new_observers.delete(observer)
+    @observers = new_observers
+    observer
+  end
+end
+
+
+ +
+

+ + #delete_observersObservable + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Remove all observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+50
+51
+52
+53
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb', line 50
+
+def delete_observers
+  self.observers = {}
+  self
+end
+
+
+ +
+

+ + #notify_and_delete_observers(*args, &block) ⇒ CopyOnWriteObserverSet + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Notifies all registered observers with optional args and deletes them.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    arguments to be passed to each observer

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+72
+73
+74
+75
+76
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb', line 72
+
+def notify_and_delete_observers(*args, &block)
+  old = clear_observers_and_return_old
+  notify_to(old, *args, &block)
+  self
+end
+
+
+ +
+

+ + #notify_observers(*args, &block) ⇒ CopyOnWriteObserverSet + + + + + +

+
+

+ This method is part of a private API. + You should avoid using this method if possible, as it may be removed or be changed in the future. +

+

Notifies all registered observers with optional args

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    arguments to be passed to each observer

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+63
+64
+65
+66
+
+
# File 'lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb', line 63
+
+def notify_observers(*args, &block)
+  notify_to(observers, *args, &block)
+  self
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Concern.html b/docs/1.1.10/Concurrent/Concern.html new file mode 100644 index 000000000..fb4b0e788 --- /dev/null +++ b/docs/1.1.10/Concurrent/Concern.html @@ -0,0 +1,126 @@ + + + + + + + Module: Concurrent::Concern + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Concern + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/concern/logging.rb,
+ lib/concurrent-ruby/concurrent/concern/obligation.rb,
lib/concurrent-ruby/concurrent/concern/observable.rb,
lib/concurrent-ruby/concurrent/concern/deprecation.rb,
lib/concurrent-ruby/concurrent/concern/dereferenceable.rb
+
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: Dereferenceable, Obligation, Observable + + + + +

+ + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Concern/Dereferenceable.html b/docs/1.1.10/Concurrent/Concern/Dereferenceable.html new file mode 100644 index 000000000..892250ca7 --- /dev/null +++ b/docs/1.1.10/Concurrent/Concern/Dereferenceable.html @@ -0,0 +1,276 @@ + + + + + + + Module: Concurrent::Concern::Dereferenceable + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Concern::Dereferenceable + + + +

+
+ + + + + + + + + +
+
Included in:
+
Obligation, MVar, TimerTask
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/concern/dereferenceable.rb
+
+ +
+ +

Overview

+
+

Object references in Ruby are mutable. This can lead to serious problems when +the #value of a concurrent object is a mutable reference. Which is always the +case unless the value is a Fixnum, Symbol, or similar "primitive" data type. +Most classes in this library that expose a #value getter method do so using the +Dereferenceable mixin module.

+ +

Copy Options

+ +

Object references in Ruby are mutable. This can lead to serious +problems when the #value of an object is a mutable reference. Which +is always the case unless the value is a Fixnum, Symbol, or similar +"primitive" data type. Each instance can be configured with a few +options that can help protect the program from potentially dangerous +operations. Each of these options can be optionally set when the object +instance is created:

+ +
    +
  • :dup_on_deref When true the object will call the #dup method on +the value object every time the #value method is called +(default: false)
  • +
  • :freeze_on_deref When true the object will call the #freeze +method on the value object every time the #value method is called +(default: false)
  • +
  • :copy_on_deref When given a Proc object the Proc will be run +every time the #value method is called. The Proc will be given +the current value as its only argument and the result returned by +the block will be the return value of the #value call. When nil +this option will be ignored (default: nil)
  • +
+ +

When multiple deref options are set the order of operations is strictly defined. +The order of deref operations is:

+ +
    +
  • :copy_on_deref
  • +
  • :dup_on_deref
  • +
  • :freeze_on_deref
  • +
+ +

Because of this ordering there is no need to #freeze an object created by a +provided :copy_on_deref block. Simply set :freeze_on_deref to true. +Setting both :dup_on_deref to true and :freeze_on_deref to true is +as close to the behavior of a "pure" functional language (like Erlang, Clojure, +or Haskell) as we are likely to get in Ruby.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #valueObject + + + + Also known as: + deref + + + + +

+
+

Return the value this object represents after applying the options specified +by the #set_deref_options method.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of the object

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+21
+22
+23
+
+
# File 'lib/concurrent-ruby/concurrent/concern/dereferenceable.rb', line 21
+
+def value
+  synchronize { apply_deref_options(@value) }
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Concern/Obligation.html b/docs/1.1.10/Concurrent/Concern/Obligation.html new file mode 100644 index 000000000..f4cc9db22 --- /dev/null +++ b/docs/1.1.10/Concurrent/Concern/Obligation.html @@ -0,0 +1,1305 @@ + + + + + + + Module: Concurrent::Concern::Obligation + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Concern::Obligation + + + +

+
+ + + + + + +
+
Includes:
+
Dereferenceable
+
+ + + + +
+
Included in:
+
Delay, IVar
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/concern/obligation.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #complete?Boolean + + + + + +

+
+

Has the obligation completed processing?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+49
+50
+51
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 49
+
+def complete?
+  [:fulfilled, :rejected].include? state
+end
+
+
+ +
+

+ + #exception(*args) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ +
+

Examples:

+ + +

allows Obligation to be risen

+

+ +
rejected_ivar = Ivar.new.fail
+raise rejected_ivar
+ +
+ + +
+ + + + +
+
+
+
+126
+127
+128
+129
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 126
+
+def exception(*args)
+  raise 'obligation is not rejected' unless rejected?
+  reason.exception(*args)
+end
+
+
+ +
+

+ + #fulfilled?Boolean + + + + Also known as: + realized? + + + + +

+
+

Has the obligation been fulfilled?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+20
+21
+22
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 20
+
+def fulfilled?
+  state == :fulfilled
+end
+
+
+ +
+

+ + #incomplete?Boolean + + + + + +

+
+

Is the obligation still awaiting completion of processing?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 56
+
+def incomplete?
+  ! complete?
+end
+
+
+ +
+

+ + #pending?Boolean + + + + + +

+
+

Is obligation completion still pending?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 35
+
+def pending?
+  state == :pending
+end
+
+
+ +
+

+ + #reasonException + + + + + +

+
+

If an exception was raised during processing this will return the +exception object. Will return nil when the state is pending or if +the obligation has been successfully fulfilled.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Exception) + + + + — +

    the exception raised during processing or nil

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+119
+120
+121
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 119
+
+def reason
+  synchronize { @reason }
+end
+
+
+ +
+

+ + #rejected?Boolean + + + + + +

+
+

Has the obligation been rejected?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+28
+29
+30
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 28
+
+def rejected?
+  state == :rejected
+end
+
+
+ +
+

+ + #stateSymbol + + + + + +

+
+

The current state of the obligation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Symbol) + + + + — +

    the current state

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+110
+111
+112
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 110
+
+def state
+  synchronize { @state }
+end
+
+
+ +
+

+ + #unscheduled?Boolean + + + + + +

+
+

Is the obligation still unscheduled?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+42
+43
+44
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 42
+
+def unscheduled?
+  state == :unscheduled
+end
+
+
+ +
+

+ + #value(timeout = nil) ⇒ Object + + + + + +

+
+

The current value of the obligation. Will be nil while the state is +pending or the operation has been rejected.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    see Dereferenceable#deref

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+65
+66
+67
+68
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 65
+
+def value(timeout = nil)
+  wait timeout
+  deref
+end
+
+
+ +
+

+ + #value!(timeout = nil) ⇒ Object + + + + + +

+
+

The current value of the obligation. Will be nil while the state is +pending or the operation has been rejected. Will re-raise any exceptions +raised during processing (but will not raise an exception on timeout).

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    see Dereferenceable#deref

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    raises the reason when rejected

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+98
+99
+100
+101
+102
+103
+104
+105
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 98
+
+def value!(timeout = nil)
+  wait(timeout)
+  if rejected?
+    raise self
+  else
+    deref
+  end
+end
+
+
+ +
+

+ + #wait(timeout = nil) ⇒ Obligation + + + + + +

+
+

Wait until obligation is complete or the timeout has been reached.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Obligation) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+74
+75
+76
+77
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 74
+
+def wait(timeout = nil)
+  event.wait(timeout) if timeout != 0 && incomplete?
+  self
+end
+
+
+ +
+

+ + #wait!(timeout = nil) ⇒ Obligation + + + + Also known as: + no_error! + + + + +

+
+

Wait until obligation is complete or the timeout is reached. Will re-raise +any exceptions raised during processing (but will not raise an exception +on timeout).

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Obligation) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    raises the reason when rejected

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+86
+87
+88
+
+
# File 'lib/concurrent-ruby/concurrent/concern/obligation.rb', line 86
+
+def wait!(timeout = nil)
+  wait(timeout).tap { raise self if rejected? }
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Concern/Observable.html b/docs/1.1.10/Concurrent/Concern/Observable.html new file mode 100644 index 000000000..7a296390b --- /dev/null +++ b/docs/1.1.10/Concurrent/Concern/Observable.html @@ -0,0 +1,693 @@ + + + + + + + Module: Concurrent::Concern::Observable + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Concern::Observable + + + +

+
+ + + + + + + + + +
+
Included in:
+
Agent, Atom, IVar, TimerTask
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/concern/observable.rb
+
+ +
+ +

Overview

+
+

The observer pattern is one +of the most useful design patterns.

+ +

The workflow is very simple:

+ +
    +
  • an observer can register itself to a subject via a callback
  • +
  • many observers can be registered to the same subject
  • +
  • the subject notifies all registered observers when its status changes
  • +
  • an observer can deregister itself when is no more interested to receive +event notifications
  • +
+ +

In a single threaded environment the whole pattern is very easy: the +subject can use a simple data structure to manage all its subscribed +observers and every observer can react directly to every event without +caring about synchronization.

+ +

In a multi threaded environment things are more complex. The subject must +synchronize the access to its data structure and to do so currently we're +using two specialized ObserverSet: CopyOnWriteObserverSet +and CopyOnNotifyObserverSet.

+ +

When implementing and observer there's a very important rule to remember: +there are no guarantees about the thread that will execute the callback

+ +

Let's take this example

+ +
class Observer
+  def initialize
+    @count = 0
+  end
+
+  def update
+    @count += 1
+  end
+end
+
+obs = Observer.new
+[obj1, obj2, obj3, obj4].each { |o| o.add_observer(obs) }
+# execute [obj1, obj2, obj3, obj4]
+
+ +

obs is wrong because the variable @count can be accessed by different +threads at the same time, so it should be synchronized (using either a Mutex +or an AtomicFixum)

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #add_observer(observer = nil, func = :update, &block) ⇒ Object + + + + + +

+
+

Adds an observer to this set. If a block is passed, the observer will be +created by this method and no other params should be passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification. +Default is :update

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the added observer

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+61
+62
+63
+
+
# File 'lib/concurrent-ruby/concurrent/concern/observable.rb', line 61
+
+def add_observer(observer = nil, func = :update, &block)
+  observers.add_observer(observer, func, &block)
+end
+
+
+ +
+

+ + #count_observersInteger + + + + + +

+
+

Return the number of observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the observers count

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+101
+102
+103
+
+
# File 'lib/concurrent-ruby/concurrent/concern/observable.rb', line 101
+
+def count_observers
+  observers.count_observers
+end
+
+
+ +
+

+ + #delete_observer(observer) ⇒ Object + + + + + +

+
+

Remove observer as an observer on this object so that it will no +longer receive notifications.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + + — +

    the observer to remove

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the deleted observer

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+82
+83
+84
+
+
# File 'lib/concurrent-ruby/concurrent/concern/observable.rb', line 82
+
+def delete_observer(observer)
+  observers.delete_observer(observer)
+end
+
+
+ +
+

+ + #delete_observersObservable + + + + + +

+
+

Remove all observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+91
+92
+93
+94
+
+
# File 'lib/concurrent-ruby/concurrent/concern/observable.rb', line 91
+
+def delete_observers
+  observers.delete_observers
+  self
+end
+
+
+ +
+

+ + #with_observer(observer = nil, func = :update, &block) ⇒ Observable + + + + + +

+
+

As #add_observer but can be used for chaining.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+70
+71
+72
+73
+
+
# File 'lib/concurrent-ruby/concurrent/concern/observable.rb', line 70
+
+def with_observer(observer = nil, func = :update, &block)
+  add_observer(observer, func, &block)
+  self
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ConcurrentUpdateError.html b/docs/1.1.10/Concurrent/ConcurrentUpdateError.html new file mode 100644 index 000000000..42c54e266 --- /dev/null +++ b/docs/1.1.10/Concurrent/ConcurrentUpdateError.html @@ -0,0 +1,176 @@ + + + + + + + Exception: Concurrent::ConcurrentUpdateError + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Exception: Concurrent::ConcurrentUpdateError + + + +

+
+ +
+
Inherits:
+
+ ThreadError + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Private Implementation: This abstraction is a private, internal +implementation detail. It should never be used directly.

+
+
+ + + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
CONC_UP_ERR_BACKTRACE = +
+
+

frozen pre-allocated backtrace to speed ConcurrentUpdateError

+ + +
+
+
+ + +
+
+
['backtrace elided; set verbose to enable'].freeze
+ +
+ + + + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/CountDownLatch.html b/docs/1.1.10/Concurrent/CountDownLatch.html new file mode 100644 index 000000000..8c1a3c4d1 --- /dev/null +++ b/docs/1.1.10/Concurrent/CountDownLatch.html @@ -0,0 +1,540 @@ + + + + + + + Class: Concurrent::CountDownLatch + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::CountDownLatch + + + +

+
+ +
+
Inherits:
+
+ CountDownLatchImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb
+
+ +
+ +

Overview

+
+

A synchronization object that allows one thread to wait on multiple other threads. +The thread that will wait creates a CountDownLatch and sets the initial value +(normally equal to the number of other threads). The initiating thread passes the +latch to the other threads then waits for the other threads by calling the #wait +method. Each of the other threads calls #count_down when done with its work. +When the latch counter reaches zero the waiting thread is unblocked and continues +with its work. A CountDownLatch can be used only once. Its value cannot be reset.

+ + +
+
+
+ +
+

Examples:

+ + +

Waiter and Decrementer

+

+ +
latch = Concurrent::CountDownLatch.new(3)
+
+waiter = Thread.new do
+  latch.wait()
+  puts ("Waiter released")
+end
+
+decrementer = Thread.new do
+  sleep(1)
+  latch.count_down
+  puts latch.count
+
+  sleep(1)
+  latch.count_down
+  puts latch.count
+
+  sleep(1)
+  latch.count_down
+  puts latch.count
+end
+
+[waiter, decrementer].each(&:join)
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(count = 1) ⇒ undocumented + + + + + +

+
+

Create a new CountDownLatch with the initial count.

+ + +
+
+
+

Parameters:

+
    + +
  • + + count + + + (new) + + + (defaults to: 1) + + + — +

    the initial count

    +
    + +
  • + +
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if count is not an integer or is less than zero

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+98
+99
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb', line 98
+
+class CountDownLatch < CountDownLatchImplementation
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #countFixnum + + + + + +

+
+

The current value of the counter.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    the current value of the counter

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+98
+99
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb', line 98
+
+class CountDownLatch < CountDownLatchImplementation
+end
+
+
+ +
+

+ + #count_downundocumented + + + + + +

+
+

Signal the latch to decrement the counter. Will signal all blocked threads when +the count reaches zero.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+98
+99
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb', line 98
+
+class CountDownLatch < CountDownLatchImplementation
+end
+
+
+ +
+

+ + #wait(timeout = nil) ⇒ Boolean + + + + + +

+
+

Block on the latch until the counter reaches zero or until timeout is reached.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Fixnum) + + + (defaults to: nil) + + + — +

    the number of seconds to wait for the counter or nil +to block indefinitely

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the count reaches zero else false on timeout

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+98
+99
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb', line 98
+
+class CountDownLatch < CountDownLatchImplementation
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/CyclicBarrier.html b/docs/1.1.10/Concurrent/CyclicBarrier.html new file mode 100644 index 000000000..1a4c26e49 --- /dev/null +++ b/docs/1.1.10/Concurrent/CyclicBarrier.html @@ -0,0 +1,788 @@ + + + + + + + Class: Concurrent::CyclicBarrier + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::CyclicBarrier + + + +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb
+
+ +
+ +

Overview

+
+

A synchronization aid that allows a set of threads to all wait for each +other to reach a common barrier point.

+ + +
+
+
+ +
+

Examples:

+ + +
barrier = Concurrent::CyclicBarrier.new(3)
+jobs    = Array.new(3) { |i| -> { sleep i; p done: i } }
+process = -> (i) do
+  # waiting to start at the same time
+  barrier.wait
+  # execute job
+  jobs[i].call
+  # wait for others to finish
+  barrier.wait
+end
+threads = 2.times.map do |i|
+  Thread.new(i, &process)
+end
+
+# use main as well
+process.call 2
+
+# here we can be sure that all jobs are processed
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(parties) { ... } ⇒ CyclicBarrier + + + + + +

+
+

Create a new CyclicBarrier that waits for parties threads

+ + +
+
+
+

Parameters:

+
    + +
  • + + parties + + + (Fixnum) + + + + — +

    the number of parties

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    an optional block that will be executed that will be executed after +the last thread arrives and before the others are released

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if parties is not an integer or is less than zero

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+40
+41
+42
+43
+44
+45
+46
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb', line 40
+
+def initialize(parties, &block)
+  Utility::NativeInteger.ensure_integer_and_bounds parties
+  Utility::NativeInteger.ensure_positive_and_no_zero parties
+
+  super(&nil)
+  synchronize { ns_initialize parties, &block }
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #broken?Boolean + + + + + +

+
+

A barrier can be broken when:

+ +
    +
  • a thread called the reset method while at least one other thread was waiting
  • +
  • at least one thread timed out on wait method
  • +
+ +

A broken barrier can be restored using reset it's safer to create a new one

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the barrier is broken otherwise false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+105
+106
+107
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb', line 105
+
+def broken?
+  synchronize { @generation.status != :waiting }
+end
+
+
+ +
+

+ + #number_waitingFixnum + + + + + +

+
+

Returns the number of threads currently waiting on the barrier.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    the number of threads currently waiting on the barrier

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb', line 54
+
+def number_waiting
+  synchronize { @number_waiting }
+end
+
+
+ +
+

+ + #partiesFixnum + + + + + +

+
+

Returns the number of threads needed to pass the barrier.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    the number of threads needed to pass the barrier

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+49
+50
+51
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb', line 49
+
+def parties
+  synchronize { @parties }
+end
+
+
+ +
+

+ + #resetnil + + + + + +

+
+

resets the barrier to its initial state +If there is at least one waiting thread, it will be woken up, the wait +method will return false and the barrier will be broken +If the barrier is broken, this method restores it to the original state

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (nil) + + + +
  • + +
+ +
+ + + + +
+
+
+
+95
+96
+97
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb', line 95
+
+def reset
+  synchronize { ns_generation_done @generation, :reset }
+end
+
+
+ +
+

+ + #wait(timeout = nil) ⇒ Boolean + + + + + +

+
+

Blocks on the barrier until the number of waiting threads is equal to +parties or until timeout is reached or reset is called +If a block has been passed to the constructor, it will be executed once by + the last arrived thread before releasing the others

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Fixnum) + + + (defaults to: nil) + + + — +

    the number of seconds to wait for the counter or +nil to block indefinitely

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the count reaches zero else false on +timeout or on reset or if the barrier is broken

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb', line 66
+
+def wait(timeout = nil)
+  synchronize do
+
+    return false unless @generation.status == :waiting
+
+    @number_waiting += 1
+
+    if @number_waiting == @parties
+      @action.call if @action
+      ns_generation_done @generation, :fulfilled
+      true
+    else
+      generation = @generation
+      if ns_wait_until(timeout) { generation.status != :waiting }
+        generation.status == :fulfilled
+      else
+        ns_generation_done generation, :broken, false
+        false
+      end
+    end
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Delay.html b/docs/1.1.10/Concurrent/Delay.html new file mode 100644 index 000000000..2c6b243b0 --- /dev/null +++ b/docs/1.1.10/Concurrent/Delay.html @@ -0,0 +1,1738 @@ + + + + + + + Class: Concurrent::Delay + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Delay + + + +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Concern::Obligation
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/delay.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

The default behavior of Delay is to block indefinitely when +calling either value or wait, executing the delayed operation on +the current thread. This makes the timeout value completely +irrelevant. To enable non-blocking behavior, use the executor +constructor option. This will cause the delayed operation to be +execute on the given executor, allowing the call to timeout.

+
+
+ +

Lazy evaluation of a block yielding an immutable result. Useful for +expensive operations that may never be needed. It may be non-blocking, +supports the Concern::Obligation interface, and accepts the injection of +custom executor upon which to execute the block. Processing of +block will be deferred until the first time #value is called. +At that time the caller can choose to return immediately and let +the block execute asynchronously, block indefinitely, or block +with a timeout.

+ +

When a Delay is created its state is set to pending. The value and +reason are both nil. The first time the #value method is called the +enclosed opration will be run and the calling thread will block. Other +threads attempting to call #value will block as well. Once the operation +is complete the value will be set to the result of the operation or the +reason will be set to the raised exception, as appropriate. All threads +blocked on #value will return. Subsequent calls to #value will immediately +return the cached value. The operation will only be run once. This means that +any side effects created by the operation will only happen once as well.

+ +

Delay includes the Concurrent::Concern::Dereferenceable mixin to support thread +safety of the reference returned by #value.

+ +

Copy Options

+ +

Object references in Ruby are mutable. This can lead to serious +problems when the #value of an object is a mutable reference. Which +is always the case unless the value is a Fixnum, Symbol, or similar +"primitive" data type. Each instance can be configured with a few +options that can help protect the program from potentially dangerous +operations. Each of these options can be optionally set when the object +instance is created:

+ +
    +
  • :dup_on_deref When true the object will call the #dup method on +the value object every time the #value method is called +(default: false)
  • +
  • :freeze_on_deref When true the object will call the #freeze +method on the value object every time the #value method is called +(default: false)
  • +
  • :copy_on_deref When given a Proc object the Proc will be run +every time the #value method is called. The Proc will be given +the current value as its only argument and the result returned by +the block will be the return value of the #value call. When nil +this option will be ignored (default: nil)
  • +
+ +

When multiple deref options are set the order of operations is strictly defined. +The order of deref operations is:

+ +
    +
  • :copy_on_deref
  • +
  • :dup_on_deref
  • +
  • :freeze_on_deref
  • +
+ +

Because of this ordering there is no need to #freeze an object created by a +provided :copy_on_deref block. Simply set :freeze_on_deref to true. +Setting both :dup_on_deref to true and :freeze_on_deref to true is +as close to the behavior of a "pure" functional language (like Erlang, Clojure, +or Haskell) as we are likely to get in Ruby.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(opts = {}) { ... } ⇒ Delay + + + + + +

+
+

Create a new Delay in the :pending state.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from #value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from #value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the #value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
+ + +

Yields:

+
    + +
  • + + + + + + + +

    the delayed operation to perform

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+62
+63
+64
+65
+66
+
+
# File 'lib/concurrent-ruby/concurrent/delay.rb', line 62
+
+def initialize(opts = {}, &block)
+  raise ArgumentError.new('no block given') unless block_given?
+  super(&nil)
+  synchronize { ns_initialize(opts, &block) }
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #reconfigure { ... } ⇒ true, false + + + + + +

+
+

Reconfigures the block returning the value if still #incomplete?

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the delayed operation to perform

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    if success

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+
+
# File 'lib/concurrent-ruby/concurrent/delay.rb', line 146
+
+def reconfigure(&block)
+  synchronize do
+    raise ArgumentError.new('no block given') unless block_given?
+    unless @evaluation_started
+      @task = block
+      true
+    else
+      false
+    end
+  end
+end
+
+
+ +
+

+ + #value(timeout = nil) ⇒ Object + + + + + +

+
+ +
+ Note: +

The default behavior of Delay is to block indefinitely when +calling either value or wait, executing the delayed operation on +the current thread. This makes the timeout value completely +irrelevant. To enable non-blocking behavior, use the executor +constructor option. This will cause the delayed operation to be +execute on the given executor, allowing the call to timeout.

+
+
+ +

Return the value this object represents after applying the options +specified by the #set_deref_options method. If the delayed operation +raised an exception this method will return nil. The execption object +can be accessed via the #reason method.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum number of seconds to wait

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of the object

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+
+
# File 'lib/concurrent-ruby/concurrent/delay.rb', line 77
+
+def value(timeout = nil)
+  if @executor # TODO (pitr 12-Sep-2015): broken unsafe read?
+    super
+  else
+    # this function has been optimized for performance and
+    # should not be modified without running new benchmarks
+    synchronize do
+      execute = @evaluation_started = true unless @evaluation_started
+      if execute
+        begin
+          set_state(true, @task.call, nil)
+        rescue => ex
+          set_state(false, nil, ex)
+        end
+      elsif incomplete?
+        raise IllegalOperationError, 'Recursive call to #value during evaluation of the Delay'
+      end
+    end
+    if @do_nothing_on_deref
+      @value
+    else
+      apply_deref_options(@value)
+    end
+  end
+end
+
+
+ +
+

+ + #value!(timeout = nil) ⇒ Object + + + + + +

+
+ +
+ Note: +

The default behavior of Delay is to block indefinitely when +calling either value or wait, executing the delayed operation on +the current thread. This makes the timeout value completely +irrelevant. To enable non-blocking behavior, use the executor +constructor option. This will cause the delayed operation to be +execute on the given executor, allowing the call to timeout.

+
+
+ +

Return the value this object represents after applying the options +specified by the #set_deref_options method. If the delayed operation +raised an exception, this method will raise that exception (even when) +the operation has already been executed).

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum number of seconds to wait

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of the object

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    when #rejected? raises #reason

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+113
+114
+115
+116
+117
+118
+119
+120
+121
+
+
# File 'lib/concurrent-ruby/concurrent/delay.rb', line 113
+
+def value!(timeout = nil)
+  if @executor
+    super
+  else
+    result = value
+    raise @reason if @reason
+    result
+  end
+end
+
+
+ +
+

+ + #wait(timeout = nil) ⇒ Object + + + + + +

+
+ +
+ Note: +

The default behavior of Delay is to block indefinitely when +calling either value or wait, executing the delayed operation on +the current thread. This makes the timeout value completely +irrelevant. To enable non-blocking behavior, use the executor +constructor option. This will cause the delayed operation to be +execute on the given executor, allowing the call to timeout.

+
+
+ +

Return the value this object represents after applying the options +specified by the #set_deref_options method.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Integer) + + + (defaults to: nil) + + + — +

    (nil) the maximum number of seconds to wait for +the value to be computed. When nil the caller will block indefinitely.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+132
+133
+134
+135
+136
+137
+138
+139
+140
+
+
# File 'lib/concurrent-ruby/concurrent/delay.rb', line 132
+
+def wait(timeout = nil)
+  if @executor
+    execute_task_once
+    super(timeout)
+  else
+    value
+  end
+  self
+end
+
+
+ +
+

+ + #complete?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Has the obligation completed processing?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #exception(*args) ⇒ undocumented + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+ + +
+
+
+ +
+

Examples:

+ + +

allows Obligation to be risen

+

+ +
rejected_ivar = Ivar.new.fail
+raise rejected_ivar
+ +
+ + +
+
+ +
+

+ + #fulfilled?Boolean + + + + Also known as: + realized? + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Has the obligation been fulfilled?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #incomplete?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Is the obligation still awaiting completion of processing?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #pending?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Is obligation completion still pending?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #reasonException + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

If an exception was raised during processing this will return the +exception object. Will return nil when the state is pending or if +the obligation has been successfully fulfilled.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Exception) + + + + — +

    the exception raised during processing or nil

    +
    + +
  • + +
+ +
+
+ +
+

+ + #rejected?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Has the obligation been rejected?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #stateSymbol + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

The current state of the obligation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Symbol) + + + + — +

    the current state

    +
    + +
  • + +
+ +
+
+ +
+

+ + #unscheduled?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Is the obligation still unscheduled?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #wait!(timeout = nil) ⇒ Obligation + + + + Also known as: + no_error! + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Wait until obligation is complete or the timeout is reached. Will re-raise +any exceptions raised during processing (but will not raise an exception +on timeout).

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Obligation) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    raises the reason when rejected

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Edge.html b/docs/1.1.10/Concurrent/Edge.html new file mode 100644 index 000000000..d7cb9bc6f --- /dev/null +++ b/docs/1.1.10/Concurrent/Edge.html @@ -0,0 +1,165 @@ + + + + + + + Module: Concurrent::Edge + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Edge + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge.rb,
+ lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb,
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb,
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb
+
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

A submodule for unstable, highly experimental features that are likely to +change often and which may never become part of the core gem. Also for +new, experimental version of abstractions already in the core gem.

+ +

Most new features should start in this module, clearly indicating the +experimental and unstable nature of the feature. Once a feature becomes +more stable and is a candidate for inclusion in the core gem it should +be moved up to the Concurrent module, where it would reside once merged +into the core gem.

+ +

The only exception to this is for features which replace features from +the core gem in ways that are breaking and not backward compatible. These +features should remain in this module until merged into the core gem. This +will prevent namespace collisions.

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: LockFreeLinkedSet + + +

+ + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet.html b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet.html new file mode 100644 index 000000000..9cc389e9b --- /dev/null +++ b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet.html @@ -0,0 +1,921 @@ + + + + + + + Class: Concurrent::Edge::LockFreeLinkedSet + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Edge::LockFreeLinkedSet + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Enumerable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb,
+ lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb,
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb
+
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

This class implements a lock-free linked set. The general idea of this +implementation is this: each node has a successor which is an Atomic +Markable Reference. This is used to ensure that all modifications to the +list are atomic, preserving the structure of the linked list under any +circumstance in a multithreaded application.

+ +

One interesting aspect of this algorithm occurs with removing a node. +Instead of physically removing a node when remove is called, a node is +logically removed, by 'marking it.' By doing this, we prevent calls to +remove from traversing the list twice to perform a physical removal. +Instead, we have have calls to add and remove clean up all marked +nodes they encounter while traversing the list.

+ +

This algorithm is a variation of the Nonblocking Linked Set found in +'The Art of Multiprocessor Programming' by Herlihy and Shavit.

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: Head, Node, Tail, Window + + +

+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Constructor Details

+ +
+

+ + #initialize(initial_size = 0, val = nil) ⇒ LockFreeLinkedSet + + + + + +

+
+

Returns a new instance of LockFreeLinkedSet.

+ + +
+
+
+

Parameters:

+
    + +
  • + + initial_size + + + (Fixnum) + + + (defaults to: 0) + + + — +

    the size of the linked_list to initialize

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+28
+29
+30
+31
+32
+33
+34
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb', line 28
+
+def initialize(initial_size = 0, val = nil)
+  @head = Head.new
+
+  initial_size.times do
+    val = block_given? ? yield : val
+    add val
+  end
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #<<(item) ⇒ Object + + + + + +

+
+

ock_free_linked_list_method_<<

+ +

Atomically adds the item to the set if it does not yet exist.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item you wish to insert

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the set on which the :<< method was invoked

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+72
+73
+74
+75
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb', line 72
+
+def <<(item)
+  add item
+  self
+end
+
+
+ +
+

+ + #add(item) ⇒ Boolean + + + + + +

+
+

Atomically adds the item to the set if it does not yet exist. Note: +internally the set uses Object#hash to compare equality of items, +meaning that Strings and other objects will be considered equal +despite being different objects.

+ +

that the item was already in the set.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item you wish to insert

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if successful. A false return indicates

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb', line 48
+
+def add(item)
+  loop do
+    window = Window.find @head, item
+
+    pred, curr = window.pred, window.curr
+
+    # Item already in set
+    return false if curr == item
+
+    node = Node.new item, curr
+
+    if pred.successor_reference.compare_and_set curr, node, false, false
+      return true
+    end
+  end
+end
+
+
+ +
+

+ + #contains?(item) ⇒ Boolean + + + + + +

+
+

Atomically checks to see if the set contains an item. This method +compares equality based on the Object#hash method, meaning that the +hashed contents of an object is what determines equality instead of +Object#object_id

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item you to check for presence in the set

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    whether or not the item is in the set

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb', line 87
+
+def contains?(item)
+  curr = @head
+
+  while curr < item
+    curr = curr.next_node
+    marked = curr.successor_reference.marked?
+  end
+
+  curr == item && !marked
+end
+
+
+ +
+

+ + #each {|item| ... } ⇒ Object + + + + + +

+
+

An iterator to loop through the set.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (item) + + + + — +

    each item in the set

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item you to remove from the set

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    self: the linked set on which each was called

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb', line 132
+
+def each
+  return to_enum unless block_given?
+
+  curr = @head
+
+  until curr.last?
+    curr = curr.next_node
+    marked = curr.successor_reference.marked?
+
+    yield curr.data unless marked
+  end
+
+  self
+end
+
+
+ +
+

+ + #remove(item) ⇒ Boolean + + + + + +

+
+

Atomically attempts to remove an item, comparing using Object#hash.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Object) + + + + — +

    the item you to remove from the set

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    whether or not the item was removed from the set

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set.rb', line 105
+
+def remove(item)
+  loop do
+    window = Window.find @head, item
+    pred, curr = window.pred, window.curr
+
+    return false if curr != item
+
+    succ = curr.next_node
+    removed = curr.successor_reference.compare_and_set succ, succ, false, true
+
+    #next_node unless removed
+    next unless removed
+
+    pred.successor_reference.compare_and_set curr, succ, false, false
+
+    return true
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Head.html b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Head.html new file mode 100644 index 000000000..f007af4d0 --- /dev/null +++ b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Head.html @@ -0,0 +1,234 @@ + + + + + + + Class: Concurrent::Edge::LockFreeLinkedSet::Head + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Edge::LockFreeLinkedSet::Head + + + +

+
+ +
+
Inherits:
+
+ Node + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb
+
+ +
+ +

Overview

+
+

Internal sentinel node for the Head of the set. Head is always smaller +than any other node.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::Edge::LockFreeLinkedSet::Node

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #<=>(_other) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+75
+76
+77
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 75
+
+def <=>(_other)
+  -1
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Node.html b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Node.html new file mode 100644 index 000000000..1b1276b6f --- /dev/null +++ b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Node.html @@ -0,0 +1,698 @@ + + + + + + + Class: Concurrent::Edge::LockFreeLinkedSet::Node + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Edge::LockFreeLinkedSet::Node + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + +
+
Includes:
+
Comparable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+

Direct Known Subclasses

+

Head, Tail

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(data = nil, successor = nil) ⇒ Node + + + + + +

+
+

Returns a new instance of Node.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+11
+12
+13
+14
+15
+16
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 11
+
+def initialize(data = nil, successor = nil)
+  super()
+  @SuccessorReference  = AtomicMarkableReference.new(successor || Tail.new)
+  @Data                = data
+  @Key                 = key_for data
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #<=>(other) ⇒ undocumented + + + + + +

+
+

We use Object#hash as a way to enforce ordering on the nodes. This +can be configurable in the future; for example, you could enforce a +split-ordering on the nodes in the set.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+51
+52
+53
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 51
+
+def <=>(other)
+  @Key <=> other.hash
+end
+
+
+ +
+

+ + #dataundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+18
+19
+20
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 18
+
+def data
+  @Data
+end
+
+
+ +
+

+ + #keyundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+26
+27
+28
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 26
+
+def key
+  @Key
+end
+
+
+ +
+

+ + #key_for(data) ⇒ undocumented + + + + + +

+
+

This method provides a unqiue key for the data which will be used for +ordering. This is configurable, and changes depending on how you wish +the nodes to be ordered.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+44
+45
+46
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 44
+
+def key_for(data)
+  data.hash
+end
+
+
+ +
+

+ + #last?Boolean + + + + + +

+
+

Check to see if the node is the last in the list.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+31
+32
+33
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 31
+
+def last?
+  @SuccessorReference.value.is_a? Tail
+end
+
+
+ +
+

+ + #next_nodeundocumented + + + + + +

+
+

Next node in the list. Note: this is not the AtomicMarkableReference +of the next node, this is the actual Node itself.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+37
+38
+39
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 37
+
+def next_node
+  @SuccessorReference.value
+end
+
+
+ +
+

+ + #successor_referenceundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+22
+23
+24
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 22
+
+def successor_reference
+  @SuccessorReference
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Tail.html b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Tail.html new file mode 100644 index 000000000..897982cb1 --- /dev/null +++ b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Tail.html @@ -0,0 +1,301 @@ + + + + + + + Class: Concurrent::Edge::LockFreeLinkedSet::Tail + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Edge::LockFreeLinkedSet::Tail + + + +

+
+ +
+
Inherits:
+
+ Node + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb
+
+ +
+ +

Overview

+
+

Internal sentinel node for the Tail. It is always greater than all +other nodes, and it is self-referential; meaning its successor is +a self-loop.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(_data = nil, _succ = nil) ⇒ Tail + + + + + +

+
+

Returns a new instance of Tail.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+60
+61
+62
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 60
+
+def initialize(_data = nil, _succ = nil)
+  @SuccessorReference = AtomicMarkableReference.new self
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #<=>(_other) ⇒ undocumented + + + + + +

+
+

Always greater than other nodes. This means that traversal will end +at the tail node since we are comparing node size in the traversal.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+66
+67
+68
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/node.rb', line 66
+
+def <=>(_other)
+  1
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Window.html b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Window.html new file mode 100644 index 000000000..8f917bf64 --- /dev/null +++ b/docs/1.1.10/Concurrent/Edge/LockFreeLinkedSet/Window.html @@ -0,0 +1,497 @@ + + + + + + + Class: Concurrent::Edge::LockFreeLinkedSet::Window + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Edge::LockFreeLinkedSet::Window + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(pred, curr) ⇒ Window + + + + + +

+
+

Returns a new instance of Window.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb', line 7
+
+def initialize(pred, curr)
+  @pred, @curr = pred, curr
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #currundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+5
+6
+7
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb', line 5
+
+def curr
+  @curr
+end
+
+
+ + + +
+

+ + #predundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+5
+6
+7
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb', line 5
+
+def pred
+  @pred
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .find(head, item) ⇒ undocumented + + + + + +

+
+

This method is used to find a 'window' for which add and remove +methods can use to know where to add and remove from the list. However, +it has another responsibilility, which is to physically unlink any +nodes marked for removal in the set. This prevents adds/removes from +having to retraverse the list to physically unlink nodes.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_linked_set/window.rb', line 16
+
+def self.find(head, item)
+  loop do
+    break_inner_loops = false
+    pred = head
+    curr = pred.next_node
+
+    loop do
+      succ, marked = curr.successor_reference.get
+
+      # Remove sequence of marked nodes
+      while marked
+        removed = pred.successor_reference.compare_and_set curr, succ, false, false
+
+        # If could not remove node, try again
+        break_inner_loops = true && break unless removed
+
+        curr = succ
+        succ, marked = curr.successor_reference.get
+      end
+
+      break if break_inner_loops
+
+      # We have found a window
+      return new pred, curr if curr >= item
+
+      pred = curr
+      curr = succ
+    end
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor.html b/docs/1.1.10/Concurrent/ErlangActor.html new file mode 100644 index 000000000..02e9d1989 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor.html @@ -0,0 +1,1018 @@ + + + + + + + Module: Concurrent::ErlangActor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::ErlangActor + + + +

+
+ + + + +
+
Extended by:
+
FunctionShortcuts, Functions
+
+ + + +
+
Includes:
+
EnvironmentConstants
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

This module provides actor abstraction that has same behaviour as Erlang actor.

+ +

Examples

+ +

The simplest example is to use the actor as an asynchronous execution. +Although, Promises.future { 1 + 1 } is better suited for that purpose.

+ +
actor = Concurrent::ErlangActor.spawn(type: :on_thread, name: 'addition') { 1 + 1 }
+# => #
+actor.terminated.value!                  # => 2
+
+ +

Let's send some messages and maintain some internal state +which is what actors are good for.

+ +
actor = Concurrent::ErlangActor.spawn(type: :on_thread, name: 'sum') do
+  sum = 0 # internal state
+  # receive and sum the messages until the actor gets :done
+  while true
+    message = receive
+    break if message == :done
+    # if the message is asked and not only told, 
+    # reply with the current sum (has no effect if actor was not asked)
+    reply sum += message   
+  end
+  # The final value of the actor
+  sum
+end
+# => #
+
+ +

The actor can be either told a message asynchronously, +or asked. The ask method will block until actor replies.

+ +
# tell returns immediately returning the actor 
+actor.tell(1).tell(1)
+# => #
+# blocks, waiting for the answer 
+actor.ask 10                             # => 12
+# stop the actor
+actor.tell :done
+# => #
+# The final value of the actor 
+actor.terminated.value!                  # => 12
+
+ +

Actor types

+ +

There are two types of actors. +The type is specified when calling spawn as a first argument, +Concurrent::ErlangActor.spawn(type: :on_thread, ... or +Concurrent::ErlangActor.spawn(type: :on_pool, ....

+ +

The main difference is in how receive method returns.

+ +
    +
  • :on_thread it blocks the thread until message is available, +then it returns or calls the provided block first.

  • +
  • However, :on_pool it has to free up the thread on the receive +call back to the pool. Therefore the call to receive ends the +execution of current scope. The receive has to be given block +or blocks that act as a continuations and are called +when there is message available.

  • +
+ +

Let's have a look at how the bodies of actors differ between the types:

+ +
ping = Concurrent::ErlangActor.spawn(type: :on_thread) { reply receive }
+# => #
+ping.ask 42                              # => 42
+
+ +

It first calls receive, which blocks the thread of the actor. +When it returns the received message is passed an an argument to reply, +which replies the same value back to the ask method. +Then the actor terminates normally, because there is nothing else to do.

+ +

However when running on pool a block with code which should be evaluated +after the message is received has to be provided.

+ +
ping = Concurrent::ErlangActor.spawn(type: :on_pool) { receive { |m| reply m } }
+# => #
+ping.ask 42                              # => 42
+
+ +

It starts by calling receive which will remember the given block for later +execution when a message is available and stops executing the current scope. +Later when a message becomes available the previously provided block is given +the message and called. The result of the block is the final value of the +normally terminated actor.

+ +

The direct blocking style of :on_thread is simpler to write and more straight +forward however it has limitations. Each :on_thread actor creates a Thread +taking time and resources. +There is also a limited number of threads the Ruby process can create +so you may hit the limit and fail to create more threads and therefore actors.

+ +

Since the :on_pool actor runs on a poll of threads, its creations +is faster and cheaper and it does not create new threads. +Therefore there is no limit (only RAM) on how many actors can be created.

+ +

To simplify, if you need only few actors :on_thread is fine. +However if you will be creating hundreds of actors or +they will be short-lived :on_pool should be used.

+ +

Receiving messages

+ +

Simplest message receive.

+ +
actor = Concurrent::ErlangActor.spawn(type: :on_thread) { receive }
+# => #
+actor.tell :m
+# => #
+actor.terminated.value!                  # => :m
+
+ +

which also works for actor on pool, +because if no block is given it will use a default block { |v| v }

+ +
actor = Concurrent::ErlangActor.spawn(type: :on_pool) { receive { |v| v } }
+# => #
+# can simply be following
+actor = Concurrent::ErlangActor.spawn(type: :on_pool) { receive }
+# => #
+actor.tell :m
+# => #
+actor.terminated.value!                  # => :m
+
+ +

The received message type can be limited.

+ +
Concurrent::ErlangActor.
+  spawn(type: :on_thread) { receive(Numeric).succ }.
+  tell('junk'). # ignored message
+  tell(42).
+  terminated.value!                      # => 43
+
+ +

On pool it requires a block.

+ +
Concurrent::ErlangActor.
+  spawn(type: :on_pool) { receive(Numeric) { |v| v.succ } }.
+  tell('junk'). # ignored message
+  tell(42).
+  terminated.value!                      # => 43
+
+ +

By the way, the body written for on pool actor will work for on thread actor +as well.

+ +
Concurrent::ErlangActor.
+  spawn(type: :on_thread) { receive(Numeric) { |v| v.succ } }.
+  tell('junk'). # ignored message
+  tell(42).
+  terminated.value!                      # => 43
+
+ +

The receive method can be also used to dispatch based on the received message.

+ +
actor = Concurrent::ErlangActor.spawn(type: :on_thread) do
+  while true
+    receive(on(Symbol) { |s| reply s.to_s },
+            on(And[Numeric, -> v { v >= 0 }]) { |v| reply v.succ },
+            # put last works as else
+            on(ANY) do |v| 
+              reply :bad_message
+              terminate [:bad_message, v]
+            end)            
+  end 
+end
+# => #
+actor.ask 1                              # => 2
+actor.ask 2                              # => 3
+actor.ask :value                         # => "value"
+# this malformed message will terminate the actor
+actor.ask -1                             # => :bad_message
+# the actor is no longer alive, so ask fails
+actor.ask "junk" rescue $!
+# => #>
+actor.terminated.result                  # => [false, nil, [:bad_message, -1]]
+
+ +

And a same thing for the actor on pool. +Since it cannot loop it will call the body method repeatedly.

+ +
module Behaviour
+  def body
+    receive(on(Symbol) do |s| 
+              reply s.to_s 
+              body # call again  
+            end,
+            on(And[Numeric, -> v { v >= 0 }]) do |v| 
+              reply v.succ
+              body # call again 
+            end,
+            # put last works as else
+            on(ANY) do |v| 
+              reply :bad_message
+              terminate [:bad_message, v]
+            end)  
+  end
+end                                      # => :body
+
+actor = Concurrent::ErlangActor.spawn(type: :on_pool, environment: Behaviour) { body }
+# => #
+actor.ask 1                              # => 2
+actor.ask 2                              # => 3
+actor.ask :value                         # => "value"
+# this malformed message will terminate the actor
+actor.ask -1                             # => :bad_message
+# the actor is no longer alive, so ask fails
+actor.ask "junk" rescue $!
+# => #>
+actor.terminated.result                  # => [false, nil, [:bad_message, -1]]
+
+ +

Since the behavior is stable in this case we can simplify with the :keep option +that will keep the receive rules until another receive is called +replacing the kept rules.

+ +
actor = Concurrent::ErlangActor.spawn(type: :on_pool) do
+  receive(on(Symbol) { |s| reply s.to_s },
+          on(And[Numeric, -> v { v >= 0 }]) { |v| reply v.succ },
+          # put last works as else
+          on(ANY) do |v| 
+            reply :bad_message
+            terminate [:bad_message, v]
+          end,
+          keep: true)            
+end
+# => #
+actor.ask 1                              # => 2
+actor.ask 2                              # => 3
+actor.ask :value                         # => "value"
+# this malformed message will terminate the actor
+actor.ask -1                             # => :bad_message
+# the actor is no longer alive, so ask fails
+actor.ask "junk" rescue $!
+# => #>
+actor.terminated.result                  # => [false, nil, [:bad_message, -1]]
+
+ +

Erlang behaviour

+ +

The actor matches Erlang processes in behaviour. +Therefore it supports the usual Erlang actor linking, monitoring, exit behaviour, etc.

+ +
actor = Concurrent::ErlangActor.spawn(type: :on_thread) do
+  spawn(link: true) do # equivalent of spawn_link in Erlang
+    terminate :err # equivalent of exit in Erlang    
+  end
+  trap # equivalent of process_flag(trap_exit, true) 
+  receive  
+end
+# => #
+actor.terminated.value!
+# => ##     @from=
+#      #,
+#     @reason=:err>
+
+ +

The methods have same or very similar name to be easily found. +The one exception from the original Erlang naming is exit. +To avoid clashing with Kernel#exit it's called terminate.

+ +

Until there is more information available here, the chapters listed below from +a book lern you some Erlang +are excellent source of information. +The Ruby ErlangActor implementation has same behaviour.

+ + + +

If anything behaves differently than in Erlang, please file an issue.

+ +

Chapters or points to be added

+ +
    +
  • More erlang behaviour examples.
  • +
  • The mailbox can be bounded in size, +then the tell and ask will block until there is space available in the mailbox. +Useful for building systems with backpressure.
  • +
  • #tell_op and ask_op method examples, integration with promises.
  • +
  • Best practice: always use timeout, +and do something if the message does not arrive, don't leave the actor stuck.
  • +
  • Best practice: drop and log unrecognized messages, +or be even more defensive and terminate.
  • +
  • Environment definition for actors.
  • +
+

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: EnvironmentConstants, FunctionShortcuts, Functions + + + + Classes: Down, Environment, Error, NoActor, NoReply, Pid, Reference, Terminated + + +

+ + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + + + + + + + + + + +
+

Class Method Details

+ + +
+

+ + .default_actor_executorExecutorService + + + + + + + Originally defined in module + Functions + + +

+
+

Returns the default executor service for actors.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (ExecutorService) + + + + — +

    the default executor service for actors

    +
    + +
  • + +
+ +
+
+ +
+

+ + .default_executorExecutorService + + + + + + + Originally defined in module + Functions + + +

+
+

Returns the default executor service, +may be shared by other abstractions.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (ExecutorService) + + + + — +

    the default executor service, +may be shared by other abstractions

    +
    + +
  • + +
+ +
+
+ +
+

+ + .spawn(*args, **kwargs, &body) ⇒ Pid + + + + + + + Originally defined in module + FunctionShortcuts + + +

+
+

Optionally included shortcut method for Concurrent::ErlangActor::Functions#spawn_actor

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Pid) + + + +
  • + +
+ +
+
+ +
+

+ + .spawn_actor(*args, type:, channel: Promises::Channel.new, environment: Environment, name: nil, executor: default_actor_executor, &body) ⇒ Pid + + + + + + + Originally defined in module + Functions + + +

+
+

Creates an actor. Same as Environment#spawn but lacks link and monitor options.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + +
  • + +
  • + + type + + + (:on_thread, :on_pool) + + + +
  • + +
  • + + channel + + + (Channel) + + + (defaults to: Promises::Channel.new) + + +
  • + +
  • + + environment + + + (Environment, Module) + + + (defaults to: Environment) + + +
  • + +
  • + + name + + + (#to_s) + + + (defaults to: nil) + + + — +

    of the actor

    +
    + +
  • + +
  • + + executor + + + (ExecutorService) + + + (defaults to: default_actor_executor) + + + — +

    of the actor

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Pid) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + .terminate(pid, reason) ⇒ true + + + + + + + Originally defined in module + FunctionShortcuts + + +

+
+

Optionally included shortcut method for Concurrent::ErlangActor::Functions#terminate_actor

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + +
  • + +
+ +
+
+ +
+

+ + .terminate_actor(pid, reason) ⇒ true + + + + + + + Originally defined in module + Functions + + +

+
+

Same as Environment#terminate, but it requires pid.

+ + +
+
+
+

Parameters:

+
    + +
  • + + pid + + + (Pid) + + + +
  • + +
  • + + reason + + + (Object, :normal, :kill) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/Down.html b/docs/1.1.10/Concurrent/ErlangActor/Down.html new file mode 100644 index 000000000..b20523ad2 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/Down.html @@ -0,0 +1,638 @@ + + + + + + + Class: Concurrent::ErlangActor::Down + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::Down + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

A message send by a monitored actor when terminated.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Instance Attribute Details

+ + + +
+

+ + #fromPid (readonly) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Pid) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1461
+1462
+1463
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1461
+
+def from
+  @from
+end
+
+
+ + + +
+

+ + #infoObject (readonly) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1465
+1466
+1467
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1465
+
+def info
+  @info
+end
+
+
+ + + +
+

+ + #referenceReference (readonly) + + + + + +

+
+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+1463
+1464
+1465
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1463
+
+def reference
+  @reference
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #==(o) ⇒ true, false + + + + Also known as: + eql? + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1480
+1481
+1482
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1480
+
+def ==(o)
+  o.class == self.class && o.from == @from && o.reference == @reference && o.info == @info
+end
+
+
+ +
+

+ + #hashInteger + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1487
+1488
+1489
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1487
+
+def hash
+  to_ary.hash
+end
+
+
+ +
+

+ + #to_ary::Array(Pis, Reference, Object) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (::Array(Pis, Reference, Object)) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1475
+1476
+1477
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1475
+
+def to_ary
+  [@from, @reference, @info]
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/Environment.html b/docs/1.1.10/Concurrent/ErlangActor/Environment.html new file mode 100644 index 000000000..2c82fb6b0 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/Environment.html @@ -0,0 +1,2114 @@ + + + + + + + Class: Concurrent::ErlangActor::Environment + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::Environment + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

A class providing environment and methods for actor bodies to run in.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #default_executorExecutorService + + + + + +

+
+

Returns a default executor which is picked by spawn call.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (ExecutorService) + + + + — +

    a default executor which is picked by spawn call

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+457
+458
+459
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 457
+
+def default_executor
+  @DefaultExecutor
+end
+
+
+ +
+

+ + #demonitor(reference, *options) ⇒ true, false + + + + + +

+
+

If MonitorRef is a reference which the calling actor obtained by calling #monitor, +this monitoring is turned off. +If the monitoring is already turned off, nothing happens.

+ +

Once demonitor has returned it is guaranteed that no DownSignal message +due to the monitor will be placed in the caller's message queue in the future. +A DownSignal message might have been placed in the caller's message queue prior to the call, though. +Therefore, in most cases, it is advisable to remove such a 'DOWN' message from the message queue +after monitoring has been stopped. +demonitor(reference, :flush) can be used if this cleanup is wanted.

+ +

The behavior of this method can be viewed as two combined operations: +asynchronously send a "demonitor signal" to the monitored actor and +ignore any future results of the monitor.

+ +

Failure: It is an error if reference refers to a monitoring started by another actor. +In that case it may raise an ArgumentError or go unnoticed.

+ +

Options:

+ +
    +
  • :flush - Remove (one) DownSignal message, +if there is one, from the caller's message queue after monitoring has been stopped. +Calling demonitor(pid, :flush) is equivalent to the following, but more efficient:

    + +
    demonitor(pid)
    +receive on(And[DownSignal, -> d { d.reference == reference}], true), timeout: 0, timeout_value: true
    +
  • +
  • info +The returned value is one of the following:

    + +
      +
    • true - The monitor was found and removed. +In this case no DownSignal message due to this monitor have been +nor will be placed in the message queue of the caller.
    • +
    • false - The monitor was not found and could not be removed. +This probably because someone already has placed a DownSignal message +corresponding to this monitor in the caller's message queue.
    • +
    + +

    If the info option is combined with the flush option, +false will be returned if a flush was needed; otherwise, true.

  • +
+ + +
+
+
+

Parameters:

+
    + +
  • + + reference + + + (Reference) + + + +
  • + +
  • + + options + + + (:flush, :info) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+324
+325
+326
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 324
+
+def demonitor(reference, *options)
+  @Actor.demonitor(reference, *options)
+end
+
+
+ +
+
+
+

Creates a link between the calling actor and another actor, +if there is not such a link already. +If a actor attempts to create a link to itself, nothing is done. Returns true.

+ +

If pid does not exist, +the behavior of the method depends on +if the calling actor is trapping exits or not (see #trap):

+ +
    +
  • If the calling actor is not trapping exits link raises with NoActor.
  • +
  • Otherwise, if the calling actor is trapping exits, link returns true, +but an exit signal with reason noproc is sent to the calling actor.
  • +
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + +
  • + +
+

Raises:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+228
+229
+230
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 228
+
+def link(pid)
+  @Actor.link(pid)
+end
+
+
+ +
+

+ + #monitor(pid) ⇒ Reference + + + + + +

+
+

The calling actor starts monitoring actor with given pid.

+ +

A DownSignal message will be sent to the monitoring actor +if the actor with given pid dies, +or if the actor with given pid does not exist.

+ +

The monitoring is turned off either +when the DownSignal message is sent, or when #demonitor is called.

+ +

Making several calls to monitor for the same pid is not an error; +it results in as many, completely independent, monitorings.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+277
+278
+279
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 277
+
+def monitor(pid)
+  @Actor.monitor(pid)
+end
+
+
+ +
+

+ + #name#to_s + + + + + +

+
+

Returns the name od the actor if provided to spawn method.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (#to_s) + + + + — +

    the name od the actor if provided to spawn method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+146
+147
+148
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 146
+
+def name
+  pid.name
+end
+
+
+ +
+

+ + #on(matcher, value = nil, &block) ⇒ undocumented + + + + + +

+
+

Helper for constructing a #receive rules

+ + +
+
+
+ +
+

Examples:

+ + +
receive on(Numeric) { |v| v.succ },
+        on(ANY) { terminate :bad_message }
+ +
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+177
+178
+179
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 177
+
+def on(matcher, value = nil, &block)
+  @Actor.on matcher, value, &block
+end
+
+
+ +
+

+ + #pidPid + + + + + +

+
+

Returns the pid of this actor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Pid) + + + + — +

    the pid of this actor

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+141
+142
+143
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 141
+
+def pid
+  @Actor.pid
+end
+
+
+ +
+

+ + #receive(*rules, timeout: nil, timeout_value: nil, **options) {|message| ... } ⇒ Object, nothing + + + + + +

+
+

Receive a message.

+ + +
+
+
+

Parameters:

+
    + +
  • + + rules + + + (::Array(), ::Array(#===), ::Array<::Array(#===, Proc)>) + + + + — +
      +
    • No rule - receive, receive {|m| m.to_s}
    • +
    • or single rule which can be combined with the supplied block - +receive(Numeric), receive(Numeric) {|v| v.succ}
    • +
    • or array of matcher-proc pairs - +receive on(Numeric) { |v| v*2 }, on(Symbol) { |c| do_command c }
    • +
    +
    + +
  • + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    how long it should wait for the message

    +
    + +
  • + +
  • + + timeout_value + + + (Object) + + + (defaults to: nil) + + + — +

    if rule on(TIMEOUT) { do_something } is not specified +then timeout_value is returned.

    +
    + +
  • + +
  • + + options + + + (Hash) + + + + — +

    other options specific by type of the actor

    +
    + +
  • + +
+ + + + + + + + + + +

Options Hash (**options):

+
    + +
  • + :keep + (true, false) + + + + + —

    Keep the rules and repeatedly call the associated blocks, +until receive is called again.

    +
    + +
  • + +
+ + +

Yields:

+
    + +
  • + + + (message) + + + + — +

    block +to process the message +if single matcher is supplied

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + message + + + (Object) + + + + — +

    the received message

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object, nothing) + + + + — +

    depends on type of the actor. +On thread it blocks until message is available +then it returns the message (or a result of a called block). +On pool it stops executing and continues with a given block +when message becomes available.

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+210
+211
+212
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 210
+
+def receive(*rules, timeout: nil, timeout_value: nil, **options, &block)
+  @Actor.receive(*rules, timeout: timeout, timeout_value: timeout_value, **options, &block)
+end
+
+
+ +
+

+ + #reply(value) ⇒ true, false + + + + + +

+
+

Shortcut for fulfilling the reply, same as reply_resolution true, value, nil.

+ + +
+
+
+ +
+

Examples:

+ + +
actor = Concurrent::ErlangActor.spawn(:on_thread) { reply receive * 2 }
+actor.ask 2 #=> 4
+ +
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    did the sender ask, and was it resolved

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+397
+398
+399
+400
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 397
+
+def reply(value)
+  # TODO (pitr-ch 08-Feb-2019): consider adding reply? which returns true,false if success, reply method will always return value
+  reply_resolution true, value, nil
+end
+
+
+ +
+

+ + #reply_resolution(fulfilled = true, value = nil, reason = nil) ⇒ true, false + + + + + +

+
+

Reply to the sender of the message currently being processed +if the actor was asked instead of told. +The reply is stored in a Promises::ResolvableFuture +so the arguments are same as for Promises::ResolvableFuture#resolve method.

+ +

The reply may timeout, then this will fail with false.

+ + +
+
+
+ +
+

Examples:

+ + +
actor = Concurrent::ErlangActor.spawn(:on_thread) { reply_resolution true, receive * 2, nil }
+actor.ask 2 #=> 4
+ +
+

Parameters:

+
    + +
  • + + fulfilled + + + (true, false) + + + (defaults to: true) + + +
  • + +
  • + + value + + + (Object) + + + (defaults to: nil) + + +
  • + +
  • + + reason + + + (Object) + + + (defaults to: nil) + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    did the sender ask, and was it resolved before it timed out?

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+418
+419
+420
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 418
+
+def reply_resolution(fulfilled = true, value = nil, reason = nil)
+  @Actor.reply_resolution(fulfilled, value, reason)
+end
+
+
+ +
+

+ + #spawn(*args, type: @Actor.class, channel: Promises::Channel.new, environment: Environment, name: nil, executor: default_executor, link: false, monitor: false) {|*args| ... } ⇒ Pid, ::Array(Pid, Reference) + + + + + +

+
+

Creates an actor.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    arguments for the actor body

    +
    + +
  • + +
  • + + type + + + (:on_thread, :on_pool) + + + (defaults to: @Actor.class) + + + — +

    of the actor to be created.

    +
    + +
  • + +
  • + + channel + + + (Channel) + + + (defaults to: Promises::Channel.new) + + + — +

    The mailbox of the actor, by default it has unlimited capacity. +Crating the actor with a bounded queue is useful to create backpressure. +The channel can be shared with other abstractions +but actor has to be the only consumer +otherwise internal signals could be lost.

    +
    + +
  • + +
  • + + environment + + + (Environment, Module) + + + (defaults to: Environment) + + + — +

    A class which is used to run the body of the actor in. +It can either be a child of Concurrent::ErlangActor::Environment or a module. +Module is extended to a new instance of environment, +therefore if there is many actors with this module +it is better to create a class and use it instead.

    +
    + +
  • + +
  • + + name + + + (#to_s) + + + (defaults to: nil) + + + — +

    of the actor. +Available by Pid#name or #name and part of Pid#to_s.

    +
    + +
  • + +
  • + + link + + + (true, false) + + + (defaults to: false) + + + — +

    the created actor is atomically created and linked with the calling actor

    +
    + +
  • + +
  • + + monitor + + + (true, false) + + + (defaults to: false) + + + — +

    the created actor is atomically created and monitored by the calling actor

    +
    + +
  • + +
  • + + executor + + + (ExecutorService) + + + (defaults to: default_executor) + + + — +

    The executor service to use to execute the actor on. +Applies only to :on_pool actor type.

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (*args) + + + + — +

    the body of the actor. +When actor is spawned this block is evaluated +until it terminates. +The on-thread actor requires a block. +The on-poll actor has a default -> { start }, +therefore if not block is given it executes a #start method +which needs to be provided with environment.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Pid, ::Array(Pid, Reference)) + + + + — +

    a pid or a pid-reference pair when monitor is true

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 370
+
+def spawn(*args,
+          type: @Actor.class,
+          channel: Promises::Channel.new,
+          environment: Environment,
+          name: nil,
+          executor: default_executor,
+          link: false,
+          monitor: false,
+          &body)
+
+  @Actor.spawn(*args,
+               type:        type,
+               channel:     channel,
+               environment: environment,
+               name:        name,
+               executor:    executor,
+               link:        link,
+               monitor:     monitor,
+               &body)
+end
+
+
+ +
+

+ + #terminate(pid = nil, reason, value: nil) ⇒ nothing + + + + + +

+
+

If pid is not provided stops the execution of the calling actor +with the exit reason.

+ +

If pid is provided, +it sends an exit signal with exit reason to the actor identified by pid.

+ +

The following behavior apply +if reason is any object except :normal or :kill. +If pid is not trapping exits, +pid itself will exit with exit reason. +If pid is trapping exits, +the exit signal is transformed into a message Terminated +and delivered to the message queue of pid.

+ +

If reason is the Symbol :normal, pid will not exit. +If it is trapping exits, the exit signal is transformed into a message Terminated +and delivered to its message queue.

+ +

If reason is the Symbol :kill, that is if exit(pid, :kill) is called, +an untrappable exit signal is sent to pid which will unconditionally exit +with exit reason :killed.

+ +

Since evaluating this function causes the process to terminate, it has no return value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + pid + + + (Pid) + + + (defaults to: nil) + + +
  • + +
  • + + reason + + + (Object, :normal, :kill) + + + +
  • + +
  • + + value + + + (Object) + + + (defaults to: nil) + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (nothing) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+452
+453
+454
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 452
+
+def terminate(pid = nil, reason, value: nil)
+  @Actor.terminate pid, reason, value: value
+end
+
+
+ +
+

+ + #terminatedPromises::Future + + + + + +

+
+

Returns a future which is resolved with +the final result of the actor that is either the reason for +termination or a value if terminated normally.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Promises::Future) + + + + — +

    a future which is resolved with +the final result of the actor that is either the reason for +termination or a value if terminated normally.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+136
+137
+138
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 136
+
+def terminated
+  @Actor.terminated
+end
+
+
+ +
+

+ + #trap(value = true) ⇒ true, false + + + + + +

+
+

When trap is set to true, +exit signals arriving to a actor are converted to Terminated messages, +which can be received as ordinary messages. +If trap is set to false, +the actor exits +if it receives an exit signal other than normal +and the exit signal is propagated to its linked actors. +Application actors should normally not trap exits.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (true, false) + + + (defaults to: true) + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    the old value of the flag

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+168
+169
+170
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 168
+
+def trap(value = true)
+  @Actor.trap(value)
+end
+
+
+ +
+

+ + #traps?true, false + + + + + +

+
+

Returns does this actor trap exit messages?.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    does this actor trap exit messages?

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+152
+153
+154
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 152
+
+def traps?
+  @Actor.traps?
+end
+
+
+ +
+
+
+

Removes the link, if there is one, +between the calling actor and the actor referred to by pid.

+ +

Returns true and does not fail, even if there is no link to Id, or if Id does not exist.

+ +

Once unlink(pid) has returned +it is guaranteed +that the link between the caller and the actor referred to by pid +has no effect on the caller in the future (unless the link is setup again). +If caller is trapping exits, +an Terminated message due to the link might have been placed +in the caller's message queue prior to the call, though.

+ +

Note, the Terminated message can be the result of the link, +but can also be the result of calling #terminate method externally. +Therefore, it may be appropriate to cleanup the message queue +when trapping exits after the call to unlink, as follow:

+ +
receive on(And[Terminated, -> e { e.pid == pid }], true), timeout: 0
+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + +
  • + +
+ +
+ + + + +
+
+
+
+254
+255
+256
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 254
+
+def unlink(pid)
+  @Actor.unlink(pid)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants.html b/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants.html new file mode 100644 index 000000000..24698081c --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants.html @@ -0,0 +1,196 @@ + + + + + + + Module: Concurrent::ErlangActor::EnvironmentConstants + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::ErlangActor::EnvironmentConstants + + + +

+
+ + + + + + + + + +
+
Included in:
+
Concurrent::ErlangActor
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

These constants are useful +where the body of an actor is defined. +For convenience they are provided in this module for including.

+ + +
+
+
+ +
+

Examples:

+ + +
include Concurrent::ErlangActor::EnvironmentConstants
+actor = Concurrent::ErlangActor.spawn(:on_thread) do
+  receive on(Numeric) { |v| v.succ },
+          on(ANY) { terminate :bad_message },
+          on(TIMEOUT) { terminate :no_message },
+          timeout: 1
+end
+ +
+ + +

Defined Under Namespace

+

+ + + + + Classes: AbstractLogicOperationMatcher, And, Or + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
TIMEOUT = +
+
+

Unique identifier of a timeout, singleton.

+ + +
+
+
+ + +
+
+
Token.new 'TIMEOUT'
+ +
ANY = +
+
+

A singleton which matches anything using #=== method

+ + +
+
+
+ + +
+
+
Promises::Channel::ANY
+ +
+ + + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/AbstractLogicOperationMatcher.html b/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/AbstractLogicOperationMatcher.html new file mode 100644 index 000000000..c9732eec4 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/AbstractLogicOperationMatcher.html @@ -0,0 +1,299 @@ + + + + + + + Class: Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+

Direct Known Subclasses

+

And, Or

+
+ + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(*matchers) ⇒ AbstractLogicOperationMatcher + + + + + +

+
+

Returns a new instance of AbstractLogicOperationMatcher.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+591
+592
+593
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 591
+
+def initialize(*matchers)
+  @matchers = matchers
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .[](*matchers) ⇒ undocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+587
+588
+589
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 587
+
+def self.[](*matchers)
+  new(*matchers)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/And.html b/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/And.html new file mode 100644 index 000000000..9e2f6260c --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/And.html @@ -0,0 +1,250 @@ + + + + + + + Class: Concurrent::ErlangActor::EnvironmentConstants::And + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::EnvironmentConstants::And + + + +

+
+ +
+
Inherits:
+
+ AbstractLogicOperationMatcher + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

Combines matchers into one which matches if all match.

+ + +
+
+
+ +
+

Examples:

+ + +
And[Numeric, -> v { v >= 0 }] === 1  # => true
+And[Numeric, -> v { v >= 0 }] === -1 # => false
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #===(v) ⇒ true, false + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+602
+603
+604
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 602
+
+def ===(v)
+  @matchers.all? { |m| m === v }
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/Or.html b/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/Or.html new file mode 100644 index 000000000..4a797852d --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/EnvironmentConstants/Or.html @@ -0,0 +1,251 @@ + + + + + + + Class: Concurrent::ErlangActor::EnvironmentConstants::Or + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::EnvironmentConstants::Or + + + +

+
+ +
+
Inherits:
+
+ AbstractLogicOperationMatcher + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

Combines matchers into one which matches if any matches.

+ + +
+
+
+ +
+

Examples:

+ + +
Or[Symbol, String] === :v  # => true
+Or[Symbol, String] === 'v' # => true
+Or[Symbol, String] === 1   # => false
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +

This class inherits a constructor from Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #===(v) ⇒ true, false + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+614
+615
+616
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 614
+
+def ===(v)
+  @matchers.any? { |m| m === v }
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/Error.html b/docs/1.1.10/Concurrent/ErlangActor/Error.html new file mode 100644 index 000000000..b4939ba44 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/Error.html @@ -0,0 +1,144 @@ + + + + + + + Class: Concurrent::ErlangActor::Error + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::Error + + + +

+
+ +
+
Inherits:
+
+ Concurrent::Error + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

Abstract error class for ErlangActor errors.

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

NoActor, NoReply

+
+ + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/FunctionShortcuts.html b/docs/1.1.10/Concurrent/ErlangActor/FunctionShortcuts.html new file mode 100644 index 000000000..fd446dcfd --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/FunctionShortcuts.html @@ -0,0 +1,298 @@ + + + + + + + Module: Concurrent::ErlangActor::FunctionShortcuts + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::ErlangActor::FunctionShortcuts + + + +

+
+ + + + + + + + + +
+
Included in:
+
Concurrent::ErlangActor
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

Constrains shortcuts for methods in Functions.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #spawn(*args, **kwargs, &body) ⇒ Pid + + + + + +

+
+

Optionally included shortcut method for Concurrent::ErlangActor::Functions#spawn_actor

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Pid) + + + +
  • + +
+ +
+ + + + +
+
+
+
+530
+531
+532
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 530
+
+def spawn(*args, **kwargs, &body)
+  spawn_actor(*args, **kwargs, &body)
+end
+
+
+ +
+

+ + #terminate(pid, reason) ⇒ true + + + + + +

+
+

Optionally included shortcut method for Concurrent::ErlangActor::Functions#terminate_actor

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + +
  • + +
+ +
+ + + + +
+
+
+
+536
+537
+538
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 536
+
+def terminate(pid, reason)
+  terminate_actor(pid, reason)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/Functions.html b/docs/1.1.10/Concurrent/ErlangActor/Functions.html new file mode 100644 index 000000000..2b62bbc1f --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/Functions.html @@ -0,0 +1,626 @@ + + + + + + + Module: Concurrent::ErlangActor::Functions + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::ErlangActor::Functions + + + +

+
+ + + + + + + + + +
+
Included in:
+
Concurrent::ErlangActor
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

A module containing entry functions to actors like spawn_actor, terminate_actor. +It can be included in environments working with actors.

+ + +
+
+
+ +
+

Examples:

+ + +
include Concurrent::ErlangActors::Functions
+actor = spawn_actor :on_pool do
+  receive { |data| process data }
+end
+ +
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #default_actor_executorExecutorService + + + + + +

+
+

Returns the default executor service for actors.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (ExecutorService) + + + + — +

    the default executor service for actors

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+515
+516
+517
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 515
+
+def default_actor_executor
+  default_executor
+end
+
+
+ +
+

+ + #default_executorExecutorService + + + + + +

+
+

Returns the default executor service, +may be shared by other abstractions.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (ExecutorService) + + + + — +

    the default executor service, +may be shared by other abstractions

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+521
+522
+523
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 521
+
+def default_executor
+  :io
+end
+
+
+ +
+

+ + #spawn_actor(*args, type:, channel: Promises::Channel.new, environment: Environment, name: nil, executor: default_actor_executor, &body) ⇒ Pid + + + + + +

+
+

Creates an actor. Same as Environment#spawn but lacks link and monitor options.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + +
  • + +
  • + + type + + + (:on_thread, :on_pool) + + + +
  • + +
  • + + channel + + + (Channel) + + + (defaults to: Promises::Channel.new) + + +
  • + +
  • + + environment + + + (Environment, Module) + + + (defaults to: Environment) + + +
  • + +
  • + + name + + + (#to_s) + + + (defaults to: nil) + + + — +

    of the actor

    +
    + +
  • + +
  • + + executor + + + (ExecutorService) + + + (defaults to: default_actor_executor) + + + — +

    of the actor

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Pid) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 488
+
+def spawn_actor(*args,
+                type:,
+                channel: Promises::Channel.new,
+                environment: Environment,
+                name: nil,
+                executor: default_actor_executor,
+                &body)
+
+  actor = ErlangActor.create type, channel, environment, name, executor
+  actor.run(*args, &body)
+  return actor.pid
+end
+
+
+ +
+

+ + #terminate_actor(pid, reason) ⇒ true + + + + + +

+
+

Same as Environment#terminate, but it requires pid.

+ + +
+
+
+

Parameters:

+
    + +
  • + + pid + + + (Pid) + + + +
  • + +
  • + + reason + + + (Object, :normal, :kill) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true) + + + +
  • + +
+ +
+ + + + +
+
+
+
+505
+506
+507
+508
+509
+510
+511
+512
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 505
+
+def terminate_actor(pid, reason)
+  if reason == :kill
+    pid.tell Kill.new(nil)
+  else
+    pid.tell Terminate.new(nil, reason, false)
+  end
+  true
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/NoActor.html b/docs/1.1.10/Concurrent/ErlangActor/NoActor.html new file mode 100644 index 000000000..959772eb3 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/NoActor.html @@ -0,0 +1,492 @@ + + + + + + + Class: Concurrent::ErlangActor::NoActor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::NoActor + + + +

+
+ +
+
Inherits:
+
+ Error + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

An error used when actor tries to link or monitor terminated actor.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(pid = nil) ⇒ self + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + pid + + + (Pid) + + + (defaults to: nil) + + +
  • + +
+ + +
+ + + + +
+
+
+
+1503
+1504
+1505
+1506
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1503
+
+def initialize(pid = nil)
+  super(pid.to_s)
+  @pid = pid
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #pidPid (readonly) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Pid) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1499
+1500
+1501
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1499
+
+def pid
+  @pid
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #==(o) ⇒ true, false + + + + Also known as: + eql? + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1509
+1510
+1511
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1509
+
+def ==(o)
+  o.class == self.class && o.pid == self.pid
+end
+
+
+ +
+

+ + #hashInteger + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1516
+1517
+1518
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1516
+
+def hash
+  pid.hash
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/NoReply.html b/docs/1.1.10/Concurrent/ErlangActor/NoReply.html new file mode 100644 index 000000000..ec8f1e596 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/NoReply.html @@ -0,0 +1,145 @@ + + + + + + + Class: Concurrent::ErlangActor::NoReply + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::NoReply + + + +

+
+ +
+
Inherits:
+
+ Error + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

An error used when actor is asked but no reply was given or +when the actor terminates before it gives a reply.

+ + +
+
+
+ + +
+ + + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/Pid.html b/docs/1.1.10/Concurrent/ErlangActor/Pid.html new file mode 100644 index 000000000..2e898b0be --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/Pid.html @@ -0,0 +1,903 @@ + + + + + + + Class: Concurrent::ErlangActor::Pid + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::Pid + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

The public reference of the actor which can be stored and passed around. +Nothing else of the actor should be exposed. +Functions#spawn_actor and Environment#spawn return the pid.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #ask(message, timeout = nil, timeout_value = nil) ⇒ Object, timeout_value + + + + + +

+
+

The actor is asked the message and blocks until a reply is available, +which is returned by the method. +If the reply is a rejection then the methods raises it.

+ +

If the actor does not call Environment#reply or Environment#reply_resolution +the method will raise NoReply error. +If the actor is terminated it will raise NoActor. +Therefore the ask is never left unanswered and blocking.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait

    +
    + +
  • + +
  • + + timeout_value + + + (Object) + + + (defaults to: nil) + + + — +

    the value returned on timeout

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, timeout_value) + + + + — +

    reply to the message

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+73
+74
+75
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 73
+
+def ask(message, timeout = nil, timeout_value = nil)
+  @Actor.ask message, timeout, timeout_value
+end
+
+
+ +
+

+ + #ask_op(message, probe = Promises.resolvable_future) ⇒ Promises::Future(Object) + + + + + +

+
+

Same as #tell but represented as a Promises::Future.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
  • + + probe + + + (Promises::ResolvableFuture) + + + (defaults to: Promises.resolvable_future) + + + — +

    a resolvable future which is resolved with the reply.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Promises::Future(Object)) + + + + — +

    reply to the message

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+82
+83
+84
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 82
+
+def ask_op(message, probe = Promises.resolvable_future)
+  @Actor.ask_op message, probe
+end
+
+
+ +
+

+ + #name#to_s, nil + + + + + +

+
+

Returns optional name of the actor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (#to_s, nil) + + + + — +

    optional name of the actor

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+95
+96
+97
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 95
+
+def name
+  @Name
+end
+
+
+ +
+

+ + #tell(message, timeout = nil) ⇒ self, true, false + + + + + +

+
+

The actor is asynchronously told a message. +The method returns immediately unless +the actor has bounded mailbox and there is no more space for the message. +Then the method blocks current thread until there is space available. +This is useful for backpressure.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, true, false) + + + + — +

    self if timeout was nil, false on timing out and true if told in time.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+48
+49
+50
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 48
+
+def tell(message, timeout = nil)
+  @Actor.tell message, timeout
+end
+
+
+ +
+

+ + #tell_op(message) ⇒ Promises::Future(self) + + + + + +

+
+

Same as #tell but represented as a Promises::Future.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+55
+56
+57
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 55
+
+def tell_op(message)
+  @Actor.tell_op(message)
+end
+
+
+ +
+

+ + #terminatedPromises::Future + + + + + +

+
+

Returns a future which is resolved with +the final result of the actor that is either the reason for +termination or a value if terminated normally.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Promises::Future) + + + + — +

    a future which is resolved with +the final result of the actor that is either the reason for +termination or a value if terminated normally.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+90
+91
+92
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 90
+
+def terminated
+  @Actor.terminated
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    string representation

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 100
+
+def to_s
+  original = super
+  state    = case terminated.state
+             when :pending
+               'running'
+             when :fulfilled
+               "terminated normally with #{terminated.value}"
+             when :rejected
+               "terminated because of #{terminated.reason}"
+             else
+               raise
+             end
+  [original[0..-2], *@Name, state].join(' ') << '>'
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/Reference.html b/docs/1.1.10/Concurrent/ErlangActor/Reference.html new file mode 100644 index 000000000..ede459453 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/Reference.html @@ -0,0 +1,140 @@ + + + + + + + Class: Concurrent::ErlangActor::Reference + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::Reference + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

An object representing instance of a monitor, created with Environment#monitor.

+ + +
+
+
+ + +
+ + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ErlangActor/Terminated.html b/docs/1.1.10/Concurrent/ErlangActor/Terminated.html new file mode 100644 index 000000000..a34fa28b3 --- /dev/null +++ b/docs/1.1.10/Concurrent/ErlangActor/Terminated.html @@ -0,0 +1,557 @@ + + + + + + + Class: Concurrent::ErlangActor::Terminated + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ErlangActor::Terminated + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
+
+ +
+ +

Overview

+
+

A message send when actor terminates.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Instance Attribute Details

+ + + +
+

+ + #fromPid (readonly) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Pid) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1399
+1400
+1401
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1399
+
+def from
+  @from
+end
+
+
+ + + +
+

+ + #reasonObject (readonly) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1401
+1402
+1403
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1401
+
+def reason
+  @reason
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #==(o) ⇒ true, false + + + + Also known as: + eql? + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1416
+1417
+1418
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1416
+
+def ==(o)
+  o.class == self.class && o.from == @from && o.reason == self.reason
+end
+
+
+ +
+

+ + #hashInteger + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1423
+1424
+1425
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1423
+
+def hash
+  [@from, @reason].hash
+end
+
+
+ +
+

+ + #to_ary::Array(Pid, Object) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (::Array(Pid, Object)) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1411
+1412
+1413
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1411
+
+def to_ary
+  [@from, @reason]
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Event.html b/docs/1.1.10/Concurrent/Event.html new file mode 100644 index 000000000..3530d98be --- /dev/null +++ b/docs/1.1.10/Concurrent/Event.html @@ -0,0 +1,697 @@ + + + + + + + Class: Concurrent::Event + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Event + + + +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/event.rb
+
+ +
+ +

Overview

+
+

Old school kernel-style event reminiscent of Win32 programming in C++.

+ +

When an Event is created it is in the unset state. Threads can choose to +#wait on the event, blocking until released by another thread. When one +thread wants to alert all blocking threads it calls the #set method which +will then wake up all listeners. Once an Event has been set it remains set. +New threads calling #wait will return immediately. An Event may be +#reset at any time once it has been set.

+ + +
+
+
+ +
+

Examples:

+ + +
event = Concurrent::Event.new
+
+t1 = Thread.new do
+  puts "t1 is waiting"
+  event.wait(1)
+  puts "event occurred"
+end
+
+t2 = Thread.new do
+  puts "t2 calling set"
+  event.set
+end
+
+[t1, t2].each(&:join)
+
+# prints:
+# t1 is waiting
+# t2 calling set
+# event occurred
+ +
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initializeEvent + + + + + +

+
+

Creates a new Event in the unset state. Threads calling #wait on the +Event will block.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+40
+41
+42
+43
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/event.rb', line 40
+
+def initialize
+  super
+  synchronize { ns_initialize }
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #resetBoolean + + + + + +

+
+

Reset a previously set event back to the unset state. +Has no effect if the Event has not yet been set.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    should always return true

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+68
+69
+70
+71
+72
+73
+74
+75
+76
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/event.rb', line 68
+
+def reset
+  synchronize do
+    if @set
+      @set       = false
+      @iteration +=1
+    end
+    true
+  end
+end
+
+
+ +
+

+ + #setBoolean + + + + + +

+
+

Trigger the event, setting the state to set and releasing all threads +waiting on the event. Has no effect if the Event has already been set.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    should always return true

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/event.rb', line 56
+
+def set
+  synchronize { ns_set }
+end
+
+
+ +
+

+ + #set?Boolean + + + + + +

+
+

Is the object in the set state?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    indicating whether or not the Event has been set

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+48
+49
+50
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/event.rb', line 48
+
+def set?
+  synchronize { @set }
+end
+
+
+ +
+

+ + #try?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+60
+61
+62
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/event.rb', line 60
+
+def try?
+  synchronize { @set ? false : ns_set }
+end
+
+
+ +
+

+ + #wait(timeout = nil) ⇒ Boolean + + + + + +

+
+

Wait a given number of seconds for the Event to be set by another +thread. Will wait forever when no timeout value is given. Returns +immediately if the Event has already been set.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the Event was set before timeout else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/event.rb', line 83
+
+def wait(timeout = nil)
+  synchronize do
+    unless @set
+      iteration = @iteration
+      ns_wait_until(timeout) { iteration < @iteration || @set }
+    else
+      true
+    end
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Exchanger.html b/docs/1.1.10/Concurrent/Exchanger.html new file mode 100644 index 000000000..e16c57345 --- /dev/null +++ b/docs/1.1.10/Concurrent/Exchanger.html @@ -0,0 +1,204 @@ + + + + + + + Class: Concurrent::Exchanger + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Exchanger + + + +

+
+ +
+
Inherits:
+
+ ExchangerImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/exchanger.rb
+
+ +
+ +

Overview

+
+

A synchronization point at which threads can pair and swap elements within +pairs. Each thread presents some object on entry to the exchange method, +matches with a partner thread, and receives its partner's object on return.

+ +

Thread-safe Variable Classes

+ +

Each of the thread-safe variable classes is designed to solve a different +problem. In general:

+ +
    +
  • Agent: Shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately.
  • +
  • Atom: Shared, mutable variable providing independent, +uncoordinated, synchronous change of individual values. Best used when +the value will undergo frequent reads but only occasional, though complex, +updates. Suitable when the result of an update must be known immediately.
  • +
  • AtomicReference: A simple object reference that can be updated +atomically. Updates are synchronous but fast. Best used when updates a +simple set operations. Not suitable when updates are complex. +AtomicBoolean and AtomicFixnum are similar +but optimized for the given data type.
  • +
  • Exchanger: Shared, stateless synchronization point. Used +when two or more threads need to exchange data. The threads will pair then +block on each other until the exchange is complete.
  • +
  • MVar: Shared synchronization point. Used when one thread +must give a value to another, which must take the value. The threads will +block on each other until the exchange is complete.
  • +
  • ThreadLocalVar: Shared, mutable, isolated variable which +holds a different value for each thread which has access. Often used as +an instance variable in objects which must maintain different state +for different threads.
  • +
  • TVar: Shared, mutable variables which provide +coordinated, synchronous, change of many stated. Used when multiple +value must change together, in an all-or-nothing transaction. +This implementation is very simple, using only a single slot for each +exchanger (unlike more advanced implementations which use an "arena"). +This approach will work perfectly fine when there are only a few threads +accessing a single Exchanger. Beyond a handful of threads the performance +will degrade rapidly due to contention on the single slot, but the algorithm +will remain correct.
  • +
+ + +
+
+
+ +
+

Examples:

+ + +

+exchanger = Concurrent::Exchanger.new
+
+threads = [
+  Thread.new { puts "first: " << exchanger.exchange('foo', 1) }, #=> "first: bar"
+  Thread.new { puts "second: " << exchanger.exchange('bar', 1) } #=> "second: foo"
+]
+threads.each {|t| t.join(2) }
+ +
+ + +

See Also:

+ + +
+ + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/FixedThreadPool.html b/docs/1.1.10/Concurrent/FixedThreadPool.html new file mode 100644 index 000000000..32812a7a5 --- /dev/null +++ b/docs/1.1.10/Concurrent/FixedThreadPool.html @@ -0,0 +1,409 @@ + + + + + + + Class: Concurrent::FixedThreadPool + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::FixedThreadPool + + + +

+
+ +
+
Inherits:
+
+ ThreadPoolExecutor + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Failure to properly shutdown a thread pool can lead to unpredictable results. +Please read Shutting Down Thread Pools for more information.

+
+
+ +

A thread pool that reuses a fixed number of threads operating off an unbounded queue. +At any point, at most num_threads will be active processing tasks. When all threads are busy new +tasks #post to the thread pool are enqueued until a thread becomes available. +Should a thread crash for any reason the thread will immediately be removed +from the pool and replaced.

+ +

The API and behavior of this class are based on Java's FixedThreadPool

+ +

Thread Pool Options

+ +

Thread pools support several configuration options:

+ +
    +
  • idletime: The number of seconds that a thread may be idle before being reclaimed.
  • +
  • name: The name of the executor (optional). Printed in the executor's #to_s output and +a <name>-worker-<id> name is given to its threads if supported by used Ruby +implementation. <id> is uniq for each thread.
  • +
  • max_queue: The maximum number of tasks that may be waiting in the work queue at +any one time. When the queue size reaches max_queue and no new threads can be created, +subsequent tasks will be rejected in accordance with the configured fallback_policy.
  • +
  • auto_terminate: When true (default), the threads started will be marked as daemon.
  • +
  • fallback_policy: The policy defining how rejected tasks are handled.
  • +
+ +

Three fallback policies are supported:

+ +
    +
  • :abort: Raise a RejectedExecutionError exception and discard the task.
  • +
  • :discard: Discard the task and return false.
  • +
  • :caller_runs: Execute the task on the calling thread.
  • +
+ +

Shutting Down Thread Pools

+ +

Killing a thread pool while tasks are still being processed, either by calling +the #kill method or at application exit, will have unpredictable results. There +is no way for the thread pool to know what resources are being used by the +in-progress tasks. When those tasks are killed the impact on those resources +cannot be predicted. The best practice is to explicitly shutdown all thread +pools using the provided methods:

+ +
    +
  • Call #shutdown to initiate an orderly termination of all in-progress tasks
  • +
  • Call #wait_for_termination with an appropriate timeout interval an allow +the orderly shutdown to complete
  • +
  • Call #kill only when the thread pool fails to shutdown in the allotted time
  • +
+ +

On some runtime platforms (most notably the JVM) the application will not +exit until all thread pools have been shutdown. To prevent applications from +"hanging" on exit, all threads can be marked as daemon according to the +:auto_terminate option.

+ +
pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon
+pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon
+
+ + +
+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(num_threads, opts = {}) ⇒ FixedThreadPool + + + + + +

+
+

Create a new thread pool.

+ + +
+
+
+

Parameters:

+
    + +
  • + + num_threads + + + (Integer) + + + + — +

    the number of threads to allocate

    +
    + +
  • + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options defining pool behavior.

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :fallback_policy + (Symbol) + + + — default: + `:abort` + + + + —

    the fallback policy

    +
    + +
  • + +
+ + +

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if num_threads is less than or equal to zero

    +
    + +
  • + +
  • + + + (ArgumentError) + + + + — +

    if fallback_policy is not a known policy

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+211
+212
+213
+214
+215
+216
+217
+218
+
+
# File 'lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb', line 211
+
+def initialize(num_threads, opts = {})
+  raise ArgumentError.new('number of threads must be greater than zero') if num_threads.to_i < 1
+  defaults  = { max_queue:   DEFAULT_MAX_QUEUE_SIZE,
+                idletime:    DEFAULT_THREAD_IDLETIMEOUT }
+  overrides = { min_threads: num_threads,
+                max_threads: num_threads }
+  super(defaults.merge(opts).merge(overrides))
+end
+
+
+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Future.html b/docs/1.1.10/Concurrent/Future.html new file mode 100644 index 000000000..7ca71eb29 --- /dev/null +++ b/docs/1.1.10/Concurrent/Future.html @@ -0,0 +1,1339 @@ + + + + + + + Class: Concurrent::Future + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Future + + + +

+
+ +
+
Inherits:
+
+ IVar + +
    +
  • Object
  • + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/future.rb
+
+ +
+ +

Overview

+
+

Future is inspired by Clojure's future function. A future represents a promise to complete an action at some time in the future. The action is atomic and permanent. The idea behind a future is to send an operation for asynchronous completion, do other stuff, then return and retrieve the result of the async operation at a later time. Futures run on the global thread pool.

+ +
Feature:
+  As a highly responsive Ruby application
+  I want long-running tasks on a separate thread
+  So I can perform other tasks without waiting
+
+ +

Futures have several possible states: :unscheduled, :pending, :processing, :rejected, or :fulfilled. These are also aggregated as #incomplete? and #complete?. When a Future is created it is set to :unscheduled. Once the #execute method is called the state becomes :pending. Once a job is pulled from the thread pool's queue and is given to a thread for processing (often immediately upon #post) the state becomes :processing. The future will remain in this state until processing is complete. A future that is in the :unscheduled, :pending, or :processing is considered #incomplete?. A #complete? Future is either :rejected, indicating that an exception was thrown during processing, or :fulfilled, indicating success. If a Future is :fulfilled its #value will be updated to reflect the result of the operation. If :rejected the reason will be updated with a reference to the thrown exception. The predicate methods #unscheduled?, #pending?, #rejected?, and #fulfilled? can be called at any time to obtain the state of the Future, as can the #state method, which returns a symbol.

+ +

Retrieving the value of a Future is done through the #value (alias: #deref) method. Obtaining the value of a Future is a potentially blocking operation. When a Future is :rejected a call to #value will return nil immediately. When a Future is :fulfilled a call to #value will immediately return the current value. When a Future is :pending a call to #value will block until the Future is either :rejected or :fulfilled. A timeout value can be passed to #value to limit how long the call will block. If nil the call will block indefinitely. If 0 the call will not block. Any other integer or float value will indicate the maximum number of seconds to block.

+ +

The constructor can also be given zero or more processing options. Currently the only supported options are those recognized by the Dereferenceable module.

+ +

The Future class also includes the behavior of the Ruby standard library Observable module, but does so in a thread-safe way. On fulfillment or rejection all observers will be notified according to the normal Observable behavior. The observer callback function will be called with three parameters: the Time of fulfillment/rejection, the final value, and the final reason. Observers added after fulfillment/rejection will still be notified as normal. The notification will occur on the same thread that processed the job.

+ +

Examples

+ +

A fulfilled example:

+ +
require 'concurrent'
+require 'csv'
+require 'open-uri'
+
+class Ticker
+  def get_year_end_closing(symbol, year, api_key)
+    uri = "https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=#{symbol}&apikey=#{api_key}&datatype=csv"
+    data = []
+    csv = URI.parse(uri).read
+    if csv.include?('call frequency')
+      return :rate_limit_exceeded
+    end
+    CSV.parse(csv, headers: true) do |row|
+      data << row['close'].to_f if row['timestamp'].include?(year.to_s)
+    end
+    year_end = data.first
+    year_end
+  rescue => e
+    p e
+  end
+end
+
+api_key = ENV['ALPHAVANTAGE_KEY']
+abort(error_message) unless api_key
+
+# Future
+price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013, api_key) }
+p price.state #=> :pending
+p price.pending? #=> true
+p price.value(0) #=> nil (does not block)
+
+sleep(1)    # do other stuff
+
+p price.value #=> 63.65 (after blocking if necessary)
+p price.state #=> :fulfilled
+p price.fulfilled? #=> true
+p price.value #=> 63.65
+
+ +

A rejected example:

+ +
count = Concurrent::Future.execute{ sleep(10); raise StandardError.new("Boom!") }
+count.state #=> :pending
+count.pending? #=> true
+
+count.value #=> nil (after blocking)
+count.rejected? #=> true
+count.reason #=> #
+
+ +

An example with observation:

+ +
class Ticker
+  Stock = Struct.new(:symbol, :name, :exchange)
+
+  def update(time, value, reason)
+    ticker = value.collect do |symbol|
+      Stock.new(symbol['symbol'], symbol['name'], symbol['exch'])
+    end
+
+    output = ticker.join("\n")
+    print "#{output}\n"
+  end
+end
+
+yahoo = Ticker.new('YAHOO')
+future = Concurrent::Future.new { yahoo.update.suggested_symbols }
+future.add_observer(Ticker.new)
+future.execute
+
+# do important stuff...
+
+#>> #
+#>> #
+#>> #
+#>> #
+#>> #
+#>> #
+#>> #
+#>> #
+#>> #
+#>> #
+
+

+ +

Copy Options

+ +

Object references in Ruby are mutable. This can lead to serious +problems when the Concern::Obligation#value of an object is a mutable reference. Which +is always the case unless the value is a Fixnum, Symbol, or similar +"primitive" data type. Each instance can be configured with a few +options that can help protect the program from potentially dangerous +operations. Each of these options can be optionally set when the object +instance is created:

+ +
    +
  • :dup_on_deref When true the object will call the #dup method on +the value object every time the #value method is called +(default: false)
  • +
  • :freeze_on_deref When true the object will call the #freeze +method on the value object every time the #value method is called +(default: false)
  • +
  • :copy_on_deref When given a Proc object the Proc will be run +every time the #value method is called. The Proc will be given +the current value as its only argument and the result returned by +the block will be the return value of the #value call. When nil +this option will be ignored (default: nil)
  • +
+ +

When multiple deref options are set the order of operations is strictly defined. +The order of deref operations is:

+ +
    +
  • :copy_on_deref
  • +
  • :dup_on_deref
  • +
  • :freeze_on_deref
  • +
+ +

Because of this ordering there is no need to #freeze an object created by a +provided :copy_on_deref block. Simply set :freeze_on_deref to true. +Setting both :dup_on_deref to true and :freeze_on_deref to true is +as close to the behavior of a "pure" functional language (like Erlang, Clojure, +or Haskell) as we are likely to get in Ruby.

+ + +
+
+ + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(opts = {}) { ... } ⇒ Future + + + + + +

+
+

Create a new Future in the :unscheduled state.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Obligation#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
  • + :args + (object, Array) + + + + + —

    zero or more arguments to be passed the task +block on execution

    +
    + +
  • + +
+ + +

Yields:

+
    + +
  • + + + + + + + +

    the asynchronous operation to perform

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+33
+34
+35
+36
+
+
# File 'lib/concurrent-ruby/concurrent/future.rb', line 33
+
+def initialize(opts = {}, &block)
+  raise ArgumentError.new('no block given') unless block_given?
+  super(NULL, opts.merge(__task_from_block__: block), &nil)
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .execute(opts = {}) { ... } ⇒ Future + + + + + +

+
+

Create a new Future object with the given block, execute it, and return the +:pending object.

+ + +
+
+
+ +
+

Examples:

+ + +
future = Concurrent::Future.execute{ sleep(1); 42 }
+future.state #=> :pending
+ +
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Obligation#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
  • + :args + (object, Array) + + + + + —

    zero or more arguments to be passed the task +block on execution

    +
    + +
  • + +
+ + +

Yields:

+
    + +
  • + + + + + + + +

    the asynchronous operation to perform

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Future) + + + + — +

    the newly created Future in the :pending state

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+77
+78
+79
+
+
# File 'lib/concurrent-ruby/concurrent/future.rb', line 77
+
+def self.execute(opts = {}, &block)
+  Future.new(opts, &block).execute
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #cancelBoolean + + + + + +

+
+

Attempt to cancel the operation if it has not already processed. +The operation can only be cancelled while still pending. It cannot +be cancelled once it has begun processing or has completed.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    was the operation successfully cancelled.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+99
+100
+101
+102
+103
+104
+105
+106
+
+
# File 'lib/concurrent-ruby/concurrent/future.rb', line 99
+
+def cancel
+  if compare_and_set_state(:cancelled, :pending)
+    complete(false, nil, CancelledOperationError.new)
+    true
+  else
+    false
+  end
+end
+
+
+ +
+

+ + #cancelled?Boolean + + + + + +

+
+

Has the operation been successfully cancelled?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+111
+112
+113
+
+
# File 'lib/concurrent-ruby/concurrent/future.rb', line 111
+
+def cancelled?
+  state == :cancelled
+end
+
+
+ +
+

+ + #executeFuture + + + + + +

+
+

Execute an :unscheduled Future. Immediately sets the state to :pending and +passes the block to a new thread/thread pool for eventual execution. +Does nothing if the Future is in any state other than :unscheduled.

+ + +
+
+
+ +
+

Examples:

+ + +

Instance and execute in separate steps

+

+ +
future = Concurrent::Future.new{ sleep(1); 42 }
+future.state #=> :unscheduled
+future.execute
+future.state #=> :pending
+ + +

Instance and execute in one line

+

+ +
future = Concurrent::Future.new{ sleep(1); 42 }.execute
+future.state #=> :pending
+ +
+ +

Returns:

+
    + +
  • + + + (Future) + + + + — +

    a reference to self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+53
+54
+55
+56
+57
+58
+
+
# File 'lib/concurrent-ruby/concurrent/future.rb', line 53
+
+def execute
+  if compare_and_set_state(:pending, :unscheduled)
+    @executor.post{ safe_execute(@task, @args) }
+    self
+  end
+end
+
+
+ +
+

+ + #set(value = NULL) { ... } ⇒ IVar + + + + + +

+
+

Set the IVar to a value and wake or notify all threads waiting on it.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + (defaults to: NULL) + + + — +

    the value to store in the IVar

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    A block operation to use for setting the value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (IVar) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if both a value and a block are given

    +
    + +
  • + +
  • + + + (Concurrent::MultipleAssignmentError) + + + + — +

    if the IVar has already +been set or otherwise completed

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+
+
# File 'lib/concurrent-ruby/concurrent/future.rb', line 82
+
+def set(value = NULL, &block)
+  check_for_block_or_value!(block_given?, value)
+  synchronize do
+    if @state != :unscheduled
+      raise MultipleAssignmentError
+    else
+      @task = block || Proc.new { value }
+    end
+  end
+  execute
+end
+
+
+ +
+

+ + #wait_or_cancel(timeout) ⇒ Boolean + + + + + +

+
+

Wait the given number of seconds for the operation to complete. +On timeout attempt to cancel the operation.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the operation completed before the timeout +else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+121
+122
+123
+124
+125
+126
+127
+128
+129
+
+
# File 'lib/concurrent-ruby/concurrent/future.rb', line 121
+
+def wait_or_cancel(timeout)
+  wait(timeout)
+  if complete?
+    true
+  else
+    cancel
+    false
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Hash.html b/docs/1.1.10/Concurrent/Hash.html new file mode 100644 index 000000000..f4e5f0c8a --- /dev/null +++ b/docs/1.1.10/Concurrent/Hash.html @@ -0,0 +1,150 @@ + + + + + + + Class: Concurrent::Hash + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Hash + + + +

+
+ +
+
Inherits:
+
+ HashImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/hash.rb
+
+ +
+ +

Overview

+
+

A thread-safe subclass of Hash. This version locks against the object +itself for every method call, ensuring only one thread can be reading +or writing at a time. This includes iteration methods like #each, +which takes the lock repeatedly when reading an item.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/IVar.html b/docs/1.1.10/Concurrent/IVar.html new file mode 100644 index 000000000..3b8248bb2 --- /dev/null +++ b/docs/1.1.10/Concurrent/IVar.html @@ -0,0 +1,2378 @@ + + + + + + + Class: Concurrent::IVar + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::IVar + + + +

+
+ +
+
Inherits:
+
+ Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Concern::Obligation, Concern::Observable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/ivar.rb
+
+ +
+ +

Overview

+
+

An IVar is like a future that you can assign. As a future is a value that +is being computed that you can wait on, an IVar is a value that is waiting +to be assigned, that you can wait on. IVars are single assignment and +deterministic.

+ +

Then, express futures as an asynchronous computation that assigns an IVar. +The IVar becomes the primitive on which futures and +dataflow are built.

+ +

An IVar is a single-element container that is normally created empty, and +can only be set once. The I in IVar stands for immutable. Reading an +IVar normally blocks until it is set. It is safe to set and read an IVar +from different threads.

+ +

If you want to have some parallel task set the value in an IVar, you want +a Future. If you want to create a graph of parallel tasks all executed +when the values they depend on are ready you want dataflow. IVar is +generally a low-level primitive.

+ +

Examples

+ +

Create, set and get an IVar

+ +
ivar = Concurrent::IVar.new
+ivar.set 14
+ivar.value #=> 14
+ivar.set 2 # would now be an error
+
+ +

See Also

+ +
    +
  1. For the theory: Arvind, R. Nikhil, and K. Pingali. +I-Structures: Data structures for parallel computing. +In Proceedings of Workshop on Graph Reduction, 1986.
  2. +
  3. For recent application: +DataDrivenFuture in Habanero Java from Rice.
  4. +
+ + +
+
+
+ + +
+

Direct Known Subclasses

+

Future, Promise, ScheduledTask

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(value = NULL, opts = {}, &block) ⇒ IVar + + + + + +

+
+

Create a new IVar in the :pending state with the (optional) initial value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + (defaults to: NULL) + + + — +

    the initial value

    +
    + +
  • + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options to create a message with

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :dup_on_deref + (String) + + + — default: + false + + + + —

    call #dup before returning +the data

    +
    + +
  • + +
  • + :freeze_on_deref + (String) + + + — default: + false + + + + —

    call #freeze before +returning the data

    +
    + +
  • + +
  • + :copy_on_deref + (String) + + + — default: + nil + + + + —

    call the given Proc passing +the internal value and returning the value returned from the proc

    +
    + +
  • + +
+ + + + + +
+ + + + +
+
+
+
+61
+62
+63
+64
+65
+66
+67
+
+
# File 'lib/concurrent-ruby/concurrent/ivar.rb', line 61
+
+def initialize(value = NULL, opts = {}, &block)
+  if value != NULL && block_given?
+    raise ArgumentError.new('provide only a value or a block')
+  end
+  super(&nil)
+  synchronize { ns_initialize(value, opts, &block) }
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #add_observer(observer = nil, func = :update, &block) ⇒ undocumented + + + + + +

+
+

Add an observer on this object that will receive notification on update.

+ +

Upon completion the IVar will notify all observers in a thread-safe way. +The func method of the observer will be called with three arguments: the +Time at which the Future completed the asynchronous operation, the +final value (or nil on rejection), and the final reason (or nil on +fulfillment).

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the object that will be notified of changes

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    symbol naming the method to call when this +Observable has changes`

    +
    + +
  • + +
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+
+
# File 'lib/concurrent-ruby/concurrent/ivar.rb', line 80
+
+def add_observer(observer = nil, func = :update, &block)
+  raise ArgumentError.new('cannot provide both an observer and a block') if observer && block
+  direct_notification = false
+
+  if block
+    observer = block
+    func = :call
+  end
+
+  synchronize do
+    if event.set?
+      direct_notification = true
+    else
+      observers.add_observer(observer, func)
+    end
+  end
+
+  observer.send(func, Time.now, self.value, reason) if direct_notification
+  observer
+end
+
+
+ +
+

+ + #fail(reason = StandardError.new) ⇒ IVar + + + + + +

+
+

Set the IVar to failed due to some error and wake or notify all threads waiting on it.

+ + +
+
+
+

Parameters:

+
    + +
  • + + reason + + + (Object) + + + (defaults to: StandardError.new) + + + — +

    for the failure

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (IVar) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+134
+135
+136
+
+
# File 'lib/concurrent-ruby/concurrent/ivar.rb', line 134
+
+def fail(reason = StandardError.new)
+  complete(false, nil, reason)
+end
+
+
+ +
+

+ + #set(value = NULL) { ... } ⇒ IVar + + + + + +

+
+

Set the IVar to a value and wake or notify all threads waiting on it.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + (defaults to: NULL) + + + — +

    the value to store in the IVar

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    A block operation to use for setting the value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (IVar) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if both a value and a block are given

    +
    + +
  • + +
  • + + + (Concurrent::MultipleAssignmentError) + + + + — +

    if the IVar has already +been set or otherwise completed

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+
+
# File 'lib/concurrent-ruby/concurrent/ivar.rb', line 112
+
+def set(value = NULL)
+  check_for_block_or_value!(block_given?, value)
+  raise MultipleAssignmentError unless compare_and_set_state(:processing, :pending)
+
+  begin
+    value = yield if block_given?
+    complete_without_notification(true, value, nil)
+  rescue => ex
+    complete_without_notification(false, nil, ex)
+  end
+
+  notify_observers(self.value, reason)
+  self
+end
+
+
+ +
+

+ + #try_set(value = NULL) { ... } ⇒ Boolean + + + + + +

+
+

Attempt to set the IVar with the given value or block. Return a +boolean indicating the success or failure of the set operation.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + (defaults to: NULL) + + + — +

    the value to store in the IVar

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    A block operation to use for setting the value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the value was set else false

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if both a value and a block are given

    +
    + +
  • + +
  • + + + (Concurrent::MultipleAssignmentError) + + + + — +

    if the IVar has already +been set or otherwise completed

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+144
+145
+146
+147
+148
+149
+
+
# File 'lib/concurrent-ruby/concurrent/ivar.rb', line 144
+
+def try_set(value = NULL, &block)
+  set(value, &block)
+  true
+rescue MultipleAssignmentError
+  false
+end
+
+
+ +
+

+ + #complete?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Has the obligation completed processing?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #count_observersInteger + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Return the number of observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the observers count

    +
    + +
  • + +
+ +
+
+ +
+

+ + #delete_observer(observer) ⇒ Object + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Remove observer as an observer on this object so that it will no +longer receive notifications.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + + — +

    the observer to remove

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the deleted observer

    +
    + +
  • + +
+ +
+
+ +
+

+ + #delete_observersObservable + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Remove all observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+

+ + #exception(*args) ⇒ undocumented + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+ + +
+
+
+ +
+

Examples:

+ + +

allows Obligation to be risen

+

+ +
rejected_ivar = Ivar.new.fail
+raise rejected_ivar
+ +
+ + +
+
+ +
+

+ + #fulfilled?Boolean + + + + Also known as: + realized? + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Has the obligation been fulfilled?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #incomplete?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Is the obligation still awaiting completion of processing?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #pending?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Is obligation completion still pending?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #reasonException + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

If an exception was raised during processing this will return the +exception object. Will return nil when the state is pending or if +the obligation has been successfully fulfilled.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Exception) + + + + — +

    the exception raised during processing or nil

    +
    + +
  • + +
+ +
+
+ +
+

+ + #rejected?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Has the obligation been rejected?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #stateSymbol + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

The current state of the obligation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Symbol) + + + + — +

    the current state

    +
    + +
  • + +
+ +
+
+ +
+

+ + #unscheduled?Boolean + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Is the obligation still unscheduled?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+
+ +
+

+ + #value(timeout = nil) ⇒ Object + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

The current value of the obligation. Will be nil while the state is +pending or the operation has been rejected.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    see Dereferenceable#deref

    +
    + +
  • + +
+ +
+
+ +
+

+ + #value!(timeout = nil) ⇒ Object + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

The current value of the obligation. Will be nil while the state is +pending or the operation has been rejected. Will re-raise any exceptions +raised during processing (but will not raise an exception on timeout).

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    see Dereferenceable#deref

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    raises the reason when rejected

    +
    + +
  • + +
+ +
+
+ +
+

+ + #wait(timeout = nil) ⇒ Obligation + + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Wait until obligation is complete or the timeout has been reached.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Obligation) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+

+ + #wait!(timeout = nil) ⇒ Obligation + + + + Also known as: + no_error! + + + + + + Originally defined in module + Concern::Obligation + + +

+
+

Wait until obligation is complete or the timeout is reached. Will re-raise +any exceptions raised during processing (but will not raise an exception +on timeout).

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in seconds to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Obligation) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    raises the reason when rejected

    +
    + +
  • + +
+ +
+
+ +
+

+ + #with_observer(observer = nil, func = :update, &block) ⇒ Observable + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

As #add_observer but can be used for chaining.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ImmediateExecutor.html b/docs/1.1.10/Concurrent/ImmediateExecutor.html new file mode 100644 index 000000000..4391ffdcc --- /dev/null +++ b/docs/1.1.10/Concurrent/ImmediateExecutor.html @@ -0,0 +1,925 @@ + + + + + + + Class: Concurrent::ImmediateExecutor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ImmediateExecutor + + + +

+
+ +
+
Inherits:
+
+ AbstractExecutorService + +
    +
  • Object
  • + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/immediate_executor.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Intended for use primarily in testing and debugging.

+
+
+ +

An executor service which runs all operations on the current thread, +blocking as necessary. Operations are performed in the order they are +received and no two operations can be performed simultaneously.

+ +

This executor service exists mainly for testing an debugging. When used +it immediately runs every #post operation on the current thread, blocking +that thread until the operation is complete. This can be very beneficial +during testing because it makes all operations deterministic.

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

IndirectImmediateExecutor

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initializeImmediateExecutor + + + + + +

+
+

Creates a new executor

+ + +
+
+
+ + +
+ + + + +
+
+
+
+21
+22
+23
+
+
# File 'lib/concurrent-ruby/concurrent/executor/immediate_executor.rb', line 21
+
+def initialize
+  @stopped = Concurrent::Event.new
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #<<(task) ⇒ self + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + task + + + (Proc) + + + + — +

    the asynchronous task to perform

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + + — +

    returns itself

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+34
+35
+36
+37
+
+
# File 'lib/concurrent-ruby/concurrent/executor/immediate_executor.rb', line 34
+
+def <<(task)
+  post(&task)
+  self
+end
+
+
+ +
+

+ + #post(*args) { ... } ⇒ Boolean + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + 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

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+26
+27
+28
+29
+30
+31
+
+
# File 'lib/concurrent-ruby/concurrent/executor/immediate_executor.rb', line 26
+
+def post(*args, &task)
+  raise ArgumentError.new('no block given') unless block_given?
+  return false unless running?
+  task.call(*args)
+  true
+end
+
+
+ +
+

+ + #running?Boolean + + + + + +

+
+

Is the executor running?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when running, false when shutting down or shutdown

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+40
+41
+42
+
+
# File 'lib/concurrent-ruby/concurrent/executor/immediate_executor.rb', line 40
+
+def running?
+  ! shutdown?
+end
+
+
+ +
+

+ + #shutdownundocumented + + + + Also known as: + kill + + + + +

+
+

Begin an orderly shutdown. Tasks already in the queue will be executed, +but no new tasks will be accepted. Has no additional effect if the +thread pool is not running.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+55
+56
+57
+58
+
+
# File 'lib/concurrent-ruby/concurrent/executor/immediate_executor.rb', line 55
+
+def shutdown
+  @stopped.set
+  true
+end
+
+
+ +
+

+ + #shutdown?Boolean + + + + + +

+
+

Is the executor shutdown?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when shutdown, false when shutting down or running

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+50
+51
+52
+
+
# File 'lib/concurrent-ruby/concurrent/executor/immediate_executor.rb', line 50
+
+def shutdown?
+  @stopped.set?
+end
+
+
+ +
+

+ + #shuttingdown?Boolean + + + + + +

+
+

Is the executor shuttingdown?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when not running and not shutdown, else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+45
+46
+47
+
+
# File 'lib/concurrent-ruby/concurrent/executor/immediate_executor.rb', line 45
+
+def shuttingdown?
+  false
+end
+
+
+ +
+

+ + #wait_for_termination(timeout = nil) ⇒ Boolean + + + + + +

+
+ +
+ Note: +

Does not initiate shutdown or termination. Either shutdown or kill +must be called before this method (or on another thread).

+
+
+ +

Block until executor shutdown is complete or until timeout seconds have +passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Integer) + + + (defaults to: nil) + + + — +

    the maximum number of seconds to wait for shutdown to complete

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if shutdown complete or false on timeout

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+62
+63
+64
+
+
# File 'lib/concurrent-ruby/concurrent/executor/immediate_executor.rb', line 62
+
+def wait_for_termination(timeout = nil)
+  @stopped.wait(timeout)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ImmutableStruct.html b/docs/1.1.10/Concurrent/ImmutableStruct.html new file mode 100644 index 000000000..060b2aefd --- /dev/null +++ b/docs/1.1.10/Concurrent/ImmutableStruct.html @@ -0,0 +1,1222 @@ + + + + + + + Module: Concurrent::ImmutableStruct + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::ImmutableStruct + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/immutable_struct.rb
+
+ +
+ +

Overview

+
+

A thread-safe, immutable variation of Ruby's standard Struct.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #==(other) ⇒ Boolean + + + + + +

+
+

Equality

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if other has the same struct subclass and has +equal member values (according to Object#==)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+51
+52
+53
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 51
+
+def ==(other)
+  ns_equality(other)
+end
+
+
+ +
+

+ + #[](member) ⇒ Object + + + + + +

+
+

Attribute Reference

+ + +
+
+
+

Parameters:

+
    + +
  • + + member + + + (Symbol, String, Integer) + + + + — +

    the string or symbol name of the member +for which to obtain the value or the member's index

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value of the given struct member or the member at the given index.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NameError) + + + + — +

    if the member does not exist

    +
    + +
  • + +
  • + + + (IndexError) + + + + — +

    if the index is out of range.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+46
+47
+48
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 46
+
+def [](member)
+  ns_get(member)
+end
+
+
+ +
+

+ + #each {|value| ... } ⇒ undocumented + + + + + +

+
+

Yields the value of each struct member in order. If no block is given +an enumerator is returned.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 56
+
+def each(&block)
+  return enum_for(:each) unless block_given?
+  ns_each(&block)
+end
+
+
+ +
+

+ + #each_pair {|member, value| ... } ⇒ undocumented + + + + + +

+
+

Yields the name and value of each struct member in order. If no block is +given an enumerator is returned.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member/value pair

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + member + + + (Object) + + + + — +

    each struct member (in order)

    +
    + +
  • + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+62
+63
+64
+65
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 62
+
+def each_pair(&block)
+  return enum_for(:each_pair) unless block_given?
+  ns_each_pair(&block)
+end
+
+
+ +
+

+ + #inspectString + + + + Also known as: + to_s + + + + +

+
+

Describe the contents of this struct in a string.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    the contents of this struct in a string

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+29
+30
+31
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 29
+
+def inspect
+  ns_inspect
+end
+
+
+ +
+

+ + #merge(other) {|member, selfvalue, othervalue| ... } ⇒ Synchronization::AbstractStruct + + + + + +

+
+

Returns a new struct containing the contents of other and the contents +of self. If no block is specified, the value for entries with duplicate +keys will be that of other. Otherwise the value for each duplicate key +is determined by calling the block with the key, its value in self and +its value in other.

+ + +
+
+
+

Parameters:

+
    + +
  • + + other + + + (Hash) + + + + — +

    the hash from which to set the new values

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    an options block for resolving duplicate keys

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + member + + + (String, Symbol) + + + + — +

    the name of the member which is duplicated

    +
    + +
  • + +
  • + + selfvalue + + + (Object) + + + + — +

    the value of the member in self

    +
    + +
  • + +
  • + + othervalue + + + (Object) + + + + — +

    the value of the member in other

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Synchronization::AbstractStruct) + + + + — +

    a new struct with the new values

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    of given a member that is not defined in the struct

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+36
+37
+38
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 36
+
+def merge(other, &block)
+  ns_merge(other, &block)
+end
+
+
+ +
+

+ + #select {|value| ... } ⇒ Array + + + + + +

+
+

Yields each member value from the struct to the block and returns an Array +containing the member values from the struct for which the given block +returns a true value (equivalent to Enumerable#select).

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Array) + + + + — +

    an array containing each value for which the block returns true

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+68
+69
+70
+71
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 68
+
+def select(&block)
+  return enum_for(:select) unless block_given?
+  ns_select(&block)
+end
+
+
+ +
+

+ + #to_hHash + + + + + +

+
+

Returns a hash containing the names and values for the struct’s members.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +

    the names and values for the struct’s members

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+41
+42
+43
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 41
+
+def to_h
+  ns_to_h
+end
+
+
+ +
+

+ + #valuesArray + + + + Also known as: + to_a + + + + +

+
+

Returns the values for this struct as an Array.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Array) + + + + — +

    the values for this struct

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 17
+
+def values
+  ns_values
+end
+
+
+ +
+

+ + #values_at(*indexes) ⇒ undocumented + + + + + +

+
+

Returns the struct member values for each selector as an Array.

+ +

A selector may be either an Integer offset or a Range of offsets (as in Array#values_at).

+ + +
+
+
+

Parameters:

+
    + +
  • + + indexes + + + (Fixnum, Range) + + + + — +

    the index(es) from which to obatin the values (in order)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+24
+25
+26
+
+
# File 'lib/concurrent-ruby/concurrent/immutable_struct.rb', line 24
+
+def values_at(*indexes)
+  ns_values_at(indexes)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/IndirectImmediateExecutor.html b/docs/1.1.10/Concurrent/IndirectImmediateExecutor.html new file mode 100644 index 000000000..7f079b526 --- /dev/null +++ b/docs/1.1.10/Concurrent/IndirectImmediateExecutor.html @@ -0,0 +1,427 @@ + + + + + + + Class: Concurrent::IndirectImmediateExecutor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::IndirectImmediateExecutor + + + +

+
+ +
+
Inherits:
+
+ ImmediateExecutor + +
    +
  • Object
  • + + + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Intended for use primarily in testing and debugging.

+
+
+ +

An executor service which runs all operations on a new thread, blocking +until it completes. Operations are performed in the order they are received +and no two operations can be performed simultaneously.

+ +

This executor service exists mainly for testing an debugging. When used it +immediately runs every #post operation on a new thread, blocking the +current thread until the operation is complete. This is similar to how the +ImmediateExecutor works, but the operation has the full stack of the new +thread at its disposal. This can be helpful when the operations will spawn +more operations on the same executor and so on - such a situation might +overflow the single stack in case of an ImmediateExecutor, which is +inconsistent with how it would behave for a threaded executor.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initializeIndirectImmediateExecutor + + + + + +

+
+

Creates a new executor

+ + +
+
+
+ + +
+ + + + +
+
+
+
+21
+22
+23
+24
+
+
# File 'lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb', line 21
+
+def initialize
+  super
+  @internal_executor = SimpleExecutorService.new
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #post(*args) { ... } ⇒ Boolean + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + 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

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+
+
# File 'lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb', line 27
+
+def post(*args, &task)
+  raise ArgumentError.new("no block given") unless block_given?
+  return false unless running?
+
+  event = Concurrent::Event.new
+  @internal_executor.post do
+    begin
+      task.call(*args)
+    ensure
+      event.set
+    end
+  end
+  event.wait
+
+  true
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/LazyRegister.html b/docs/1.1.10/Concurrent/LazyRegister.html new file mode 100644 index 000000000..ef366898e --- /dev/null +++ b/docs/1.1.10/Concurrent/LazyRegister.html @@ -0,0 +1,706 @@ + + + + + + + Class: Concurrent::LazyRegister + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::LazyRegister + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/lazy_register.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Hash-like collection that store lazy evaluated values.

+ + +
+
+
+ +
+

Examples:

+ + +
register = Concurrent::LazyRegister.new
+#=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @Data=#<Concurrent::AtomicReference:0x007fd7ecd5e1e0>>
+register[:key]
+#=> nil
+register.add(:key) { Concurrent::Actor.spawn!(Actor::AdHoc, :ping) { -> message { message } } }
+#=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @Data=#<Concurrent::AtomicReference:0x007fd7ecd5e1e0>>
+register[:key]
+#=> #<Concurrent::Actor::Reference /ping (Concurrent::Actor::AdHoc)>
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initializeLazyRegister + + + + + +

+
+

Returns a new instance of LazyRegister.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+25
+26
+27
+28
+
+
# File 'lib/concurrent-ruby-edge/concurrent/lazy_register.rb', line 25
+
+def initialize
+  super
+  self.data = {}
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #[](key) ⇒ Object + + + + + +

+
+

Element reference. Retrieves the value object corresponding to the +key object. Returns nil if the key is not found. Raises an exception +if the stored item raised an exception when the block was evaluated.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    value stored for the key or nil if the key is not found

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + + + + + +

    Exception when the initialization block fails

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+38
+39
+40
+41
+
+
# File 'lib/concurrent-ruby-edge/concurrent/lazy_register.rb', line 38
+
+def [](key)
+  delay = data[key]
+  delay ? delay.value! : nil
+end
+
+
+ +
+

+ + #register(key) { ... } ⇒ LazyRegister + + + + Also known as: + add, store + + + + +

+
+

Element assignment. Associates the value given by value with the +key given by key.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the object to store under the key

    +
    + +
  • + +
+

Returns:

+ + +
+ + + + +
+
+
+
+61
+62
+63
+64
+65
+
+
# File 'lib/concurrent-ruby-edge/concurrent/lazy_register.rb', line 61
+
+def register(key, &block)
+  delay = Delay.new(executor: :immediate, &block)
+  update_data { |h| h.merge(key => delay) }
+  self
+end
+
+
+ +
+

+ + #registered?(key) ⇒ true, false + + + + Also known as: + key?, has_key? + + + + +

+
+

Returns true if the given key is present.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    if the key is registered

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+47
+48
+49
+
+
# File 'lib/concurrent-ruby-edge/concurrent/lazy_register.rb', line 47
+
+def registered?(key)
+  data.key?(key)
+end
+
+
+ +
+

+ + #unregister(key) ⇒ LazyRegister + + + + Also known as: + remove, delete + + + + +

+
+

Un-registers the object under key, realized or not.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+75
+76
+77
+78
+
+
# File 'lib/concurrent-ruby-edge/concurrent/lazy_register.rb', line 75
+
+def unregister(key)
+  update_data { |h| h.dup.tap { |j| j.delete(key) } }
+  self
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/LockFreeQueue/Node.html b/docs/1.1.10/Concurrent/LockFreeQueue/Node.html new file mode 100644 index 000000000..40bc91776 --- /dev/null +++ b/docs/1.1.10/Concurrent/LockFreeQueue/Node.html @@ -0,0 +1,708 @@ + + + + + + + Class: Concurrent::LockFreeQueue::Node + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::LockFreeQueue::Node + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(item, successor) ⇒ Node + + + + + +

+
+

Returns a new instance of Node.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+12
+13
+14
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb', line 9
+
+def initialize(item, successor)
+  super()
+  # published through queue, no need to be volatile or final
+  @Item          = item
+  self.successor = successor
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #compare_and_set_successor(expected_successor, new_successor) ⇒ true, false + + + + + +

+
+

Sets the successor to new_successor if the current successor is expected_successor

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+7
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb', line 7
+
+attr_atomic :successor
+
+
+ +
+

+ + #itemundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb', line 16
+
+def item
+  @Item
+end
+
+
+ +
+

+ + #successorObject + + + + + +

+
+

Returns The successor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    The successor.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+7
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb', line 7
+
+attr_atomic :successor
+
+
+ +
+

+ + #successor=(new_successor) ⇒ Object + + + + + +

+
+

Set the successor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    new_successor.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+7
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb', line 7
+
+attr_atomic :successor
+
+
+ +
+

+ + #swap_successor(new_successor) ⇒ Object + + + + + +

+
+

Set the successor to new_successor and return the old successor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    old successor

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+7
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb', line 7
+
+attr_atomic :successor
+
+
+ +
+

+ + #update_successor {|Object| ... } ⇒ Object + + + + + +

+
+

Updates the successor using the block.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (Object) + + + + — +

    Calculate a new successor using given (old) successor

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old + + + (Object) + + + + — +

    successor

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    new successor

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+7
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/lock_free_queue.rb', line 7
+
+attr_atomic :successor
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/LockFreeStack.html b/docs/1.1.10/Concurrent/LockFreeStack.html new file mode 100644 index 000000000..6e41f6893 --- /dev/null +++ b/docs/1.1.10/Concurrent/LockFreeStack.html @@ -0,0 +1,1504 @@ + + + + + + + Class: Concurrent::LockFreeStack + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::LockFreeStack + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + +
+
Includes:
+
Enumerable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ + + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: Node + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
EMPTY = +
+
+

The singleton for empty node

+ + +
+
+
+ + +
+
+
Node[nil, nil]
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(head = EMPTY) ⇒ LockFreeStack + + + + + +

+
+

Returns a new instance of LockFreeStack.

+ + +
+
+
+

Parameters:

+
    + +
  • + + head + + + (Node) + + + (defaults to: EMPTY) + + +
  • + +
+ + +
+ + + + +
+
+
+
+49
+50
+51
+52
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 49
+
+def initialize(head = EMPTY)
+  super()
+  self.head = head
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #cleartrue, false + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+116
+117
+118
+119
+120
+121
+122
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 116
+
+def clear
+  while true
+    current_head = head
+    return false if current_head == EMPTY
+    return true if compare_and_set_head current_head, EMPTY
+  end
+end
+
+
+ +
+

+ + #clear_each {|value| ... } ⇒ self + + + + + +

+
+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    over the cleared stack

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 140
+
+def clear_each(&block)
+  while true
+    current_head = head
+    return self if current_head == EMPTY
+    if compare_and_set_head current_head, EMPTY
+      each current_head, &block
+      return self
+    end
+  end
+end
+
+
+ +
+

+ + #clear_if(head) ⇒ true, false + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + head + + + (Node) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+126
+127
+128
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 126
+
+def clear_if(head)
+  compare_and_set_head head, EMPTY
+end
+
+
+ +
+

+ + #compare_and_clear(head) ⇒ true, false + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + head + + + (Node) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+97
+98
+99
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 97
+
+def compare_and_clear(head)
+  compare_and_set_head head, EMPTY
+end
+
+
+ +
+

+ + #compare_and_pop(head) ⇒ true, false + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + head + + + (Node) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+83
+84
+85
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 83
+
+def compare_and_pop(head)
+  compare_and_set_head head, head.next_node
+end
+
+
+ +
+

+ + #compare_and_push(head, value) ⇒ true, false + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + head + + + (Node) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+63
+64
+65
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 63
+
+def compare_and_push(head, value)
+  compare_and_set_head head, Node[value, head]
+end
+
+
+ +
+

+ + #each(head = nil) ⇒ self + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + head + + + (Node) + + + (defaults to: nil) + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+105
+106
+107
+108
+109
+110
+111
+112
+113
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 105
+
+def each(head = nil)
+  return to_enum(:each, head) unless block_given?
+  it = head || peek
+  until it.equal?(EMPTY)
+    yield it.value
+    it = it.next_node
+  end
+  self
+end
+
+
+ +
+

+ + #empty?(head = head()) ⇒ true, false + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + head + + + (Node) + + + (defaults to: head()) + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 56
+
+def empty?(head = head())
+  head.equal? EMPTY
+end
+
+
+ +
+

+ + #peekNode + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Node) + + + +
  • + +
+ +
+ + + + +
+
+
+
+77
+78
+79
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 77
+
+def peek
+  head
+end
+
+
+ +
+

+ + #popObject + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + +
  • + +
+ +
+ + + + +
+
+
+
+88
+89
+90
+91
+92
+93
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 88
+
+def pop
+  while true
+    current_head = head
+    return current_head.value if compare_and_set_head current_head, current_head.next_node
+  end
+end
+
+
+ +
+

+ + #push(value) ⇒ self + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+69
+70
+71
+72
+73
+74
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 69
+
+def push(value)
+  while true
+    current_head = head
+    return self if compare_and_set_head current_head, Node[value, current_head]
+  end
+end
+
+
+ +
+

+ + #replace_if(head, new_head) ⇒ true, false + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + head + + + (Node) + + + +
  • + +
  • + + new_head + + + (Node) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+133
+134
+135
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 133
+
+def replace_if(head, new_head)
+  compare_and_set_head head, new_head
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    Short string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+152
+153
+154
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 152
+
+def to_s
+  format '%s %s>', super[0..-2], to_a.to_s
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/LockFreeStack/Node.html b/docs/1.1.10/Concurrent/LockFreeStack/Node.html new file mode 100644 index 000000000..74f910eef --- /dev/null +++ b/docs/1.1.10/Concurrent/LockFreeStack/Node.html @@ -0,0 +1,393 @@ + + + + + + + Class: Concurrent::LockFreeStack::Node + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::LockFreeStack::Node + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb
+
+ +
+ +
+
+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(value, next_node) ⇒ Node + + + + + +

+
+

Returns a new instance of Node.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+21
+22
+23
+24
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 21
+
+def initialize(value, next_node)
+  @value     = value
+  @next_node = next_node
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #next_nodeNode (readonly) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Node) + + + +
  • + +
+ +
+ + + + +
+
+
+
+12
+13
+14
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 12
+
+def next_node
+  @next_node
+end
+
+
+ + + +
+

+ + #valueObject + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + +
  • + +
+ +
+ + + + +
+
+
+
+15
+16
+17
+
+
# File 'lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb', line 15
+
+def value
+  @value
+end
+
+
+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/MVar.html b/docs/1.1.10/Concurrent/MVar.html new file mode 100644 index 000000000..58aea171c --- /dev/null +++ b/docs/1.1.10/Concurrent/MVar.html @@ -0,0 +1,1433 @@ + + + + + + + Class: Concurrent::MVar + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::MVar + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + +
+
Includes:
+
Concern::Dereferenceable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/mvar.rb
+
+ +
+ +

Overview

+
+

An MVar is a synchronized single element container. They are empty or +contain one item. Taking a value from an empty MVar blocks, as does +putting a value into a full one. You can either think of them as blocking +queue of length one, or a special kind of mutable variable.

+ +

On top of the fundamental #put and #take operations, we also provide a +#mutate that is atomic with respect to operations on the same instance. +These operations all support timeouts.

+ +

We also support non-blocking operations #try_put! and #try_take!, a +#set! that ignores existing values, a #value that returns the value +without removing it or returns MVar::EMPTY, and a #modify! that yields +MVar::EMPTY if the MVar is empty and can be used to set MVar::EMPTY. +You shouldn't use these operations in the first instance.

+ +

MVar is a Dereferenceable.

+ +

MVar is related to M-structures in Id, MVar in Haskell and SyncVar in Scala.

+ +

Note that unlike the original Haskell paper, our #take is blocking. This is how +Haskell and Scala do it today.

+ +

Copy Options

+ +

Object references in Ruby are mutable. This can lead to serious +problems when the Concern::Dereferenceable#value of an object is a mutable reference. Which +is always the case unless the value is a Fixnum, Symbol, or similar +"primitive" data type. Each instance can be configured with a few +options that can help protect the program from potentially dangerous +operations. Each of these options can be optionally set when the object +instance is created:

+ +
    +
  • :dup_on_deref When true the object will call the #dup method on +the value object every time the #value method is called +(default: false)
  • +
  • :freeze_on_deref When true the object will call the #freeze +method on the value object every time the #value method is called +(default: false)
  • +
  • :copy_on_deref When given a Proc object the Proc will be run +every time the #value method is called. The Proc will be given +the current value as its only argument and the result returned by +the block will be the return value of the #value call. When nil +this option will be ignored (default: nil)
  • +
+ +

When multiple deref options are set the order of operations is strictly defined. +The order of deref operations is:

+ +
    +
  • :copy_on_deref
  • +
  • :dup_on_deref
  • +
  • :freeze_on_deref
  • +
+ +

Because of this ordering there is no need to #freeze an object created by a +provided :copy_on_deref block. Simply set :freeze_on_deref to true. +Setting both :dup_on_deref to true and :freeze_on_deref to true is +as close to the behavior of a "pure" functional language (like Erlang, Clojure, +or Haskell) as we are likely to get in Ruby.

+ +

See Also

+ +
    +
  1. P. Barth, R. Nikhil, and Arvind. M-Structures: Extending a parallel, non- strict, functional language with state. In Proceedings of the 5th +ACM Conference on Functional Programming Languages and Computer Architecture (FPCA), 1991.

  2. +
  3. S. Peyton Jones, A. Gordon, and S. Finne. Concurrent Haskell. +In Proceedings of the 23rd Symposium on Principles of Programming Languages +(PoPL), 1996.

  4. +
+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
EMPTY = +
+
+

Unique value that represents that an MVar was empty

+ + +
+
+
+ + +
+
+
::Object.new
+ +
TIMEOUT = +
+
+

Unique value that represents that an MVar timed out before it was able +to produce a value.

+ + +
+
+
+ + +
+
+
::Object.new
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(value = EMPTY, opts = {}) ⇒ MVar + + + + + +

+
+

Create a new MVar, either empty or with an initial value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options controlling how the future will be processed

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Dereferenceable#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Dereferenceable#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Dereferenceable#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
+ + + +
+ + + + +
+
+
+
+54
+55
+56
+57
+58
+59
+60
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 54
+
+def initialize(value = EMPTY, opts = {})
+  @value = value
+  @mutex = Mutex.new
+  @empty_condition = ConditionVariable.new
+  @full_condition = ConditionVariable.new
+  set_deref_options(opts)
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #borrow(timeout = nil) ⇒ Object + + + + + +

+
+

acquires lock on the from an MVAR, yields the value to provided block, +and release lock. A timeout can be set to limit the time spent blocked, +in which case it returns TIMEOUT if the time is exceeded.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value returned by the block, or TIMEOUT

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 86
+
+def borrow(timeout = nil)
+  @mutex.synchronize do
+    wait_for_full(timeout)
+
+    # if we timeoud out we'll still be empty
+    if unlocked_full?
+      yield @value
+    else
+      TIMEOUT
+    end
+  end
+end
+
+
+ +
+

+ + #empty?Boolean + + + + + +

+
+

Returns if the MVar is currently empty.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+195
+196
+197
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 195
+
+def empty?
+  @mutex.synchronize { @value == EMPTY }
+end
+
+
+ +
+

+ + #full?Boolean + + + + + +

+
+

Returns if the MVar currently contains a value.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+200
+201
+202
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 200
+
+def full?
+  !empty?
+end
+
+
+ +
+

+ + #modify(timeout = nil) ⇒ Object + + + + + +

+
+

Atomically take, yield the value to a block for transformation, and then +put the transformed value. Returns the transformed value. A timeout can +be set to limit the time spent blocked, in which case it returns TIMEOUT +if the time is exceeded.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the transformed value, or TIMEOUT

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 123
+
+def modify(timeout = nil)
+  raise ArgumentError.new('no block given') unless block_given?
+
+  @mutex.synchronize do
+    wait_for_full(timeout)
+
+    # If we timed out we'll still be empty
+    if unlocked_full?
+      value = @value
+      @value = yield value
+      @full_condition.signal
+      apply_deref_options(value)
+    else
+      TIMEOUT
+    end
+  end
+end
+
+
+ +
+

+ + #modify!undocumented + + + + + +

+
+

Non-blocking version of modify that will yield with EMPTY if there is no value yet.

+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 179
+
+def modify!
+  raise ArgumentError.new('no block given') unless block_given?
+
+  @mutex.synchronize do
+    value = @value
+    @value = yield value
+    if unlocked_empty?
+      @empty_condition.signal
+    else
+      @full_condition.signal
+    end
+    apply_deref_options(value)
+  end
+end
+
+
+ +
+

+ + #put(value, timeout = nil) ⇒ Object + + + + + +

+
+

Put a value into an MVar, blocking if there is already a value until +it is empty. A timeout can be set to limit the time spent blocked, in +which case it returns TIMEOUT if the time is exceeded.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value that was put, or TIMEOUT

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 103
+
+def put(value, timeout = nil)
+  @mutex.synchronize do
+    wait_for_empty(timeout)
+
+    # If we timed out we won't be empty
+    if unlocked_empty?
+      @value = value
+      @full_condition.signal
+      apply_deref_options(value)
+    else
+      TIMEOUT
+    end
+  end
+end
+
+
+ +
+

+ + #set!(value) ⇒ undocumented + + + + + +

+
+

Non-blocking version of put that will overwrite an existing value.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+169
+170
+171
+172
+173
+174
+175
+176
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 169
+
+def set!(value)
+  @mutex.synchronize do
+    old_value = @value
+    @value = value
+    @full_condition.signal
+    apply_deref_options(old_value)
+  end
+end
+
+
+ +
+

+ + #take(timeout = nil) ⇒ Object + + + + + +

+
+

Remove the value from an MVar, leaving it empty, and blocking if there +isn't a value. A timeout can be set to limit the time spent blocked, in +which case it returns TIMEOUT if the time is exceeded.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value that was taken, or TIMEOUT

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 66
+
+def take(timeout = nil)
+  @mutex.synchronize do
+    wait_for_full(timeout)
+
+    # If we timed out we'll still be empty
+    if unlocked_full?
+      value = @value
+      @value = EMPTY
+      @empty_condition.signal
+      apply_deref_options(value)
+    else
+      TIMEOUT
+    end
+  end
+end
+
+
+ +
+

+ + #try_put!(value) ⇒ undocumented + + + + + +

+
+

Non-blocking version of put, that returns whether or not it was successful.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 156
+
+def try_put!(value)
+  @mutex.synchronize do
+    if unlocked_empty?
+      @value = value
+      @full_condition.signal
+      true
+    else
+      false
+    end
+  end
+end
+
+
+ +
+

+ + #try_take!undocumented + + + + + +

+
+

Non-blocking version of take, that returns EMPTY instead of blocking.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+
+
# File 'lib/concurrent-ruby/concurrent/mvar.rb', line 142
+
+def try_take!
+  @mutex.synchronize do
+    if unlocked_full?
+      value = @value
+      @value = EMPTY
+      @empty_condition.signal
+      apply_deref_options(value)
+    else
+      EMPTY
+    end
+  end
+end
+
+
+ +
+

+ + #valueObject + + + + Also known as: + deref + + + + + + Originally defined in module + Concern::Dereferenceable + + +

+
+

Return the value this object represents after applying the options specified +by the #set_deref_options method.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of the object

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Map.html b/docs/1.1.10/Concurrent/Map.html new file mode 100644 index 000000000..e8b6e42a7 --- /dev/null +++ b/docs/1.1.10/Concurrent/Map.html @@ -0,0 +1,2983 @@ + + + + + + + Class: Concurrent::Map + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Map + + + +

+
+ +
+
Inherits:
+
+ Collection::MapImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/map.rb
+
+ +
+ +

Overview

+
+

Concurrent::Map is a hash-like object and should have much better performance +characteristics, especially under high concurrency, than Concurrent::Hash. +However, Concurrent::Mapis not strictly semantically equivalent to a ruby Hash +-- for instance, it does not necessarily retain ordering by insertion time as Hash +does. For most uses it should do fine though, and we recommend you consider +Concurrent::Map instead of Concurrent::Hash for your concurrency-safe hash needs.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(options = nil, &block) ⇒ Map + + + + + +

+
+

Returns a new instance of Map.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 121
+
+def initialize(options = nil, &block)
+  if options.kind_of?(::Hash)
+    validate_options_hash!(options)
+  else
+    options = nil
+  end
+
+  super(options)
+  @default_proc = block
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #[](key) ⇒ Object + + + + Also known as: + get + + + + +

+
+

Get a value with key

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 135
+
+def [](key)
+  if value = super # non-falsy value is an existing mapping, return it right away
+    value
+    # re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call
+    # a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrent +nil+ value
+    # would be returned)
+    # note: nil == value check is not technically necessary
+  elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL))
+    @default_proc.call(self, key)
+  else
+    value
+  end
+end
+
+
+ +
+

+ + #[]=(key, value) ⇒ Object + + + + Also known as: + put + + + + +

+
+

Set a value with key

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+153
+154
+155
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 153
+
+def []=(key, value)
+  super
+end
+
+
+ +
+

+ + #compute(key) {|old_value| ... } ⇒ Object, nil + + + + + +

+
+ +
+ Note: +

Atomic methods taking a block do not allow the self instance +to be used within the block. Doing so will cause a deadlock.

+
+
+ +

Compute and store new value for key. +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    compute new value from old one

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_value + + + (Object, nil) + + + + — +

    old_value, or nil when key is absent

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    new value, when nil the key is removed

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    new value or nil

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 64
+
+
+
+
+ +
+

+ + #compute_if_absent(key) { ... } ⇒ Object + + + + + +

+
+ +
+ Note: +

Atomic methods taking a block do not allow the self instance +to be used within the block. Doing so will cause a deadlock.

+
+
+ +

Compute and store new value for key if the key is absent. +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    new value

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    new value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    new value or current value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 47
+
+
+
+
+ +
+

+ + #compute_if_present(key) {|old_value| ... } ⇒ Object, nil + + + + + +

+
+ +
+ Note: +

Atomic methods taking a block do not allow the self instance +to be used within the block. Doing so will cause a deadlock.

+
+
+ +

Compute and store new value for key if the key is present. +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    new value

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_value + + + (Object) + + + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    new value, when nil the key is removed

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    new value or nil

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 55
+
+
+
+
+ +
+

+ + #delete(key) ⇒ Object, nil + + + + + +

+
+

Delete key and its value. +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    old value or nil when the key was absent

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 107
+
+
+
+
+ +
+

+ + #delete_pair(key, value) ⇒ true, false + + + + + +

+
+

Delete pair and its value if current value equals the provided value. +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    true if deleted

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 113
+
+
+
+
+ +
+

+ + #each_key {|key| ... } ⇒ self + + + + + +

+
+ +
+ Note: +

Atomic methods taking a block do not allow the self instance +to be used within the block. Doing so will cause a deadlock.

+
+
+ +

Iterates over each key. +This method is atomic.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    for each key in the map

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+251
+252
+253
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 251
+
+def each_key
+  each_pair { |k, v| yield k }
+end
+
+
+ +
+

+ + #each_pair {|key, value| ... } ⇒ self + + + + Also known as: + each + + + + +

+
+ +
+ Note: +

Atomic methods taking a block do not allow the self instance +to be used within the block. Doing so will cause a deadlock.

+
+
+ +

Iterates over each key value pair. +This method is atomic.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    for each key value pair in the map

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+270
+271
+272
+273
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 270
+
+def each_pair
+  return enum_for :each_pair unless block_given?
+  super
+end
+
+
+ +
+

+ + #each_value {|value| ... } ⇒ self + + + + + +

+
+ +
+ Note: +

Atomic methods taking a block do not allow the self instance +to be used within the block. Doing so will cause a deadlock.

+
+
+ +

Iterates over each value. +This method is atomic.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    for each value in the map

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+260
+261
+262
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 260
+
+def each_value
+  each_pair { |k, v| yield v }
+end
+
+
+ +
+

+ + #empty?true, false + + + + + +

+
+

Is map empty?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+287
+288
+289
+290
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 287
+
+def empty?
+  each_pair { |k, v| return false }
+  true
+end
+
+
+ +
+

+ + #fetch(key, default_value = NULL) {|key| ... } ⇒ Object + + + + + +

+
+ +
+ Note: +

The "fetch-then-act" methods of Map are not atomic. Map is intended +to be use as a concurrency primitive with strong happens-before +guarantees. It is not intended to be used as a high-level abstraction +supporting complex operations. All read and write operations are +thread safe, but no guarantees are made regarding race conditions +between the fetch operation and yielding to the block. Additionally, +this method does not support recursion. This is due to internal +constraints that are very unlikely to change in the near future.

+
+
+ +

Get a value with key, or default_value when key is absent, +or fail when no default_value is given.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + default_value + + + (Object) + + + (defaults to: NULL) + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    default value for a key

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    default value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value or default value

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (KeyError) + + + + — +

    when key is missing and no default_value is provided

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 178
+
+def fetch(key, default_value = NULL)
+  if NULL != (value = get_or_default(key, NULL))
+    value
+  elsif block_given?
+    yield key
+  elsif NULL != default_value
+    default_value
+  else
+    raise_fetch_no_key
+  end
+end
+
+
+ +
+

+ + #fetch_or_store(key, default_value = NULL) {|key| ... } ⇒ Object + + + + + +

+
+ +
+ Note: +

Atomic methods taking a block do not allow the self instance +to be used within the block. Doing so will cause a deadlock.

+
+
+ +

Fetch value with key, or store default value when key is absent, +or fail when no default_value is given. This is a two step operation, +therefore not atomic. The store can overwrite other concurrently +stored value. +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + default_value + + + (Object) + + + (defaults to: NULL) + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    default value for a key

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    default value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value or default value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+201
+202
+203
+204
+205
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 201
+
+def fetch_or_store(key, default_value = NULL)
+  fetch(key) do
+    put(key, block_given? ? yield(key) : (NULL == default_value ? raise_fetch_no_key : default_value))
+  end
+end
+
+
+ +
+

+ + #get_and_set(key, value) ⇒ Object, nil + + + + + +

+
+

Get the current value under key and set new value. +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    old value or nil when the key was absent

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 100
+
+
+
+
+ +
+

+ + #key(value) ⇒ Object, nil + + + + + +

+
+

Find key of a value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    key or nil when not found

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+280
+281
+282
+283
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 280
+
+def key(value)
+  each_pair { |k, v| return k if v == value }
+  nil
+end
+
+
+ +
+

+ + #keys::Array<Object> + + + + + +

+
+

All keys

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (::Array<Object>) + + + + — +

    keys

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+232
+233
+234
+235
+236
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 232
+
+def keys
+  arr = []
+  each_pair { |k, v| arr << k }
+  arr
+end
+
+
+ +
+

+ + #merge_pair(key, value) {|old_value| ... } ⇒ Object, nil + + + + + +

+
+ +
+ Note: +

Atomic methods taking a block do not allow the self instance +to be used within the block. Doing so will cause a deadlock.

+
+
+ +

If the key is absent, the value is stored, otherwise new value is +computed with a block. +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    compute new value from old one

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + old_value + + + (Object) + + + + — +

    old value

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    new value, when nil the key is removed

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    new value or nil

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 73
+
+
+
+
+ +
+

+ + #put_if_absent(key, value) ⇒ Object, nil + + + + + +

+
+

Insert value into map with key if key is absent in one atomic step.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    the previous value when key was present or nil when there was no key

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+211
+212
+213
+214
+215
+216
+217
+218
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 211
+
+def put_if_absent(key, value)
+  computed = false
+  result   = compute_if_absent(key) do
+    computed = true
+    value
+  end
+  computed ? nil : result
+end
+
+
+ +
+

+ + #replace_if_exists(key, new_value) ⇒ Object, nil + + + + + +

+
+

Replaces current value with new_value if key exists +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + new_value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    old value or nil

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 93
+
+
+
+
+ +
+

+ + #replace_pair(key, old_value, new_value) ⇒ true, false + + + + + +

+
+

Replaces old_value with new_value if key exists and current value +matches old_value +This method is atomic.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (Object) + + + +
  • + +
  • + + old_value + + + (Object) + + + +
  • + +
  • + + new_value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    true if replaced

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 84
+
+
+
+
+ +
+

+ + #sizeInteger + + + + + +

+
+

The size of map.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    size

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+294
+295
+296
+297
+298
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 294
+
+def size
+  count = 0
+  each_pair { |k, v| count += 1 }
+  count
+end
+
+
+ +
+

+ + #value?(value) ⇒ true, false + + + + + +

+
+

Is the value stored in the map. Iterates over all values.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+223
+224
+225
+226
+227
+228
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 223
+
+def value?(value)
+  each_value do |v|
+    return true if value.equal?(v)
+  end
+  false
+end
+
+
+ +
+

+ + #values::Array<Object> + + + + + +

+
+

All values

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (::Array<Object>) + + + + — +

    values

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+240
+241
+242
+243
+244
+
+
# File 'lib/concurrent-ruby/concurrent/map.rb', line 240
+
+def values
+  arr = []
+  each_pair { |k, v| arr << v }
+  arr
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Maybe.html b/docs/1.1.10/Concurrent/Maybe.html new file mode 100644 index 000000000..d0edde87f --- /dev/null +++ b/docs/1.1.10/Concurrent/Maybe.html @@ -0,0 +1,1215 @@ + + + + + + + Class: Concurrent::Maybe + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Maybe + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + +
+
Includes:
+
Comparable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/maybe.rb
+
+ +
+ +

Overview

+
+

A Maybe encapsulates an optional value. A Maybe either contains a value +of (represented as Just), or it is empty (represented as Nothing). Using +Maybe is a good way to deal with errors or exceptional cases without +resorting to drastic measures such as exceptions.

+ +

Maybe is a replacement for the use of nil with better type checking.

+ +

For compatibility with Concern::Obligation the predicate and +accessor methods are aliased as fulfilled?, rejected?, value, and +reason.

+ +

Motivation

+ +

A common pattern in languages with pattern matching, such as Erlang and +Haskell, is to return either a value or an error from a function +Consider this Erlang code:

+ +
case file:consult("data.dat") of
+  {ok, Terms} -> do_something_useful(Terms);
+  {error, Reason} -> lager:error(Reason)
+end.
+
+ +

In this example the standard library function file:consult returns a +tuple +with two elements: an atom +(similar to a ruby symbol) and a variable containing ancillary data. On +success it returns the atom ok and the data from the file. On failure it +returns error and a string with an explanation of the problem. With this +pattern there is no ambiguity regarding success or failure. If the file is +empty the return value cannot be misinterpreted as an error. And when an +error occurs the return value provides useful information.

+ +

In Ruby we tend to return nil when an error occurs or else we raise an +exception. Both of these idioms are problematic. Returning nil is +ambiguous because nil may also be a valid value. It also lacks +information pertaining to the nature of the error. Raising an exception +is both expensive and usurps the normal flow of control. All of these +problems can be solved with the use of a Maybe.

+ +

A Maybe is unambiguous with regard to whether or not it contains a value. +When Just it contains a value, when Nothing it does not. When Just +the value it contains may be nil, which is perfectly valid. When +Nothing the reason for the lack of a value is contained as well. The +previous Erlang example can be duplicated in Ruby in a principled way by +having functions return Maybe objects:

+ +
result = MyFileUtils.consult("data.dat") # returns a Maybe
+if result.just?
+  do_something_useful(result.value)      # or result.just
+else
+  logger.error(result.reason)            # or result.nothing
+end
+
+ + +
+
+
+ +
+

Examples:

+ + +

Returning a Maybe from a Function

+

+ +
module MyFileUtils
+  def self.consult(path)
+    file = File.open(path, 'r')
+    Concurrent::Maybe.just(file.read)
+  rescue => ex
+    return Concurrent::Maybe.nothing(ex)
+  ensure
+    file.close if file
+  end
+end
+
+maybe = MyFileUtils.consult('bogus.file')
+maybe.just?    #=> false
+maybe.nothing? #=> true
+maybe.reason   #=> #<Errno::ENOENT: No such file or directory @ rb_sysopen - bogus.file>
+
+maybe = MyFileUtils.consult('README.md')
+maybe.just?    #=> true
+maybe.nothing? #=> false
+maybe.value    #=> "# Concurrent Ruby\n[![Gem Version..."
+ + +

Using Maybe with a Block

+

+ +
result = Concurrent::Maybe.from do
+  Client.find(10) # Client is an ActiveRecord model
+end
+
+# -- if the record was found
+result.just? #=> true
+result.value #=> #<Client id: 10, first_name: "Ryan">
+
+# -- if the record was not found
+result.just?  #=> false
+result.reason #=> ActiveRecord::RecordNotFound
+ + +

Using Maybe with the Null Object Pattern

+

+ +
# In a Rails controller...
+result = ClientService.new(10).find    # returns a Maybe
+render json: result.or(NullClient.new)
+ +
+ + +

See Also:

+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
NONE = +
+
+

Indicates that the given attribute has not been set. +When Just the #nothing getter will return NONE. +When Nothing the #just getter will return NONE.

+ + +
+
+
+ + +
+
+
::Object.new.freeze
+ +
+ + + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Attribute Details

+ + + +
+

+ + #justundocumented (readonly) + + + + Also known as: + value + + + + +

+
+

The value of a Maybe when Just. Will be NONE when Nothing.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+114
+115
+116
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 114
+
+def just
+  @just
+end
+
+
+ + + +
+

+ + #nothingundocumented (readonly) + + + + Also known as: + reason + + + + +

+
+

The reason for the Maybe when Nothing. Will be NONE when Just.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+117
+118
+119
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 117
+
+def nothing
+  @nothing
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .from(*args) {|args| ... } ⇒ Maybe + + + + + +

+
+

Create a new Maybe using the given block.

+ +

Runs the given block passing all function arguments to the block as block +arguments. If the block runs to completion without raising an exception +a new Just is created with the value set to the return value of the +block. If the block raises an exception a new Nothing is created with +the reason being set to the raised exception.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    Zero or more arguments to pass to the block.

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    The block from which to create a new Maybe.

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + args + + + (Array<Object>) + + + + — +

    Zero or more block arguments passed as +arguments to the function.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Maybe) + + + + — +

    The newly created object.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    when no block given.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+137
+138
+139
+140
+141
+142
+143
+144
+145
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 137
+
+def self.from(*args)
+  raise ArgumentError.new('no block given') unless block_given?
+  begin
+    value = yield(*args)
+    return new(value, NONE)
+  rescue => ex
+    return new(NONE, ex)
+  end
+end
+
+
+ +
+

+ + .just(value) ⇒ Maybe + + + + + +

+
+

Create a new Just with the given value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    The value to set for the new Maybe object.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Maybe) + + + + — +

    The newly created object.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+152
+153
+154
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 152
+
+def self.just(value)
+  return new(value, NONE)
+end
+
+
+ +
+

+ + .nothing(error = '') ⇒ Maybe + + + + + +

+
+

Create a new Nothing with the given (optional) reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + error + + + (Exception) + + + (defaults to: '') + + + — +

    The reason to set for the new Maybe object. +When given a string a new StandardError will be created with the +argument as the message. When no argument is given a new +StandardError with an empty message will be created.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Maybe) + + + + — +

    The newly created object.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+164
+165
+166
+167
+168
+169
+170
+171
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 164
+
+def self.nothing(error = '')
+  if error.is_a?(Exception)
+    nothing = error
+  else
+    nothing = StandardError.new(error.to_s)
+  end
+  return new(NONE, nothing)
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #<=>(other) ⇒ Integer + + + + + +

+
+

Comparison operator.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    0 if self and other are both Nothing; +-1 if self is Nothing and other is Just; +1 if self is Just and other is nothing; +self.just <=> other.just if both self and other are Just.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+199
+200
+201
+202
+203
+204
+205
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 199
+
+def <=>(other)
+  if nothing?
+    other.nothing? ? 0 : -1
+  else
+    other.nothing? ? 1 : just <=> other.just
+  end
+end
+
+
+ +
+

+ + #just?Boolean + + + + Also known as: + fulfilled? + + + + +

+
+

Is this Maybe a Just (successfully fulfilled with a value)?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if Just or false if Nothing.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+176
+177
+178
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 176
+
+def just?
+  ! nothing?
+end
+
+
+ +
+

+ + #nothing?Boolean + + + + Also known as: + rejected? + + + + +

+
+

Is this Maybe a nothing (rejected with an exception upon fulfillment)?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if Nothing or false if Just.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+184
+185
+186
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 184
+
+def nothing?
+  @nothing != NONE
+end
+
+
+ +
+

+ + #or(other) ⇒ Object + + + + + +

+
+

Return either the value of self or the given default value.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    The value of self when Just; else the given default.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+210
+211
+212
+
+
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 210
+
+def or(other)
+  just? ? just : other
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/MultipleAssignmentError.html b/docs/1.1.10/Concurrent/MultipleAssignmentError.html new file mode 100644 index 000000000..d12deacc8 --- /dev/null +++ b/docs/1.1.10/Concurrent/MultipleAssignmentError.html @@ -0,0 +1,361 @@ + + + + + + + Class: Concurrent::MultipleAssignmentError + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::MultipleAssignmentError + + + +

+
+ +
+
Inherits:
+
+ Error + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/errors.rb
+
+ +
+ +

Overview

+
+

Raised when an attempt is made to modify an immutable object +(such as an IVar) after its final state has been set.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(message = nil, inspection_data = nil) ⇒ MultipleAssignmentError + + + + + +

+
+

Returns a new instance of MultipleAssignmentError.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+36
+37
+38
+39
+
+
# File 'lib/concurrent-ruby/concurrent/errors.rb', line 36
+
+def initialize(message = nil, inspection_data = nil)
+  @inspection_data = inspection_data
+  super message
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #inspection_dataundocumented (readonly) + + + + + +

+
+

Returns the value of attribute inspection_data.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+34
+35
+36
+
+
# File 'lib/concurrent-ruby/concurrent/errors.rb', line 34
+
+def inspection_data
+  @inspection_data
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #inspectundocumented + + + + + +

+ + + + +
+
+
+
+41
+42
+43
+
+
# File 'lib/concurrent-ruby/concurrent/errors.rb', line 41
+
+def inspect
+  format '%s %s>', super[0..-2], @inspection_data.inspect
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/MultipleErrors.html b/docs/1.1.10/Concurrent/MultipleErrors.html new file mode 100644 index 000000000..870adcca8 --- /dev/null +++ b/docs/1.1.10/Concurrent/MultipleErrors.html @@ -0,0 +1,306 @@ + + + + + + + Class: Concurrent::MultipleErrors + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::MultipleErrors + + + +

+
+ +
+
Inherits:
+
+ Error + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/errors.rb
+
+ +
+ +

Overview

+
+

Aggregates multiple exceptions.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(errors, message = "#{errors.size} errors") ⇒ MultipleErrors + + + + + +

+
+

Returns a new instance of MultipleErrors.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+61
+62
+63
+64
+65
+66
+
+
# File 'lib/concurrent-ruby/concurrent/errors.rb', line 61
+
+def initialize(errors, message = "#{errors.size} errors")
+  @errors = errors
+  super [*message,
+         *errors.map { |e| [format('%s (%s)', e.message, e.class), *e.backtrace] }.flatten(1)
+        ].join("\n")
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #errorsundocumented (readonly) + + + + + +

+
+

Returns the value of attribute errors.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+59
+60
+61
+
+
# File 'lib/concurrent-ruby/concurrent/errors.rb', line 59
+
+def errors
+  @errors
+end
+
+
+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/MutableStruct.html b/docs/1.1.10/Concurrent/MutableStruct.html new file mode 100644 index 000000000..a723c1898 --- /dev/null +++ b/docs/1.1.10/Concurrent/MutableStruct.html @@ -0,0 +1,1375 @@ + + + + + + + Module: Concurrent::MutableStruct + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::MutableStruct + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/mutable_struct.rb
+
+ +
+ +

Overview

+
+

An thread-safe variation of Ruby's standard Struct. Values can be set at +construction or safely changed at any time during the object's lifecycle.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #==(other) ⇒ Boolean + + + + + +

+
+

Equality

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if other has the same struct subclass and has +equal member values (according to Object#==)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+128
+129
+130
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 128
+
+def ==(other)
+  synchronize { ns_equality(other) }
+end
+
+
+ +
+

+ + #[](member) ⇒ Object + + + + + +

+
+

Attribute Reference

+ + +
+
+
+

Parameters:

+
    + +
  • + + member + + + (Symbol, String, Integer) + + + + — +

    the string or symbol name of the member +for which to obtain the value or the member's index

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value of the given struct member or the member at the given index.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NameError) + + + + — +

    if the member does not exist

    +
    + +
  • + +
  • + + + (IndexError) + + + + — +

    if the index is out of range.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 118
+
+def [](member)
+  synchronize { ns_get(member) }
+end
+
+
+ +
+

+ + #[]=(member, value) ⇒ Object + + + + + +

+
+

Attribute Assignment

+ +

Sets the value of the given struct member or the member at the given index.

+ + +
+
+
+

Parameters:

+
    + +
  • + + member + + + (Symbol, String, Integer) + + + + — +

    the string or symbol name of the member +for which to obtain the value or the member's index

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value of the given struct member or the member at the given index.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NameError) + + + + — +

    if the name does not exist

    +
    + +
  • + +
  • + + + (IndexError) + + + + — +

    if the index is out of range.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 185
+
+def []=(member, value)
+  if member.is_a? Integer
+    length = synchronize { @values.length }
+    if member >= length
+      raise IndexError.new("offset #{member} too large for struct(size:#{length})")
+    end
+    synchronize { @values[member] = value }
+  else
+    send("#{member}=", value)
+  end
+rescue NoMethodError
+  raise NameError.new("no member '#{member}' in struct")
+end
+
+
+ +
+

+ + #each {|value| ... } ⇒ undocumented + + + + + +

+
+

Yields the value of each struct member in order. If no block is given +an enumerator is returned.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+139
+140
+141
+142
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 139
+
+def each(&block)
+  return enum_for(:each) unless block_given?
+  synchronize { ns_each(&block) }
+end
+
+
+ +
+

+ + #each_pair {|member, value| ... } ⇒ undocumented + + + + + +

+
+

Yields the name and value of each struct member in order. If no block is +given an enumerator is returned.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member/value pair

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + member + + + (Object) + + + + — +

    each struct member (in order)

    +
    + +
  • + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+152
+153
+154
+155
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 152
+
+def each_pair(&block)
+  return enum_for(:each_pair) unless block_given?
+  synchronize { ns_each_pair(&block) }
+end
+
+
+ +
+

+ + #inspectString + + + + Also known as: + to_s + + + + +

+
+

Describe the contents of this struct in a string.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    the contents of this struct in a string

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+72
+73
+74
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 72
+
+def inspect
+  synchronize { ns_inspect }
+end
+
+
+ +
+

+ + #merge(other) {|member, selfvalue, othervalue| ... } ⇒ Synchronization::AbstractStruct + + + + + +

+
+

Returns a new struct containing the contents of other and the contents +of self. If no block is specified, the value for entries with duplicate +keys will be that of other. Otherwise the value for each duplicate key +is determined by calling the block with the key, its value in self and +its value in other.

+ + +
+
+
+

Parameters:

+
    + +
  • + + other + + + (Hash) + + + + — +

    the hash from which to set the new values

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    an options block for resolving duplicate keys

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + member + + + (String, Symbol) + + + + — +

    the name of the member which is duplicated

    +
    + +
  • + +
  • + + selfvalue + + + (Object) + + + + — +

    the value of the member in self

    +
    + +
  • + +
  • + + othervalue + + + (Object) + + + + — +

    the value of the member in other

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Synchronization::AbstractStruct) + + + + — +

    a new struct with the new values

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    of given a member that is not defined in the struct

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+94
+95
+96
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 94
+
+def merge(other, &block)
+  synchronize { ns_merge(other, &block) }
+end
+
+
+ +
+

+ + #select {|value| ... } ⇒ Array + + + + + +

+
+

Yields each member value from the struct to the block and returns an Array +containing the member values from the struct for which the given block +returns a true value (equivalent to Enumerable#select).

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Array) + + + + — +

    an array containing each value for which the block returns true

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+167
+168
+169
+170
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 167
+
+def select(&block)
+  return enum_for(:select) unless block_given?
+  synchronize { ns_select(&block) }
+end
+
+
+ +
+

+ + #to_hHash + + + + + +

+
+

Returns a hash containing the names and values for the struct’s members.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +

    the names and values for the struct’s members

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+103
+104
+105
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 103
+
+def to_h
+  synchronize { ns_to_h }
+end
+
+
+ +
+

+ + #valuesArray + + + + Also known as: + to_a + + + + +

+
+

Returns the values for this struct as an Array.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Array) + + + + — +

    the values for this struct

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+51
+52
+53
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 51
+
+def values
+  synchronize { ns_values }
+end
+
+
+ +
+

+ + #values_at(*indexes) ⇒ undocumented + + + + + +

+
+

Returns the struct member values for each selector as an Array.

+ +

A selector may be either an Integer offset or a Range of offsets (as in Array#values_at).

+ + +
+
+
+

Parameters:

+
    + +
  • + + indexes + + + (Fixnum, Range) + + + + — +

    the index(es) from which to obatin the values (in order)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+63
+64
+65
+
+
# File 'lib/concurrent-ruby/concurrent/mutable_struct.rb', line 63
+
+def values_at(*indexes)
+  synchronize { ns_values_at(indexes) }
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ProcessingActor.html b/docs/1.1.10/Concurrent/ProcessingActor.html new file mode 100644 index 000000000..0bf1c3d53 --- /dev/null +++ b/docs/1.1.10/Concurrent/ProcessingActor.html @@ -0,0 +1,1141 @@ + + + + + + + Class: Concurrent::ProcessingActor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ProcessingActor + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

A new implementation of actor which also simulates the process, therefore it can be used +in the same way as Erlang's actors but without occupying thread. A tens of thousands +ProcessingActors can run at the same time sharing a thread pool.

+ + +
+
+
+ +
+

Examples:

+ + +
# Runs on a pool, does not consume 50_000 threads
+actors = 50_000.times.map do |i|
+  Concurrent::ProcessingActor.act(i) { |a, i| a.receive.then_on(:fast, i) { |m, i| m + i } }
+end
+
+actors.each { |a| a.tell 1 }
+values = actors.map(&:termination).map(&:value)
+values[0,5]                                        # => [1, 2, 3, 4, 5]
+values[-5, 5]                                      # => [49996, 49997, 49998, 49999, 50000]
+ +
+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Class Method Details

+ + +
+

+ + .act(*args, &process) ⇒ ProcessingActor + + + + + +

+
+

Creates an actor.

+ + +
+
+
+ +
+

Examples:

+ + +
actor = Concurrent::ProcessingActor.act do |actor|
+  actor.receive.then do |message|
+    # the actor ends normally with message
+    message
+  end
+end
+
+actor.tell :a_message
+    # => <#Concurrent::ProcessingActor:0x7fff11280560 termination:pending>
+actor.termination.value! # => :a_message
+ +
+ +

Returns:

+ + +

See Also:

+
    + +
  • Behaves the same way, but does not take mailbox as a first argument.
  • + +
+ +
+ + + + +
+
+
+
+50
+51
+52
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 50
+
+def self.act(*args, &process)
+  act_listening Promises::Channel.new, *args, &process
+end
+
+
+ +
+

+ + .act_listening(channel, *args) {|actor, *args| ... } ⇒ ProcessingActor + + + + + +

+
+

Creates an actor listening to a specified channel (mailbox).

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    Arguments passed to the process.

    +
    + +
  • + +
  • + + channel + + + (Promises::Channel) + + + + — +

    which serves as mailing box. The channel can have limited +size to achieve backpressure.

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (actor, *args) + + + + — +

    to the process to get back a future which represents the actors execution.

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + actor + + + (ProcessingActor) + + + +
  • + +
  • + + *args + + + (Object) + + + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Promises::Future(Object)) + + + + — +

    a future representing next step of execution

    +
    + +
  • + +
+

Returns:

+ + +
+ + + + +
+
+
+
+63
+64
+65
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 63
+
+def self.act_listening(channel, *args, &process)
+  ProcessingActor.new channel, *args, &process
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #ask_op(answer = Promises.resolvable_future, &message_provider) ⇒ undocumented + + + + + +

+
+

actor.ask2 { |a| [:count, a] }

+ + +
+
+
+ + +
+ + + + +
+
+
+
+153
+154
+155
+156
+157
+158
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 153
+
+def ask_op(answer = Promises.resolvable_future, &message_provider)
+  # TODO (pitr-ch 12-Dec-2018): is it ok to let the answers be unanswered when the actor terminates
+  tell_op(message_provider.call(answer)).then(answer) { |_, a| a }
+
+  # answer.chain { |v| [true, v] } | @Terminated.then
+end
+
+
+ +
+

+ + #mailboxPromises::Channel + + + + + +

+
+

Returns actor's mailbox.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 25
+
+def mailbox
+  @Mailbox
+end
+
+
+ +
+

+ + #receive(channel = mailbox) ⇒ undocumented + + + + + +

+
+

Receives a message when available, used in the actor's process.

+ +

@return [Promises::Future(Object)] a future which will be fulfilled with a message from

+ +

mailbox when it is available.

+ +

def receive(*channels) + channels = [@Mailbox] if channels.empty? + Promises::Channel.select(*channels) + # TODO (pitr-ch 27-Dec-2016): support patterns + # - put any received message aside if it does not match + # - on each receive call check the messages put aside + # - track where the message came from, cannot later receive m form other channel only because it matches +end

+ + +
+
+
+ + +
+ + + + +
+
+
+
+79
+80
+81
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 79
+
+def receive(channel = mailbox)
+  channel.pop_op
+end
+
+
+ +
+

+ + #tell!(message) ⇒ self + + + + + +

+
+

Tells a message to the actor. May block current thread if the mailbox is full. +#tell_op is a better option since it does not block. It's usually used to integrate with +threading code.

+ + +
+
+
+ +
+

Examples:

+ + +
Thread.new(actor) do |actor|
+  # ...
+  actor.tell! :a_message # blocks until the message is told
+  #   (there is a space for it in the channel)
+  # ...
+end
+ +
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+95
+96
+97
+98
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 95
+
+def tell!(message)
+  @Mailbox.push(message)
+  self
+end
+
+
+ +
+

+ + #tell_op(message) ⇒ Promises::Future(ProcessingActor) + + + + + +

+
+

Tells a message to the actor.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Promises::Future(ProcessingActor)) + + + + — +

    a future which will be fulfilled with the actor +when the message is pushed to mailbox.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+104
+105
+106
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 104
+
+def tell_op(message)
+  @Mailbox.push_op(message).then(self) { |_ch, actor| actor }
+end
+
+
+ +
+

+ + #terminationPromises::Future(Object) + + + + + +

+
+

Returns a future which is resolved when the actor ends its processing. +It can either be fulfilled with a value when actor ends normally or rejected with +a reason (exception) when actor fails.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Promises::Future(Object)) + + + + — +

    a future which is resolved when the actor ends its processing. +It can either be fulfilled with a value when actor ends normally or rejected with +a reason (exception) when actor fails.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+32
+33
+34
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 32
+
+def termination
+  @Terminated.with_hidden_resolvable
+end
+
+
+ +
+

+ + #to_aryundocumented + + + + + +

+
+ + +
+
+
+ + +
+ + + + +
+
+
+
+167
+168
+169
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 167
+
+def to_ary
+  [@Mailbox, @Terminated]
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+161
+162
+163
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/processing_actor.rb', line 161
+
+def to_s
+  format '%s termination: %s>', super[0..-2], termination.state
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promise.html b/docs/1.1.10/Concurrent/Promise.html new file mode 100644 index 000000000..cb0f35acb --- /dev/null +++ b/docs/1.1.10/Concurrent/Promise.html @@ -0,0 +1,3041 @@ + + + + + + + Class: Concurrent::Promise + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Promise + + + +

+
+ +
+
Inherits:
+
+ IVar + +
    +
  • Object
  • + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promise.rb
+
+ +
+ +

Overview

+
+

Promises are inspired by the JavaScript Promises/A +and Promises/A+ specifications.

+ +
+

A promise represents the eventual value returned from the single +completion of an operation.

+
+ +

Promises are similar to futures and share many of the same behaviours. +Promises are far more robust, however. Promises can be chained in a tree +structure where each promise may have zero or more children. Promises are +chained using the then method. The result of a call to then is always +another promise. Promises are resolved asynchronously (with respect to the +main thread) but in a strict order: parents are guaranteed to be resolved +before their children, children before their younger siblings. The then +method takes two parameters: an optional block to be executed upon parent +resolution and an optional callable to be executed upon parent failure. The +result of each promise is passed to each of its children upon resolution. +When a promise is rejected all its children will be summarily rejected and +will receive the reason.

+ +

Promises have several possible states: :unscheduled, :pending, +:processing, :rejected, or :fulfilled. These are also aggregated as +#incomplete? and #complete?. When a Promise is created it is set to +:unscheduled. Once the #execute method is called the state becomes +:pending. Once a job is pulled from the thread pool's queue and is given +to a thread for processing (often immediately upon #post) the state +becomes :processing. The future will remain in this state until processing +is complete. A future that is in the :unscheduled, :pending, or +:processing is considered #incomplete?. A #complete? Promise is either +:rejected, indicating that an exception was thrown during processing, or +:fulfilled, indicating success. If a Promise is :fulfilled its #value +will be updated to reflect the result of the operation. If :rejected the +reason will be updated with a reference to the thrown exception. The +predicate methods #unscheduled?, #pending?, #rejected?, and +#fulfilled? can be called at any time to obtain the state of the Promise, +as can the #state method, which returns a symbol.

+ +

Retrieving the value of a promise is done through the value (alias: +deref) method. Obtaining the value of a promise is a potentially blocking +operation. When a promise is rejected a call to value will return nil +immediately. When a promise is fulfilled a call to value will +immediately return the current value. When a promise is pending a call to +value will block until the promise is either rejected or fulfilled. A +timeout value can be passed to value to limit how long the call will +block. If nil the call will block indefinitely. If 0 the call will not +block. Any other integer or float value will indicate the maximum number of +seconds to block.

+ +

Promises run on the global thread pool.

+ +

Copy Options

+ +

Object references in Ruby are mutable. This can lead to serious +problems when the Concern::Obligation#value of an object is a mutable reference. Which +is always the case unless the value is a Fixnum, Symbol, or similar +"primitive" data type. Each instance can be configured with a few +options that can help protect the program from potentially dangerous +operations. Each of these options can be optionally set when the object +instance is created:

+ +
    +
  • :dup_on_deref When true the object will call the #dup method on +the value object every time the #value method is called +(default: false)
  • +
  • :freeze_on_deref When true the object will call the #freeze +method on the value object every time the #value method is called +(default: false)
  • +
  • :copy_on_deref When given a Proc object the Proc will be run +every time the #value method is called. The Proc will be given +the current value as its only argument and the result returned by +the block will be the return value of the #value call. When nil +this option will be ignored (default: nil)
  • +
+ +

When multiple deref options are set the order of operations is strictly defined. +The order of deref operations is:

+ +
    +
  • :copy_on_deref
  • +
  • :dup_on_deref
  • +
  • :freeze_on_deref
  • +
+ +

Because of this ordering there is no need to #freeze an object created by a +provided :copy_on_deref block. Simply set :freeze_on_deref to true. +Setting both :dup_on_deref to true and :freeze_on_deref to true is +as close to the behavior of a "pure" functional language (like Erlang, Clojure, +or Haskell) as we are likely to get in Ruby.

+ +

Examples

+ +

Start by requiring promises

+ +
require 'concurrent'
+
+ +

Then create one

+ +
p = Concurrent::Promise.execute do
+      # do something
+      42
+    end
+
+ +

Promises can be chained using the then method. The then method accepts a +block and an executor, to be executed on fulfillment, and a callable argument to be executed +on rejection. The result of the each promise is passed as the block argument +to chained promises.

+ +
p = Concurrent::Promise.new{10}.then{|x| x * 2}.then{|result| result - 10 }.execute
+
+ +

And so on, and so on, and so on...

+ +
p = Concurrent::Promise.fulfill(20).
+    then{|result| result - 10 }.
+    then{|result| result * 3 }.
+    then(executor: different_executor){|result| result % 5 }.execute
+
+ +

The initial state of a newly created Promise depends on the state of its parent:

+ +
    +
  • if parent is unscheduled the child will be unscheduled
  • +
  • if parent is pending the child will be pending
  • +
  • if parent is fulfilled the child will be pending
  • +
  • if parent is rejected the child will be pending (but will ultimately be rejected)
  • +
+ +

Promises are executed asynchronously from the main thread. By the time a +child Promise finishes intialization it may be in a different state than its +parent (by the time a child is created its parent may have completed +execution and changed state). Despite being asynchronous, however, the order +of execution of Promise objects in a chain (or tree) is strictly defined.

+ +

There are multiple ways to create and execute a new Promise. Both ways +provide identical behavior:

+ +
# create, operate, then execute
+p1 = Concurrent::Promise.new{ "Hello World!" }
+p1.state #=> :unscheduled
+p1.execute
+
+# create and immediately execute
+p2 = Concurrent::Promise.new{ "Hello World!" }.execute
+
+# execute during creation
+p3 = Concurrent::Promise.execute{ "Hello World!" }
+
+ +

Once the execute method is called a Promise becomes pending:

+ +
p = Concurrent::Promise.execute{ "Hello, world!" }
+p.state    #=> :pending
+p.pending? #=> true
+
+ +

Wait a little bit, and the promise will resolve and provide a value:

+ +
p = Concurrent::Promise.execute{ "Hello, world!" }
+sleep(0.1)
+
+p.state      #=> :fulfilled
+p.fulfilled? #=> true
+p.value      #=> "Hello, world!"
+
+ +

If an exception occurs, the promise will be rejected and will provide +a reason for the rejection:

+ +
p = Concurrent::Promise.execute{ raise StandardError.new("Here comes the Boom!") }
+sleep(0.1)
+
+p.state     #=> :rejected
+p.rejected? #=> true
+p.reason    #=> "#<StandardError: Here comes the Boom!>"
+
+ +

Rejection

+ +

When a promise is rejected all its children will be rejected and will +receive the rejection reason as the rejection callable parameter:

+ +
p = Concurrent::Promise.execute { Thread.pass; raise StandardError }
+
+c1 = p.then(-> reason { 42 })
+c2 = p.then(-> reason { raise 'Boom!' })
+
+c1.wait.state  #=> :fulfilled
+c1.value       #=> 45
+c2.wait.state  #=> :rejected
+c2.reason      #=> #<RuntimeError: Boom!>
+
+ +

Once a promise is rejected it will continue to accept children that will +receive immediately rejection (they will be executed asynchronously).

+ +

Aliases

+ +

The then method is the most generic alias: it accepts a block to be +executed upon parent fulfillment and a callable to be executed upon parent +rejection. At least one of them should be passed. The default block is { +|result| result } that fulfills the child with the parent value. The +default callable is { |reason| raise reason } that rejects the child with +the parent reason.

+ +
    +
  • on_success { |result| ... } is the same as then {|result| ... }
  • +
  • rescue { |reason| ... } is the same as then(Proc.new { |reason| ... } )
  • +
  • rescue is aliased by catch and on_error
  • +
+ + +
+
+
+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(opts = {}) { ... } ⇒ Promise + + + + + +

+
+

Initialize a new Promise with the provided options.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Obligation#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
  • + :parent + (Promise) + + + + + —

    the parent Promise when building a chain/tree

    +
    + +
  • + +
  • + :on_fulfill + (Proc) + + + + + —

    fulfillment handler

    +
    + +
  • + +
  • + :on_reject + (Proc) + + + + + —

    rejection handler

    +
    + +
  • + +
  • + :args + (object, Array) + + + + + —

    zero or more arguments to be passed +the task block on execution

    +
    + +
  • + +
+ + +

Yields:

+
    + +
  • + + + + + + + +

    The block operation to be performed asynchronously.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+210
+211
+212
+213
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 210
+
+def initialize(opts = {}, &block)
+  opts.delete_if { |k, v| v.nil? }
+  super(NULL, opts.merge(__promise_body_from_block__: block), &nil)
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .all?(*promises) ⇒ Boolean + + + + + +

+
+

Aggregates a collection of promises and executes the then condition +if all aggregated promises succeed. Executes the rescue handler with +a Concurrent::PromiseExecutionError if any of the aggregated promises +fail. Upon execution will execute any of the aggregate promises that +were not already executed.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+464
+465
+466
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 464
+
+def self.all?(*promises)
+  aggregate(:all?, *promises)
+end
+
+
+ +
+

+ + .any?(*promises) ⇒ Promise + + + + + +

+
+

Aggregates a collection of promises and executes the then condition +if any aggregated promises succeed. Executes the rescue handler with +a Concurrent::PromiseExecutionError if any of the aggregated promises +fail. Upon execution will execute any of the aggregate promises that +were not already executed.

+ +

The returned promise will not yet have been executed. Additional #then +and #rescue handlers may still be provided. Once the returned promise +is execute the aggregate promises will be also be executed (if they have +not been executed already). The results of the aggregate promises will +be checked upon completion. The necessary #then and #rescue blocks +on the aggregating promise will then be executed as appropriate. If the +#rescue handlers are executed the raises exception will be +Concurrent::PromiseExecutionError.

+ + +
+
+
+

Parameters:

+
    + +
  • + + promises + + + (Array) + + + + — +

    Zero or more promises to aggregate

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Promise) + + + + — +

    an unscheduled (not executed) promise that aggregates +the promises given as arguments

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+475
+476
+477
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 475
+
+def self.any?(*promises)
+  aggregate(:any?, *promises)
+end
+
+
+ +
+

+ + .execute(opts = {}, &block) ⇒ Promise + + + + + +

+
+

Create a new Promise object with the given block, execute it, and return the +:pending object.

+ + +
+
+
+ +
+

Examples:

+ + +
promise = Concurrent::Promise.execute{ sleep(1); 42 }
+promise.state #=> :pending
+ +
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Obligation#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
  • + :parent + (Promise) + + + + + —

    the parent Promise when building a chain/tree

    +
    + +
  • + +
  • + :on_fulfill + (Proc) + + + + + —

    fulfillment handler

    +
    + +
  • + +
  • + :on_reject + (Proc) + + + + + —

    rejection handler

    +
    + +
  • + +
  • + :args + (object, Array) + + + + + —

    zero or more arguments to be passed +the task block on execution

    +
    + +
  • + +
+ + + + +

Returns:

+
    + +
  • + + + (Promise) + + + + — +

    the newly created Promise in the :pending state

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+296
+297
+298
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 296
+
+def self.execute(opts = {}, &block)
+  new(opts, &block).execute
+end
+
+
+ +
+

+ + .fulfill(value, opts = {}) ⇒ Promise + + + + + +

+
+

Create a new Promise and fulfill it immediately.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Obligation#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
  • + :parent + (Promise) + + + + + —

    the parent Promise when building a chain/tree

    +
    + +
  • + +
  • + :on_fulfill + (Proc) + + + + + —

    fulfillment handler

    +
    + +
  • + +
  • + :on_reject + (Proc) + + + + + —

    rejection handler

    +
    + +
  • + +
  • + :args + (object, Array) + + + + + —

    zero or more arguments to be passed +the task block on execution

    +
    + +
  • + +
+ + +

Returns:

+
    + +
  • + + + (Promise) + + + + — +

    the newly created Promise

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+224
+225
+226
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 224
+
+def self.fulfill(value, opts = {})
+  Promise.new(opts).tap { |p| p.send(:synchronized_set_state!, true, value, nil) }
+end
+
+
+ +
+

+ + .reject(reason, opts = {}) ⇒ Promise + + + + + +

+
+

Create a new Promise and reject it immediately.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Obligation#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
  • + :parent + (Promise) + + + + + —

    the parent Promise when building a chain/tree

    +
    + +
  • + +
  • + :on_fulfill + (Proc) + + + + + —

    fulfillment handler

    +
    + +
  • + +
  • + :on_reject + (Proc) + + + + + —

    rejection handler

    +
    + +
  • + +
  • + :args + (object, Array) + + + + + —

    zero or more arguments to be passed +the task block on execution

    +
    + +
  • + +
+ + +

Returns:

+
    + +
  • + + + (Promise) + + + + — +

    the newly created Promise

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+237
+238
+239
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 237
+
+def self.reject(reason, opts = {})
+  Promise.new(opts).tap { |p| p.send(:synchronized_set_state!, false, nil, reason) }
+end
+
+
+ +
+

+ + + .zip(*promises) ⇒ Promise<Array> + + .zip(*promises, opts) ⇒ Promise<Array> + + + + + + +

+
+

Builds a promise that produces the result of promises in an Array +and fails if any of them fails.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + .zip(*promises) ⇒ Promise<Array> +
    +
    + + +
    +
    +
    +

    Parameters:

    + + + +
    +
  • + + +
  • + .zip(*promises, opts) ⇒ Promise<Array> +
    +
    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + promises + + + (Array<Promise>) + + + +
    • + +
    • + + opts + + + (Hash) + + + + — +

      the configuration options

      +
      + +
    • + +
    + + + + + + +

    Options Hash (opts):

    +
      + +
    • + :executor + (Executor) + + + — default: + ImmediateExecutor.new + + + + —

      when set use the given Executor instance.

      +
      + +
    • + +
    • + :execute + (Boolean) + + + — default: + true + + + + —

      execute promise before returning

      +
      + +
    • + +
    + + + +
    +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 409
+
+def self.zip(*promises)
+  opts = promises.last.is_a?(::Hash) ? promises.pop.dup : {}
+  opts[:executor] ||= ImmediateExecutor.new
+  zero = if !opts.key?(:execute) || opts.delete(:execute)
+    fulfill([], opts)
+  else
+    Promise.new(opts) { [] }
+  end
+
+  promises.reduce(zero) do |p1, p2|
+    p1.flat_map do |results|
+      p2.then do |next_result|
+        results << next_result
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #executePromise + + + + + +

+
+

Execute an :unscheduled Promise. Immediately sets the state to :pending and +passes the block to a new thread/thread pool for eventual execution. +Does nothing if the Promise is in any state other than :unscheduled.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Promise) + + + + — +

    a reference to self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 246
+
+def execute
+  if root?
+    if compare_and_set_state(:pending, :unscheduled)
+      set_pending
+      realize(@promise_body)
+    end
+  else
+    compare_and_set_state(:pending, :unscheduled)
+    @parent.execute
+  end
+  self
+end
+
+
+ +
+

+ + #fail(reason = StandardError.new) ⇒ IVar + + + + + +

+
+

Set the IVar to failed due to some error and wake or notify all threads waiting on it.

+ + +
+
+
+

Parameters:

+
    + +
  • + + reason + + + (Object) + + + (defaults to: StandardError.new) + + + — +

    for the failure

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (IVar) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+278
+279
+280
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 278
+
+def fail(reason = StandardError.new)
+  set { raise reason }
+end
+
+
+ +
+

+ + #flat_map(&block) ⇒ Promise + + + + + +

+
+

Yield the successful result to the block that returns a promise. If that +promise is also successful the result is the result of the yielded promise. +If either part fails the whole also fails.

+ + +
+
+
+ +
+

Examples:

+ + +
Promise.execute { 1 }.flat_map { |v| Promise.execute { v + 2 } }.value! #=> 3
+ +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 375
+
+def flat_map(&block)
+  child = Promise.new(
+    parent: self,
+    executor: ImmediateExecutor.new,
+  )
+
+  on_error { |e| child.on_reject(e) }
+  on_success do |result1|
+    begin
+      inner = block.call(result1)
+      inner.execute
+      inner.on_success { |result2| child.on_fulfill(result2) }
+      inner.on_error { |e| child.on_reject(e) }
+    rescue => e
+      child.on_reject(e)
+    end
+  end
+
+  child
+end
+
+
+ +
+

+ + #on_success { ... } ⇒ Promise + + + + + +

+
+

Chain onto this promise an action to be undertaken on success +(fulfillment).

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    The block to execute

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Promise) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+349
+350
+351
+352
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 349
+
+def on_success(&block)
+  raise ArgumentError.new('no block given') unless block_given?
+  self.then(&block)
+end
+
+
+ +
+

+ + #rescue { ... } ⇒ Promise + + + + Also known as: + catch, on_error + + + + +

+
+

Chain onto this promise an action to be undertaken on failure +(rejection).

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    The block to execute

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Promise) + + + + — +

    self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+360
+361
+362
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 360
+
+def rescue(&block)
+  self.then(block)
+end
+
+
+ +
+

+ + #set(value = NULL) { ... } ⇒ IVar + + + + + +

+
+

Set the IVar to a value and wake or notify all threads waiting on it.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + (defaults to: NULL) + + + — +

    the value to store in the IVar

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    A block operation to use for setting the value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (IVar) + + + + — +

    self

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 262
+
+def set(value = NULL, &block)
+  raise PromiseExecutionError.new('supported only on root promise') unless root?
+  check_for_block_or_value!(block_given?, value)
+  synchronize do
+    if @state != :unscheduled
+      raise MultipleAssignmentError
+    else
+      @promise_body = block || Proc.new { |result| value }
+    end
+  end
+  execute
+end
+
+
+ +
+

+ + + #then(rescuer, executor, &block) ⇒ Promise + + #then(rescuer, executor: executor, &block) ⇒ Promise + + + + + + +

+
+

Chain a new promise off the current promise.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #then(rescuer, executor, &block) ⇒ Promise +
    +
    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + rescuer + + + (Proc) + + + + — +

      An optional rescue block to be executed if the +promise is rejected.

      +
      + +
    • + +
    • + + executor + + + (ThreadPool) + + + + — +

      An optional thread pool executor to be used +in the new Promise

      +
      + +
    • + +
    + + +
    +
  • + + +
  • + #then(rescuer, executor: executor, &block) ⇒ Promise +
    +
    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + rescuer + + + (Proc) + + + + — +

      An optional rescue block to be executed if the +promise is rejected.

      +
      + +
    • + +
    • + + executor + + + (ThreadPool) + + + (defaults to: executor) + + + — +

      An optional thread pool executor to be used +in the new Promise

      +
      + +
    • + +
    + + +
    +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    The block operation to be performed asynchronously.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Promise) + + + + — +

    the new promise

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 314
+
+def then(*args, &block)
+  if args.last.is_a?(::Hash)
+    executor = args.pop[:executor]
+    rescuer = args.first
+  else
+    rescuer, executor = args
+  end
+
+  executor ||= @executor
+
+  raise ArgumentError.new('rescuers and block are both missing') if rescuer.nil? && !block_given?
+  block = Proc.new { |result| result } unless block_given?
+  child = Promise.new(
+    parent: self,
+    executor: executor,
+    on_fulfill: block,
+    on_reject: rescuer
+  )
+
+  synchronize do
+    child.state = :pending if @state == :pending
+    child.on_fulfill(apply_deref_options(@value)) if @state == :fulfilled
+    child.on_reject(@reason) if @state == :rejected
+    @children << child
+  end
+
+  child
+end
+
+
+ +
+

+ + + #zip(*promises) ⇒ Promise<Array> + + #zip(*promises, opts) ⇒ Promise<Array> + + + + + + +

+
+

Builds a promise that produces the result of self and others in an Array +and fails if any of them fails.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #zip(*promises) ⇒ Promise<Array> +
    +
    + + +
    +
    +
    +

    Parameters:

    + + + +
    +
  • + + +
  • + #zip(*promises, opts) ⇒ Promise<Array> +
    +
    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + others + + + (Array<Promise>) + + + +
    • + +
    • + + opts + + + (Hash) + + + + — +

      the configuration options

      +
      + +
    • + +
    + + + + + + +

    Options Hash (opts):

    +
      + +
    • + :executor + (Executor) + + + — default: + ImmediateExecutor.new + + + + —

      when set use the given Executor instance.

      +
      + +
    • + +
    • + :execute + (Boolean) + + + — default: + true + + + + —

      execute promise before returning

      +
      + +
    • + +
    + + + +
    +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+440
+441
+442
+
+
# File 'lib/concurrent-ruby/concurrent/promise.rb', line 440
+
+def zip(*others)
+  self.class.zip(self, *others)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises.html b/docs/1.1.10/Concurrent/Promises.html new file mode 100644 index 000000000..49a429cca --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises.html @@ -0,0 +1,3394 @@ + + + + + + + Module: Concurrent::Promises + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Promises + + + +

+
+ + + + +
+
Extended by:
+
FactoryMethods
+
+ + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb,
+ lib/concurrent-ruby-edge/concurrent/edge/channel.rb,
lib/concurrent-ruby-edge/concurrent/edge/promises.rb,
lib/concurrent-ruby-edge/concurrent/edge/old_channel_integration.rb
+
+
+ +
+ +

Overview

+
+

Promises is a new framework unifying former tools Concurrent::Future, +Concurrent::Promise, Concurrent::IVar, Concurrent::Event, +Concurrent.dataflow, Delay, and TimerTask of concurrent-ruby. It +extensively uses the new synchronization layer to make all the methods +lock-free (with the exception of obviously blocking operations like #wait, +#value, etc.). As a result it lowers danger of deadlocking and offers +better performance.

+ +

It provides similar tools as other promise libraries do, users coming from +other languages and other promise libraries will find the same tools here +(probably named differently though). The naming conventions were borrowed +heavily from JS promises.

+ +

This framework, however, is not just a re-implementation of other promise +library, it draws inspiration from many other promise libraries, adds new +ideas, and is integrated with other abstractions like actors and channels.

+ +

Therefore it is likely that user will find a suitable solution for a problem in +this framework. If the problem is simple user can pick one suitable +abstraction, e.g. just promises or actors. If the problem is complex user can +combine parts (promises, channels, actors) which were designed to work together +well to a solution. Rather than having to combine fragilely independent tools.

+ +

This framework allows its users to:

+ +
    +
  • Process tasks asynchronously
  • +
  • Chain, branch, and zip the asynchronous tasks together + +
      +
    • Therefore, to create directed acyclic graph (hereafter DAG) of tasks
    • +
  • +
  • Create delayed tasks (or delayed DAG of tasks)
  • +
  • Create scheduled tasks (or delayed DAG of tasks)
  • +
  • Deal with errors through rejections
  • +
  • Reduce danger of deadlocking
  • +
  • Control the concurrency level of tasks
  • +
  • Simulate thread-like processing without occupying threads + +
      +
    • It allows to create tens of thousands simulations on one thread +pool
    • +
    • It works well on all Ruby implementations
    • +
  • +
  • Use actors to maintain isolated states and to seamlessly combine +it with promises
  • +
  • Build parallel processing stream system with back +pressure (parts, which are not keeping up, signal to the other parts of the +system to slow down).
  • +
+ +

The guide is best place to start with promises.

+ +

Main classes

+ +

The main public user-facing classes are Event and +Future which share common ancestor +AbstractEventFuture.

+ +

AbstractEventFuture:

+ +
+

Common ancestor of Event and Future classes, many shared methods are defined here.

+
+ +

Event:

+ +
+

Represents an event which will happen in future (will be resolved). The event is either +pending or resolved. It should be always resolved. Use Future to communicate rejections and +cancellation.

+
+ +

Future:

+ +
+

Represents a value which will become available in future. May reject with a reason instead, +e.g. when the tasks raises an exception.

+
+

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: FactoryMethods, Resolvable + + + + Classes: AbstractEventFuture, Channel, Event, Future, ResolvableEvent, ResolvableFuture + + +

+ + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + + + + + + + + + +
+

Class Method Details

+ + +
+

+ + .any_event(*futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #any_event_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + .any_event_on(default_executor, *futures_and_or_events) ⇒ Event + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates new event which becomes resolved after first of the futures_and_or_events resolves. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+
+ +
+

+ + .any_fulfilled_future(*futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #any_fulfilled_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + .any_fulfilled_future_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates new future which is resolved after first of futures_and_or_events is fulfilled. +Its result equals result of the first resolved future or if all futures_and_or_events reject, +it has reason of the last resolved future. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + .any_resolved_future(*futures_and_or_events) ⇒ Future + + + + Also known as: + any + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #any_resolved_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + .any_resolved_future_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates new future which is resolved after first futures_and_or_events is resolved. +Its result equals result of the first resolved future. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + .default_executorExecutor, :io, :fast + + + + + + + Originally defined in module + FactoryMethods::Configuration + + +

+
+

Returns the executor which is used when none is supplied +to a factory method. The method can be overridden in the receivers of +include FactoryMethod.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Executor, :io, :fast) + + + + — +

    the executor which is used when none is supplied +to a factory method. The method can be overridden in the receivers of +include FactoryMethod

    +
    + +
  • + +
+ +
+
+ +
+

+ + .delay(*args, &task) ⇒ Future, Event + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #delay_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+
+ +
+

+ + + #delay_on(default_executor, *args) {|*args| ... } ⇒ Future + + #delay_on(default_executor) ⇒ Event + + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates new event or future which is resolved only after it is touched, +see AbstractEventFuture#touch.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #delay_on(default_executor, *args) {|*args| ... } ⇒ Future +
    +
    +

    If task is provided it returns a Concurrent::Promises::Future representing the result of the task.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + args + + + (Object) + + + + — +

      arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

      +
      + +
    • + +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Returns:

    + +

    Returns:

    +
      + +
    • + + + (Future) + + + +
    • + +
    + +
    +
  • + + +
  • + #delay_on(default_executor) ⇒ Event +
    +
    +

    If no task is provided, it returns an Event

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ + +
+
+ +
+

+ + .fulfilled_future(value, default_executor = self.default_executor) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates resolved future with will be fulfilled with the given value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + .future(*args, &task) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + .future_on(default_executor, *args) {|*args| ... } ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Constructs new Future which will be resolved after block is evaluated on default executor. +Evaluation begins immediately.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (*args) + + + + — +

    to the task.

    +
    + +
  • + +
+

Yield Returns:

+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + + #make_future(nil, default_executor = self.default_executor) ⇒ Event + + #make_future(a_future, default_executor = self.default_executor) ⇒ Future + + #make_future(an_event, default_executor = self.default_executor) ⇒ Event + + #make_future(exception, default_executor = self.default_executor) ⇒ Future + + #make_future(value, default_executor = self.default_executor) ⇒ Future + + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

General constructor. Behaves differently based on the argument's type. It's provided for convenience +but it's better to be explicit.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #make_future(nil, default_executor = self.default_executor) ⇒ Event +
    +
    +

    Returns resolved event.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + nil + + + (nil) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + + — +

      resolved event.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(a_future, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a future which will be resolved when a_future is.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + a_future + + + (Future) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a future which will be resolved when a_future is.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(an_event, default_executor = self.default_executor) ⇒ Event +
    +
    +

    Returns an event which will be resolved when an_event is.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + an_event + + + (Event) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + + — +

      an event which will be resolved when an_event is.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(exception, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a rejected future with the exception as its reason.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + exception + + + (Exception) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a rejected future with the exception as its reason.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(value, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a fulfilled future with the value.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + value + + + (Object) + + + + — +

      when none of the above overloads fits

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a fulfilled future with the value.

      +
      + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +

See Also:

+
    + +
  • resolved_event, fulfilled_future
  • + +
+ +
+
+ +
+

+ + .rejected_future(reason, default_executor = self.default_executor) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates resolved future with will be rejected with the given reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + reason + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + .resolvable_eventResolvableEvent + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #resolvable_event_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+
+ +
+

+ + .resolvable_event_on(default_executor = self.default_executor) ⇒ ResolvableEvent + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Created resolvable event, user is responsible for resolving the event once by +ResolvableEvent#resolve.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +
+
+ +
+

+ + .resolvable_futureResolvableFuture + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #resolvable_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+
+ +
+

+ + .resolvable_future_on(default_executor = self.default_executor) ⇒ ResolvableFuture + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates resolvable future, user is responsible for resolving the future once by +ResolvableFuture#resolve, ResolvableFuture#fulfill, +or ResolvableFuture#reject

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +
+
+ +
+

+ + .resolved_event(default_executor = self.default_executor) ⇒ Event + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates resolved event.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+
+ +
+

+ + .resolved_future(fulfilled, value, reason, default_executor = self.default_executor) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates resolved future with will be either fulfilled with the given value or rejection with +the given reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + fulfilled + + + (true, false) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
  • + + reason + + + (Object) + + + +
  • + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + .schedule(intended_time, *args, &task) ⇒ Future, Event + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #schedule_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+
+ +
+

+ + + #schedule_on(default_executor, intended_time, *args) {|*args| ... } ⇒ Future + + #schedule_on(default_executor, intended_time) ⇒ Event + + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates new event or future which is resolved in intended_time.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #schedule_on(default_executor, intended_time, *args) {|*args| ... } ⇒ Future +
    +
    +

    If task is provided it returns a Concurrent::Promises::Future representing the result of the task.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + args + + + (Object) + + + + — +

      arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

      +
      + +
    • + +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Returns:

    + +

    Returns:

    +
      + +
    • + + + (Future) + + + +
    • + +
    + +
    +
  • + + +
  • + #schedule_on(default_executor, intended_time) ⇒ Event +
    +
    +

    If no task is provided, it returns an Event

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + intended_time + + + (Numeric, Time) + + + + — +

    Numeric means to run in intended_time seconds. +Time means to run on intended_time.

    +
    + +
  • + +
+ + +
+
+ +
+

+ + .zip_events(*futures_and_or_events) ⇒ Event + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #zip_events_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + .zip_events_on(default_executor, *futures_and_or_events) ⇒ Event + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates new event which is resolved after all futures_and_or_events are resolved. +(Future is resolved when fulfilled or rejected.)

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+
+ +
+

+ + .zip_futures(*futures_and_or_events) ⇒ Future + + + + Also known as: + zip + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Shortcut of #zip_futures_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + .zip_futures_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+

Creates new future which is resolved after all futures_and_or_events are resolved. +Its value is array of zipped future values. Its reason is array of reasons for rejection. +If there is an error it rejects. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + .zip_futures_over(enumerable, &future_factory) ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Shortcut of #zip_futures_over_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + .zip_futures_over_on(default_executor, enumerable) {|element| ... } ⇒ Future + + + + + + + Originally defined in module + FactoryMethods + + +

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Creates new future which is resolved after all the futures created by future_factory from +enumerable elements are resolved. Simplified it does: +zip(*enumerable.map { |e| future e, &future_factory })

+ + +
+
+
+ +
+

Examples:

+ + +
# `#succ` calls are executed in parallel
+zip_futures_over_on(:io, [1, 2], &:succ).value! # => [2, 3]
+ +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + enumerable + + + (Enumerable) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    a task to be executed in future

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + element + + + (Object) + + + + — +

    from enumerable

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    a value of the future

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/AbstractEventFuture.html b/docs/1.1.10/Concurrent/Promises/AbstractEventFuture.html new file mode 100644 index 000000000..eb613c6cd --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/AbstractEventFuture.html @@ -0,0 +1,1980 @@ + + + + + + + Class: Concurrent::Promises::AbstractEventFuture + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Promises::AbstractEventFuture + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb
+
+ +
+ +

Overview

+
+

Common ancestor of Event and Future classes, many shared methods are defined here.

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

Event, Future

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #chain(*args, &task) ⇒ Future + + + + + +

+
+

Shortcut of #chain_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+594
+595
+596
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 594
+
+def chain(*args, &task)
+  chain_on @DefaultExecutor, *args, &task
+end
+
+
+ +
+

+ + + #an_event.chain_on(executor, *args) {|*args| ... } ⇒ Future + + #a_future.chain_on(executor, *args) {|fulfilled, value, reason, *args| ... } ⇒ Future + + + + + + +

+
+

Chains the task to be executed asynchronously on executor after it is resolved.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #an_event.chain_on(executor, *args) {|*args| ... } ⇒ Future +
    +
    + + +
    +
    +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #a_future.chain_on(executor, *args) {|fulfilled, value, reason, *args| ... } ⇒ Future +
    +
    + + +
    +
    +
    + +

    Yields:

    +
      + +
    • + + + (fulfilled, value, reason, *args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Parameters:

    +
      + +
    • + + fulfilled + + + (true, false) + + + +
    • + +
    • + + value + + + (Object) + + + +
    • + +
    • + + reason + + + (Object) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. The task is executed on it, default executor remains unchanged.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yield Returns:

+
    + +
  • + + + + + + + +

    will become result of the returned Future. +Its returned value becomes Future#value fulfilling it, +raised exception becomes Future#reason rejecting it.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+612
+613
+614
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 612
+
+def chain_on(executor, *args, &task)
+  ChainPromise.new_blocked_by1(self, @DefaultExecutor, executor, args, &task).future
+end
+
+
+ +
+

+ + #chain_resolvable(resolvable) ⇒ self + + + + Also known as: + tangle + + + + +

+
+

Resolves the resolvable when receiver is resolved.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolvable + + + (Resolvable) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+627
+628
+629
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 627
+
+def chain_resolvable(resolvable)
+  on_resolution! { resolvable.resolve_with internal_state }
+end
+
+
+ +
+

+ + #default_executorExecutor + + + + + +

+
+

Returns default executor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Executor) + + + + — +

    default executor

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+588
+589
+590
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 588
+
+def default_executor
+  @DefaultExecutor
+end
+
+
+ +
+

+ + #internal_stateObject + + + + + +

+
+

Returns The internal_state.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    The internal_state.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+513
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 513
+
+attr_atomic(:internal_state)
+
+
+ +
+

+ + #on_resolution(*args, &callback) ⇒ self + + + + + +

+
+

Shortcut of #on_resolution_using with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+635
+636
+637
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 635
+
+def on_resolution(*args, &callback)
+  on_resolution_using @DefaultExecutor, *args, &callback
+end
+
+
+ +
+

+ + + #an_event.on_resolution!(*args) {|*args| ... } ⇒ self + + #a_future.on_resolution!(*args) {|fulfilled, value, reason, *args| ... } ⇒ self + + + + + + +

+
+

Stores the callback to be executed synchronously on resolving thread after it is +resolved.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #an_event.on_resolution!(*args) {|*args| ... } ⇒ self +
    +
    + + +
    +
    +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the callback.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #a_future.on_resolution!(*args) {|fulfilled, value, reason, *args| ... } ⇒ self +
    +
    + + +
    +
    +
    + +

    Yields:

    +
      + +
    • + + + (fulfilled, value, reason, *args) + + + + — +

      to the callback.

      +
      + +
    • + +
    +

    Yield Parameters:

    +
      + +
    • + + fulfilled + + + (true, false) + + + +
    • + +
    • + + value + + + (Object) + + + +
    • + +
    • + + reason + + + (Object) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yield Returns:

+
    + +
  • + + + + + + + +

    is forgotten.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+653
+654
+655
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 653
+
+def on_resolution!(*args, &callback)
+  add_callback :callback_on_resolution, args, callback
+end
+
+
+ +
+

+ + + #an_event.on_resolution_using(executor, *args) {|*args| ... } ⇒ self + + #a_future.on_resolution_using(executor, *args) {|fulfilled, value, reason, *args| ... } ⇒ self + + + + + + +

+
+

Stores the callback to be executed asynchronously on executor after it is resolved.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #an_event.on_resolution_using(executor, *args) {|*args| ... } ⇒ self +
    +
    + + +
    +
    +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the callback.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #a_future.on_resolution_using(executor, *args) {|fulfilled, value, reason, *args| ... } ⇒ self +
    +
    + + +
    +
    +
    + +

    Yields:

    +
      + +
    • + + + (fulfilled, value, reason, *args) + + + + — +

      to the callback.

      +
      + +
    • + +
    +

    Yield Parameters:

    +
      + +
    • + + fulfilled + + + (true, false) + + + +
    • + +
    • + + value + + + (Object) + + + +
    • + +
    • + + reason + + + (Object) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. The task is executed on it, default executor remains unchanged.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yield Returns:

+
    + +
  • + + + + + + + +

    is forgotten.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+671
+672
+673
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 671
+
+def on_resolution_using(executor, *args, &callback)
+  add_callback :async_callback_on_resolution, executor, args, callback
+end
+
+
+ +
+

+ + #pending?Boolean + + + + + +

+
+

Is it in pending state?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+547
+548
+549
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 547
+
+def pending?
+  !internal_state.resolved?
+end
+
+
+ +
+

+ + #resolved?Boolean + + + + + +

+
+

Is it in resolved state?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+553
+554
+555
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 553
+
+def resolved?
+  internal_state.resolved?
+end
+
+
+ +
+

+ + + #an_event.state:pending, :resolved + + #a_future.state:pending, :fulfilled, :rejected + + + + + + +

+
+

Returns its state.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #an_event.state:pending, :resolved +
    +
    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (:pending, :resolved) + + + +
    • + +
    + +
    +
  • + + +
  • + #a_future.state:pending, :fulfilled, :rejected +
    +
    +

    Both :fulfilled, :rejected implies :resolved.

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (:pending, :fulfilled, :rejected) + + + +
    • + +
    + +
    +
  • + +
+ +

Returns:

+
    + +
  • + + + (Symbol) + + + +
  • + +
+ +
+ + + + +
+
+
+
+541
+542
+543
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 541
+
+def state
+  internal_state.to_sym
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    Short string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+617
+618
+619
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 617
+
+def to_s
+  format '%s %s>', super[0..-2], state
+end
+
+
+ +
+

+ + #touchself + + + + + +

+
+

Propagates touch. Requests all the delayed futures, which it depends on, to be +executed. This method is called by any other method requiring resolved state, like #wait.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+560
+561
+562
+563
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 560
+
+def touch
+  @Promise.touch
+  self
+end
+
+
+ +
+

+ + #wait(timeout = nil) ⇒ self, true, false + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until the Future is resolved. +Be careful it can deadlock. Try to chain instead.

+
+
+ +

Wait (block the Thread) until receiver is #resolved?. +Calls AbstractEventFuture#touch.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, true, false) + + + + — +

    self implies timeout was not used, true implies timeout was used +and it was resolved, false implies it was not resolved within timeout.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+576
+577
+578
+579
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 576
+
+def wait(timeout = nil)
+  result = wait_until_resolved(timeout)
+  timeout ? result : self
+end
+
+
+ +
+

+ + #with_default_executor(executor) ⇒ AbstractEventFuture + + + + + +

+
+
+ This method is abstract. +
+
+

Crates new object with same class with the executor set as its new default executor. +Any futures depending on it will use the new default executor.

+ + +
+
+
+ +

Returns:

+ +

Raises:

+
    + +
  • + + + (NotImplementedError) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+681
+682
+683
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 681
+
+def with_default_executor(executor)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/Channel.html b/docs/1.1.10/Concurrent/Promises/Channel.html new file mode 100644 index 000000000..e57f3d338 --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/Channel.html @@ -0,0 +1,3519 @@ + + + + + + + Class: Concurrent::Promises::Channel + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Promises::Channel + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/channel.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

A first in first out channel that accepts messages with push family of methods and returns +messages with pop family of methods. +Pop and push operations can be represented as futures, see #pop_op and #push_op. +The capacity of the channel can be limited to support back pressure, use capacity option in #initialize. +#pop method blocks ans #pop_op returns pending future if there is no message in the channel. +If the capacity is limited the #push method blocks and #push_op returns pending future.

+ +

Examples

+ +

Let's start by creating a channel with a capacity of 2 messages.

+ +
ch = Concurrent::Promises::Channel.new 2
+# => #
+
+ +

We push 3 messages, +then it can be observed that the last thread pushing is sleeping +since the channel is full.

+ +
threads = Array.new(3) { |i| Thread.new { ch.push message: i } } 
+sleep 0.01 # let the threads run
+threads
+# => [#,
+#     #,
+#     #]
+
+ +

When message is popped the last thread continues and finishes as well.

+ +
ch.pop                                   # => {:message=>1}
+threads.map(&:join)
+# => [#,
+#     #,
+#     #]
+
+ +

Same principle applies to popping as well. +There are now 2 messages int he channel. +Lets create 3 threads trying to pop a message, +one will be blocked until new messages is pushed.

+ +
threads = Array.new(3) { |i| Thread.new { ch.pop } } 
+sleep 0.01 # let the threads run
+threads 
+# => [#,
+#     #,
+#     #]
+ch.push message: 3
+# => #
+threads.map(&:value)
+# => [{:message=>0}, {:message=>2}, {:message=>3}]
+
+ +

Promises integration

+ +

However this channel is implemented to integrate with promises +therefore all operations can be represented as futures.

+ +
ch = Concurrent::Promises::Channel.new 2
+# => #
+push_operations = Array.new(3) { |i| ch.push_op message: i }
+# => [#>,
+#     #>,
+#     #]
+
+ +
+

We do not have to sleep here letting the futures execute as Threads. +Since there is capacity for 2 messages the Promises are immediately resolved +without ever allocating a Thread to execute. +Push and pop operations are often more efficient. +The remaining pending push operation will also never require another thread, +instead it will resolve when a message is popped from the channel +making a space for a new message.

+
+ +
ch.pop_op.value!                         # => {:message=>0}
+push_operations.map(&:value!)
+# => [#,
+#     #,
+#     #]
+
+pop_operations = Array.new(3) { |i| ch.pop_op }
+# => [#1}>,
+#     #2}>,
+#     #]
+ch.push message: 3 # (push|pop) can be freely mixed with (push_o|pop_op)
+pop_operations.map(&:value) 
+# => [{:message=>1}, {:message=>2}, {:message=>3}]
+
+ +

Selecting over channels

+ +

A selection over channels can be created with the .select_channel factory method. It +will be fulfilled with a first message available in any of the channels. It +returns a pair to be able to find out which channel had the message available.

+ +
ch1    = Concurrent::Promises::Channel.new 2
+# => #
+ch2    = Concurrent::Promises::Channel.new 2
+# => #
+ch1.push 1 
+# => #
+ch2.push 2 
+# => #
+
+Concurrent::Promises::Channel.select([ch1, ch2])
+# => [#, 1]
+ch1.select(ch2)
+# => [#, 2]
+
+Concurrent::Promises.future { 3 + 4 }.then_channel_push(ch1)
+# => #
+Concurrent::Promises::Channel. 
+    # or `ch1.select_op(ch2)` would be equivalent
+    select_op([ch1, ch2]).
+    then('got number %03d from ch%d') { |(channel, value), format| 
+      format format, value, [ch1, ch2].index(channel).succ
+    }.value!                             # => "got number 007 from ch1"
+
+ +

try_ variants

+ +

All blocking operations (#pop, #push, #select) have non-blocking variant +with try_ prefix. +They always return immediately and indicate either success or failure.

+ +
ch
+# => #
+ch.try_push 1                            # => true
+ch.try_push 2                            # => true
+ch.try_push 3                            # => false
+ch.try_pop                               # => 1
+ch.try_pop                               # => 2
+ch.try_pop                               # => nil
+
+ +

Timeouts

+ +

All blocking operations (#pop, #push, #select) have a timeout option. +Similar to try_ variants it will indicate success or timing out, +when the timeout option is used.

+ +
ch
+# => #
+ch.push 1, 0.01                          # => true
+ch.push 2, 0.01                          # => true
+ch.push 3, 0.01                          # => false
+ch.pop 0.01                              # => 1
+ch.pop 0.01                              # => 2
+ch.pop 0.01                              # => nil
+
+ +

Backpressure

+ +

Most importantly the channel can be used to create systems with backpressure. +A self adjusting system where the producers will slow down +if the consumers are not keeping up.

+ +
channel = Concurrent::Promises::Channel.new 2
+# => #
+log     = Concurrent::Array.new          # => []
+
+producers = Array.new 2 do |i|
+  Thread.new(i) do |i|
+    4.times do |j|
+      log.push format "producer %d pushing %d", i, j      
+      channel.push [i, j]      
+    end
+  end
+end
+# => [#,
+#     #]
+
+consumers = Array.new 4 do |i|
+  Thread.new(i) do |consumer|
+    2.times do |j|
+      from, message = channel.pop
+      log.push format "consumer %d got %d. payload %d from producer %d", 
+                      consumer, j, message, from       
+      do_stuff      
+    end
+  end
+end
+# => [#,
+#     #,
+#     #,
+#     #]
+
+# wait for all to finish
+producers.map(&:join)
+# => [#,
+#     #]
+consumers.map(&:join)
+# => [#,
+#     #,
+#     #,
+#     #]
+# investigate log
+log
+# => ["producer 0 pushing 0",
+#     "producer 0 pushing 1",
+#     "producer 0 pushing 2",
+#     "producer 1 pushing 0",
+#     "consumer 0 got 0. payload 0 from producer 0",
+#     "producer 0 pushing 3",
+#     "consumer 1 got 0. payload 1 from producer 0",
+#     "consumer 2 got 0. payload 2 from producer 0",
+#     "consumer 3 got 0. payload 0 from producer 1",
+#     "producer 1 pushing 1",
+#     "producer 1 pushing 2",
+#     "consumer 1 got 1. payload 3 from producer 0",
+#     "producer 1 pushing 3",
+#     "consumer 2 got 1. payload 1 from producer 1",
+#     "consumer 3 got 1. payload 2 from producer 1",
+#     "consumer 0 got 1. payload 3 from producer 1"]
+
+ +

The producers are much faster than consumers +(since they do_stuff which takes some time)
+but as it can be seen from the log they fill the channel +and then they slow down +until there is space available in the channel.

+ +

If permanent allocation of threads to the producers and consumers has to be avoided, +the threads can be replaced with promises +that run a thread pool.

+ +
channel = Concurrent::Promises::Channel.new 2
+# => #
+log     = Concurrent::Array.new          # => []
+
+def produce(channel, log, producer, i)
+  log.push format "producer %d pushing %d", producer, i      
+  channel.push_op([producer, i]).then do
+    i + 1 < 4 ? produce(channel, log, producer, i + 1) : :done    
+  end      
+end                                      # => :produce
+
+def consume(channel, log, consumer, i)
+  channel.pop_op.then(consumer, i) do |(from, message), consumer, i|
+    log.push format "consumer %d got %d. payload %d from producer %d", 
+                    consumer, i, message, from       
+    do_stuff
+    i + 1 < 2 ? consume(channel, log, consumer, i + 1) : :done       
+  end
+end                                      # => :consume
+
+producers = Array.new 2 do |i|
+  Concurrent::Promises.future(channel, log, i) { |*args| produce *args, 0 }.run
+end
+# => [#,
+#     #]
+
+consumers = Array.new 4 do |i|
+  Concurrent::Promises.future(channel, log, i) { |*args| consume *args, 0 }.run
+end
+# => [#,
+#     #,
+#     #,
+#     #]
+
+# wait for all to finish
+producers.map(&:value!)                  # => [:done, :done]
+consumers.map(&:value!)                  # => [:done, :done, :done, :done]
+# investigate log
+log
+# => ["producer 0 pushing 0",
+#     "producer 1 pushing 0",
+#     "producer 1 pushing 1",
+#     "consumer 1 got 0. payload 0 from producer 1",
+#     "consumer 2 got 0. payload 1 from producer 1",
+#     "producer 0 pushing 1",
+#     "producer 0 pushing 2",
+#     "producer 0 pushing 3",
+#     "producer 1 pushing 2",
+#     "consumer 0 got 0. payload 0 from producer 0",
+#     "consumer 3 got 0. payload 1 from producer 0",
+#     "producer 1 pushing 3",
+#     "consumer 2 got 1. payload 2 from producer 0",
+#     "consumer 1 got 1. payload 3 from producer 0",
+#     "consumer 3 got 1. payload 3 from producer 1",
+#     "consumer 0 got 1. payload 2 from producer 1"]
+
+ +

Synchronization of workers by passing a value

+ +

If the capacity of the channel is zero +then any push operation will succeed only +when there is a matching pop operation +which can take the message. +The operations have to be paired to succeed.

+ +
channel = Concurrent::Promises::Channel.new 0
+# => #
+thread = Thread.new { channel.pop }; sleep 0.01 
+# allow the thread to go to sleep
+thread
+# => #
+# succeeds because there is matching pop operation waiting in the thread 
+channel.try_push(:v1)                    # => true
+# remains pending, since there is no matching operation 
+push = channel.push_op(:v2)
+# => #
+thread.value                             # => :v1
+# the push operation resolves as a pairing pop is called
+channel.pop                              # => :v2
+push
+# => #>
+
+

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
UNLIMITED_CAPACITY = +
+
+

Default capacity of the Channel, makes it accept unlimited number of messages.

+ + +
+
+
+ + +
+
+
::Object.new
+ +
ANY = +
+
+

An object which matches anything (with #===)

+ + +
+
+
+ + +
+
+
Object.new.tap do |any|
+  def any.===(other)
+    true
+  end
+
+  def any.to_s
+    'ANY'
+  end
+end
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(capacity = UNLIMITED_CAPACITY) ⇒ Channel + + + + + +

+
+

Create channel.

+ + +
+
+
+

Parameters:

+
    + +
  • + + capacity + + + (Integer, UNLIMITED_CAPACITY) + + + (defaults to: UNLIMITED_CAPACITY) + + + — +

    the maximum number of messages which can be stored in the channel.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+61
+62
+63
+64
+65
+66
+67
+68
+69
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 61
+
+def initialize(capacity = UNLIMITED_CAPACITY)
+  super()
+  @Capacity = capacity
+  @Mutex    = Mutex.new
+  # TODO (pitr-ch 28-Jan-2019): consider linked lists or other data structures for following attributes, things are being deleted from the middle
+  @Probes      = []
+  @Messages    = []
+  @PendingPush = []
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .select(channels, timeout = nil) ⇒ ::Array(Channel, Object), nil + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (::Array(Channel, Object), nil) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+319
+320
+321
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 319
+
+def select(channels, timeout = nil)
+  channels.first.select(channels[1..-1], timeout)
+end
+
+
+ +
+

+ + .select_matching(matcher, channels, timeout = nil) ⇒ ::Array(Channel, Object), nil + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (::Array(Channel, Object), nil) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+337
+338
+339
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 337
+
+def select_matching(matcher, channels, timeout = nil)
+  channels.first.select_matching(matcher, channels[1..-1], timeout)
+end
+
+
+ +
+

+ + .select_op(channels, probe = Promises.resolvable_future) ⇒ Future(::Array(Channel, Object)) + + + + + +

+
+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+313
+314
+315
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 313
+
+def select_op(channels, probe = Promises.resolvable_future)
+  channels.first.select_op(channels[1..-1], probe)
+end
+
+
+ +
+

+ + .select_op_matching(matcher, channels, probe = Promises.resolvable_future) ⇒ Future(::Array(Channel, Object)) + + + + + +

+
+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+331
+332
+333
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 331
+
+def select_op_matching(matcher, channels, probe = Promises.resolvable_future)
+  channels.first.select_op_matching(matcher, channels[1..-1], probe)
+end
+
+
+ +
+

+ + .try_select(channels) ⇒ ::Array(Channel, Object) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (::Array(Channel, Object)) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+307
+308
+309
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 307
+
+def try_select(channels)
+  channels.first.try_select(channels[1..-1])
+end
+
+
+ +
+

+ + .try_select_matching(matcher, channels) ⇒ ::Array(Channel, Object) + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (::Array(Channel, Object)) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+325
+326
+327
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 325
+
+def try_select_matching(matcher, channels)
+  channels.first.try_select_matching(matcher, channels[1..-1])
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #capacityInteger + + + + + +

+
+

Returns Maximum capacity of the Channel.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    Maximum capacity of the Channel.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+292
+293
+294
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 292
+
+def capacity
+  @Capacity
+end
+
+
+ +
+

+ + #peek(no_value = nil) ⇒ Object, no_value + + + + + +

+
+

Behaves as #try_pop but it does not remove the message from the channel

+ + +
+
+
+

Parameters:

+
    + +
  • + + no_value + + + (Object) + + + (defaults to: nil) + + + — +

    returned when there is no message available

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, no_value) + + + + — +

    message or nil when there is no message

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+206
+207
+208
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 206
+
+def peek(no_value = nil)
+  peek_matching ANY, no_value
+end
+
+
+ +
+

+ + #peek_matching(matcher, no_value = nil) ⇒ Object, no_value + + + + + +

+
+

Behaves as #try_pop but it does not remove the message from the channel

+ + +
+
+
+

Parameters:

+
    + +
  • + + no_value + + + (Object) + + + (defaults to: nil) + + + — +

    returned when there is no message available

    +
    + +
  • + +
  • + + matcher + + + (#===) + + + + — +

    only consider message which matches matcher === a_message

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, no_value) + + + + — +

    message or nil when there is no message

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+212
+213
+214
+215
+216
+217
+218
+219
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 212
+
+def peek_matching(matcher, no_value = nil)
+  @Mutex.synchronize do
+    message = ns_shift_message matcher, false
+    return message if message != NOTHING
+    message = ns_consume_pending_push matcher, false
+    return message != NOTHING ? message : no_value
+  end
+end
+
+
+ +
+

+ + #pop(timeout = nil, timeout_value = nil) ⇒ Object, nil + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until it can continue. +Be careful it can deadlock.

+
+
+ +

Blocks current thread until a message is available in the channel for popping.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
  • + + timeout_value + + + (Object) + + + (defaults to: nil) + + + — +

    a value returned by the method when it times out

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    message or nil when timed out

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+174
+175
+176
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 174
+
+def pop(timeout = nil, timeout_value = nil)
+  pop_matching ANY, timeout, timeout_value
+end
+
+
+ +
+

+ + #pop_matching(matcher, timeout = nil, timeout_value = nil) ⇒ Object, nil + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until it can continue. +Be careful it can deadlock.

+
+
+ +

Blocks current thread until a message is available in the channel for popping.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
  • + + timeout_value + + + (Object) + + + (defaults to: nil) + + + — +

    a value returned by the method when it times out

    +
    + +
  • + +
  • + + matcher + + + (#===) + + + + — +

    only consider message which matches matcher === a_message

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +

    message or nil when timed out

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 180
+
+def pop_matching(matcher, timeout = nil, timeout_value = nil)
+  # TODO (pitr-ch 27-Jan-2019): should it try to match pending pushes if it fails to match in the buffer? Maybe only if the size is zero. It could be surprising if it's used as a throttle it might be expected that it will not pop if buffer is full of messages which di not match, it might it expected it will block until the message is added to the buffer
+  # that it returns even if the buffer is full. User might expect that it has to be in the buffer first.
+  probe = @Mutex.synchronize do
+    message = ns_shift_message matcher
+    if message == NOTHING
+      message = ns_consume_pending_push matcher
+      return message if message != NOTHING
+    else
+      new_message = ns_consume_pending_push ANY
+      @Messages.push new_message unless new_message == NOTHING
+      return message
+    end
+
+    probe = Promises.resolvable_future
+    @Probes.push probe, false, matcher
+    probe
+  end
+
+  probe.value!(timeout, timeout_value, [true, timeout_value, nil])
+end
+
+
+ +
+

+ + #pop_op(probe = Promises.resolvable_future) ⇒ Future(Object) + + + + + +

+
+

Returns a future witch will become fulfilled with a value from the channel when one is available. +If it is later waited on the operation with a timeout e.g.channel.pop_op.wait(1) +it will not prevent the channel to fulfill the operation later after the timeout. +The operation has to be either processed later

+ +
pop_op = channel.pop_op
+if pop_op.wait(1)
+  process_message pop_op.value
+else
+  pop_op.then { |message| log_unprocessed_message message }
+end
+
+ +

or the operation can be prevented from completion after timing out by using +channel.pop_op.wait(1, [true, nil, nil]). +It will fulfill the operation on timeout preventing channel from doing the operation, +e.g. popping a message.

+ + +
+
+
+

Parameters:

+
    + +
  • + + probe + + + (ResolvableFuture) + + + (defaults to: Promises.resolvable_future) + + + — +

    the future which will be fulfilled with a channel value

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future(Object)) + + + + — +

    the probe, its value will be the message when available.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+157
+158
+159
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 157
+
+def pop_op(probe = Promises.resolvable_future)
+  @Mutex.synchronize { ns_pop_op(ANY, probe, false) }
+end
+
+
+ +
+

+ + #pop_op_matching(matcher, probe = Promises.resolvable_future) ⇒ Future(Object) + + + + + +

+
+

Returns a future witch will become fulfilled with a value from the channel when one is available. +If it is later waited on the operation with a timeout e.g.channel.pop_op.wait(1) +it will not prevent the channel to fulfill the operation later after the timeout. +The operation has to be either processed later

+ +
pop_op = channel.pop_op
+if pop_op.wait(1)
+  process_message pop_op.value
+else
+  pop_op.then { |message| log_unprocessed_message message }
+end
+
+ +

or the operation can be prevented from completion after timing out by using +channel.pop_op.wait(1, [true, nil, nil]). +It will fulfill the operation on timeout preventing channel from doing the operation, +e.g. popping a message.

+ + +
+
+
+

Parameters:

+
    + +
  • + + probe + + + (ResolvableFuture) + + + (defaults to: Promises.resolvable_future) + + + — +

    the future which will be fulfilled with a channel value

    +
    + +
  • + +
  • + + matcher + + + (#===) + + + + — +

    only consider message which matches matcher === a_message

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future(Object)) + + + + — +

    the probe, its value will be the message when available.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+163
+164
+165
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 163
+
+def pop_op_matching(matcher, probe = Promises.resolvable_future)
+  @Mutex.synchronize { ns_pop_op(matcher, probe, false) }
+end
+
+
+ +
+

+ + #push(message, timeout = nil) ⇒ self, true, false + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until it can continue. +Be careful it can deadlock.

+
+
+ +

Blocks current thread until the message is pushed into the channel.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, true, false) + + + + — +

    self implies timeout was not used, true implies timeout was used +and it was pushed, false implies it was not pushed within timeout.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 117
+
+def push(message, timeout = nil)
+  pushed_op = @Mutex.synchronize do
+    return timeout ? true : self if ns_try_push(message)
+
+    pushed = Promises.resolvable_future
+    # TODO (pitr-ch 06-Jan-2019): clear timed out pushes in @PendingPush, null messages
+    @PendingPush.push message, pushed
+    pushed
+  end
+
+  result = pushed_op.wait!(timeout, [true, self, nil])
+  result == pushed_op ? self : result
+end
+
+
+ +
+

+ + #push_op(message) ⇒ ResolvableFuture(self) + + + + + +

+
+

Returns future which will fulfill when the message is pushed to the channel. +If it is later waited on the operation with a timeout e.g.channel.pop_op.wait(1) +it will not prevent the channel to fulfill the operation later after the timeout. +The operation has to be either processed later

+ +
pop_op = channel.pop_op
+if pop_op.wait(1)
+  process_message pop_op.value
+else
+  pop_op.then { |message| log_unprocessed_message message }
+end
+
+ +

or the operation can be prevented from completion after timing out by using +channel.pop_op.wait(1, [true, nil, nil]). +It will fulfill the operation on timeout preventing channel from doing the operation, +e.g. popping a message.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 98
+
+def push_op(message)
+  @Mutex.synchronize do
+    if ns_try_push(message)
+      Promises.fulfilled_future self
+    else
+      pushed = Promises.resolvable_future
+      @PendingPush.push message, pushed
+      return pushed
+    end
+  end
+end
+
+
+ +
+

+ + #select(channels, timeout = nil) ⇒ ::Array(Channel, Object), nil + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until it can continue. +Be careful it can deadlock.

+
+
+ +

As #select_op but does not return future, +it block current thread instead until there is a message available +in the receiver or in any of the channels.

+ + +
+
+
+

Parameters:

+
    + +
  • + + channels + + + (Channel, ::Array<Channel>) + + + +
  • + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (::Array(Channel, Object), nil) + + + + — +

    message or nil when timed out

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+275
+276
+277
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 275
+
+def select(channels, timeout = nil)
+  select_matching ANY, channels, timeout
+end
+
+
+ +
+

+ + #select_matching(matcher, channels, timeout = nil) ⇒ ::Array(Channel, Object), nil + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until it can continue. +Be careful it can deadlock.

+
+
+ +

As #select_op but does not return future, +it block current thread instead until there is a message available +in the receiver or in any of the channels.

+ + +
+
+
+

Parameters:

+
    + +
  • + + channels + + + (Channel, ::Array<Channel>) + + + +
  • + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
  • + + matcher + + + (#===) + + + + — +

    only consider message which matches matcher === a_message

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (::Array(Channel, Object), nil) + + + + — +

    message or nil when timed out

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+281
+282
+283
+284
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 281
+
+def select_matching(matcher, channels, timeout = nil)
+  probe = select_op_matching(matcher, channels)
+  probe.value!(timeout, nil, [true, nil, nil])
+end
+
+
+ +
+

+ + #select_op(channels, probe = Promises.resolvable_future) ⇒ ResolvableFuture(::Array(Channel, Object)) + + + + + +

+
+

When message is available in the receiver or any of the provided channels +the future is fulfilled with a channel message pair. +The returned channel is the origin of the message. +If it is later waited on the operation with a timeout e.g.channel.pop_op.wait(1) +it will not prevent the channel to fulfill the operation later after the timeout. +The operation has to be either processed later

+ +
pop_op = channel.pop_op
+if pop_op.wait(1)
+  process_message pop_op.value
+else
+  pop_op.then { |message| log_unprocessed_message message }
+end
+
+ +

or the operation can be prevented from completion after timing out by using +channel.pop_op.wait(1, [true, nil, nil]). +It will fulfill the operation on timeout preventing channel from doing the operation, +e.g. popping a message.

+ + +
+
+
+

Parameters:

+
    + +
  • + + channels + + + (Channel, ::Array<Channel>) + + + +
  • + +
  • + + probe + + + (ResolvableFuture) + + + (defaults to: Promises.resolvable_future) + + + — +

    the future which will be fulfilled with the message

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (ResolvableFuture(::Array(Channel, Object))) + + + + — +

    a future which is fulfilled with +pair [channel, message] when one of the channels is available for reading

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+254
+255
+256
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 254
+
+def select_op(channels, probe = Promises.resolvable_future)
+  select_op_matching ANY, channels, probe
+end
+
+
+ +
+

+ + #select_op_matching(matcher, channels, probe = Promises.resolvable_future) ⇒ ResolvableFuture(::Array(Channel, Object)) + + + + + +

+
+

When message is available in the receiver or any of the provided channels +the future is fulfilled with a channel message pair. +The returned channel is the origin of the message. +If it is later waited on the operation with a timeout e.g.channel.pop_op.wait(1) +it will not prevent the channel to fulfill the operation later after the timeout. +The operation has to be either processed later

+ +
pop_op = channel.pop_op
+if pop_op.wait(1)
+  process_message pop_op.value
+else
+  pop_op.then { |message| log_unprocessed_message message }
+end
+
+ +

or the operation can be prevented from completion after timing out by using +channel.pop_op.wait(1, [true, nil, nil]). +It will fulfill the operation on timeout preventing channel from doing the operation, +e.g. popping a message.

+ + +
+
+
+

Parameters:

+
    + +
  • + + channels + + + (Channel, ::Array<Channel>) + + + +
  • + +
  • + + probe + + + (ResolvableFuture) + + + (defaults to: Promises.resolvable_future) + + + — +

    the future which will be fulfilled with the message

    +
    + +
  • + +
  • + + matcher + + + (#===) + + + + — +

    only consider message which matches matcher === a_message

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (ResolvableFuture(::Array(Channel, Object))) + + + + — +

    a future which is fulfilled with +pair [channel, message] when one of the channels is available for reading

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+260
+261
+262
+263
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 260
+
+def select_op_matching(matcher, channels, probe = Promises.resolvable_future)
+  [self, *channels].each { |ch| ch.partial_select_op matcher, probe }
+  probe
+end
+
+
+ +
+

+ + #sizeInteger + + + + + +

+
+

Returns The number of messages currently stored in the channel.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The number of messages currently stored in the channel.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+287
+288
+289
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 287
+
+def size
+  @Mutex.synchronize { @Messages.size }
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    Short string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+297
+298
+299
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 297
+
+def to_s
+  format '%s capacity taken %s of %s>', super[0..-2], size, @Capacity
+end
+
+
+ +
+

+ + #try_pop(no_value = nil) ⇒ Object, no_value + + + + + +

+
+

Pop a message from the channel if there is one available.

+ + +
+
+
+

Parameters:

+
    + +
  • + + no_value + + + (Object) + + + (defaults to: nil) + + + — +

    returned when there is no message available

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, no_value) + + + + — +

    message or nil when there is no message

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+135
+136
+137
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 135
+
+def try_pop(no_value = nil)
+  try_pop_matching ANY, no_value
+end
+
+
+ +
+

+ + #try_pop_matching(matcher, no_value = nil) ⇒ Object, no_value + + + + + +

+
+

Pop a message from the channel if there is one available.

+ + +
+
+
+

Parameters:

+
    + +
  • + + no_value + + + (Object) + + + (defaults to: nil) + + + — +

    returned when there is no message available

    +
    + +
  • + +
  • + + matcher + + + (#===) + + + + — +

    only consider message which matches matcher === a_message

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, no_value) + + + + — +

    message or nil when there is no message

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+142
+143
+144
+145
+146
+147
+148
+149
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 142
+
+def try_pop_matching(matcher, no_value = nil)
+  @Mutex.synchronize do
+    message = ns_shift_message matcher
+    return message if message != NOTHING
+    message = ns_consume_pending_push matcher
+    return message != NOTHING ? message : no_value
+  end
+end
+
+
+ +
+

+ + #try_push(message) ⇒ true, false + + + + + +

+
+

Push the message into the channel if there is space available.

+ + +
+
+
+

Parameters:

+
    + +
  • + + message + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+74
+75
+76
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 74
+
+def try_push(message)
+  @Mutex.synchronize { ns_try_push(message) }
+end
+
+
+ +
+

+ + #try_select(channels) ⇒ ::Array(Channel, Object), nil + + + + + +

+
+

If message is available in the receiver or any of the provided channels +the channel message pair is returned. If there is no message nil is returned. +The returned channel is the origin of the message.

+ + +
+
+
+

Parameters:

+ + +

Returns:

+
    + +
  • + + + (::Array(Channel, Object), nil) + + + + — +

    pair [channel, message] if one of the channels is available for reading

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+229
+230
+231
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 229
+
+def try_select(channels)
+  try_select_matching ANY, channels
+end
+
+
+ +
+

+ + #try_select_matching(matcher, channels) ⇒ ::Array(Channel, Object), nil + + + + + +

+
+

If message is available in the receiver or any of the provided channels +the channel message pair is returned. If there is no message nil is returned. +The returned channel is the origin of the message.

+ + +
+
+
+

Parameters:

+
    + +
  • + + channels + + + (Channel, ::Array<Channel>) + + + +
  • + +
  • + + matcher + + + (#===) + + + + — +

    only consider message which matches matcher === a_message

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (::Array(Channel, Object), nil) + + + + — +

    pair [channel, message] if one of the channels is available for reading

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+235
+236
+237
+238
+239
+240
+241
+242
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/channel.rb', line 235
+
+def try_select_matching(matcher, channels)
+  message = nil
+  channel = [self, *channels].find do |ch|
+    message = ch.try_pop_matching(matcher, NOTHING)
+    message != NOTHING
+  end
+  channel ? [channel, message] : nil
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/Event.html b/docs/1.1.10/Concurrent/Promises/Event.html new file mode 100644 index 000000000..7ec5ae31d --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/Event.html @@ -0,0 +1,766 @@ + + + + + + + Class: Concurrent::Promises::Event + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Promises::Event + + + +

+
+ +
+
Inherits:
+
+ AbstractEventFuture + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb
+
+ +
+ +

Overview

+
+

Represents an event which will happen in future (will be resolved). The event is either +pending or resolved. It should be always resolved. Use Future to communicate rejections and +cancellation.

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

ResolvableEvent

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #any(event_or_future) ⇒ Event + + + + Also known as: + | + + + + +

+
+

Creates a new event which will be resolved when the first of receiver, event_or_future +resolves.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+842
+843
+844
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 842
+
+def any(event_or_future)
+  AnyResolvedEventPromise.new_blocked_by2(self, event_or_future, @DefaultExecutor).event
+end
+
+
+ +
+

+ + #delayEvent + + + + + +

+
+

Creates new event dependent on receiver which will not evaluate until touched, see AbstractEventFuture#touch. +In other words, it inserts delay into the chain of Futures making rest of it lazy evaluated.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+852
+853
+854
+855
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 852
+
+def delay
+  event = DelayPromise.new(@DefaultExecutor).event
+  ZipEventEventPromise.new_blocked_by2(self, event, @DefaultExecutor).event
+end
+
+
+ +
+

+ + #schedule(intended_time) ⇒ Event + + + + + +

+
+

Creates new event dependent on receiver scheduled to execute on/in intended_time. +In time is interpreted from the moment the receiver is resolved, therefore it inserts +delay into the chain.

+ + +
+
+
+

Parameters:

+
    + +
  • + + intended_time + + + (Numeric, Time) + + + + — +

    Numeric means to run in intended_time seconds. +Time means to run on intended_time.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+864
+865
+866
+867
+868
+869
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 864
+
+def schedule(intended_time)
+  chain do
+    event = ScheduledPromise.new(@DefaultExecutor, intended_time).event
+    ZipEventEventPromise.new_blocked_by2(self, event, @DefaultExecutor).event
+  end.flat_event
+end
+
+
+ +
+

+ + #to_eventEvent + + + + + +

+
+

Returns self, since this is event

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+882
+883
+884
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 882
+
+def to_event
+  self
+end
+
+
+ +
+

+ + #to_futureFuture + + + + + +

+
+

Converts event to a future. The future is fulfilled when the event is resolved, the future may never fail.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+874
+875
+876
+877
+878
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 874
+
+def to_future
+  future = Promises.resolvable_future
+ensure
+  chain_resolvable(future)
+end
+
+
+ +
+

+ + #with_default_executor(executor) ⇒ Event + + + + + +

+
+

Crates new object with same class with the executor set as its new default executor. +Any futures depending on it will use the new default executor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+888
+889
+890
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 888
+
+def with_default_executor(executor)
+  EventWrapperPromise.new_blocked_by1(self, executor).event
+end
+
+
+ +
+

+ + #zip(other) ⇒ Future, Event + + + + Also known as: + & + + + + +

+
+

Creates a new event or a future which will be resolved when receiver and other are. +Returns an event if receiver and other are events, otherwise returns a future. +If just one of the parties is Future then the result +of the returned future is equal to the result of the supplied future. If both are futures +then the result is as described in FactoryMethods#zip_futures_on.

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+828
+829
+830
+831
+832
+833
+834
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 828
+
+def zip(other)
+  if other.is_a?(Future)
+    ZipFutureEventPromise.new_blocked_by2(other, self, @DefaultExecutor).future
+  else
+    ZipEventEventPromise.new_blocked_by2(self, other, @DefaultExecutor).event
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/FactoryMethods.html b/docs/1.1.10/Concurrent/Promises/FactoryMethods.html new file mode 100644 index 000000000..e2cc0196a --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/FactoryMethods.html @@ -0,0 +1,6968 @@ + + + + + + + Module: Concurrent::Promises::FactoryMethods + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Promises::FactoryMethods + + + +

+
+ + + + +
+
Extended by:
+
FactoryMethods, ReInclude
+
+ + + +
+
Includes:
+
Configuration
+
+ + + + +
+
Included in:
+
Concurrent::Promises, FactoryMethods, Throttle
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb,
+ lib/concurrent-ruby-edge/concurrent/edge/promises.rb,
lib/concurrent-ruby-edge/concurrent/edge/old_channel_integration.rb
+
+
+ +
+ +

Overview

+
+

Container of all Future, Event factory methods. They are never constructed directly with +new.

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: Configuration + + + + +

+ + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + +
+

Class Method Details

+ + +
+

+ + .any_event(*futures_and_or_events) ⇒ Future + + + + + +

+
+

Shortcut of #any_event_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+317
+318
+319
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 317
+
+def any_event(*futures_and_or_events)
+  any_event_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + .any_event_on(default_executor, *futures_and_or_events) ⇒ Event + + + + + +

+
+

Creates new event which becomes resolved after first of the futures_and_or_events resolves. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+327
+328
+329
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 327
+
+def any_event_on(default_executor, *futures_and_or_events)
+  AnyResolvedEventPromise.new_blocked_by(futures_and_or_events, default_executor).event
+end
+
+
+ +
+

+ + .any_fulfilled_future(*futures_and_or_events) ⇒ Future + + + + + +

+
+

Shortcut of #any_fulfilled_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+298
+299
+300
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 298
+
+def any_fulfilled_future(*futures_and_or_events)
+  any_fulfilled_future_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + .any_fulfilled_future_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + +

+
+

Creates new future which is resolved after first of futures_and_or_events is fulfilled. +Its result equals result of the first resolved future or if all futures_and_or_events reject, +it has reason of the last resolved future. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+311
+312
+313
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 311
+
+def any_fulfilled_future_on(default_executor, *futures_and_or_events)
+  AnyFulfilledFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future
+end
+
+
+ +
+

+ + .any_resolved_future(*futures_and_or_events) ⇒ Future + + + + Also known as: + any + + + + +

+
+

Shortcut of #any_resolved_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+276
+277
+278
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 276
+
+def any_resolved_future(*futures_and_or_events)
+  any_resolved_future_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + .any_resolved_future_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + +

+
+

Creates new future which is resolved after first futures_and_or_events is resolved. +Its result equals result of the first resolved future. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+292
+293
+294
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 292
+
+def any_resolved_future_on(default_executor, *futures_and_or_events)
+  AnyResolvedFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future
+end
+
+
+ +
+

+ + .delay(*args, &task) ⇒ Future, Event + + + + + +

+
+

Shortcut of #delay_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+188
+189
+190
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 188
+
+def delay(*args, &task)
+  delay_on default_executor, *args, &task
+end
+
+
+ +
+

+ + + #delay_on(default_executor, *args) {|*args| ... } ⇒ Future + + #delay_on(default_executor) ⇒ Event + + + + + + +

+
+

Creates new event or future which is resolved only after it is touched, +see AbstractEventFuture#touch.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #delay_on(default_executor, *args) {|*args| ... } ⇒ Future +
    +
    +

    If task is provided it returns a Concurrent::Promises::Future representing the result of the task.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + args + + + (Object) + + + + — +

      arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

      +
      + +
    • + +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Returns:

    + +

    Returns:

    +
      + +
    • + + + (Future) + + + +
    • + +
    + +
    +
  • + + +
  • + #delay_on(default_executor) ⇒ Event +
    +
    +

    If no task is provided, it returns an Event

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+205
+206
+207
+208
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 205
+
+def delay_on(default_executor, *args, &task)
+  event = DelayPromise.new(default_executor).event
+  task ? event.chain(*args, &task) : event
+end
+
+
+ +
+

+ + .fulfilled_future(value, default_executor = self.default_executor) ⇒ Future + + + + + +

+
+

Creates resolved future with will be fulfilled with the given value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+125
+126
+127
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 125
+
+def fulfilled_future(value, default_executor = self.default_executor)
+  resolved_future true, value, nil, default_executor
+end
+
+
+ +
+

+ + .future(*args, &task) ⇒ Future + + + + + +

+
+

Shortcut of #future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+92
+93
+94
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 92
+
+def future(*args, &task)
+  future_on(default_executor, *args, &task)
+end
+
+
+ +
+

+ + .future_on(default_executor, *args) {|*args| ... } ⇒ Future + + + + + +

+
+

Constructs new Future which will be resolved after block is evaluated on default executor. +Evaluation begins immediately.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (*args) + + + + — +

    to the task.

    +
    + +
  • + +
+

Yield Returns:

+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+104
+105
+106
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 104
+
+def future_on(default_executor, *args, &task)
+  ImmediateEventPromise.new(default_executor).future.then(*args, &task)
+end
+
+
+ +
+

+ + + #make_future(nil, default_executor = self.default_executor) ⇒ Event + + #make_future(a_future, default_executor = self.default_executor) ⇒ Future + + #make_future(an_event, default_executor = self.default_executor) ⇒ Event + + #make_future(exception, default_executor = self.default_executor) ⇒ Future + + #make_future(value, default_executor = self.default_executor) ⇒ Future + + + + + + +

+
+

General constructor. Behaves differently based on the argument's type. It's provided for convenience +but it's better to be explicit.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #make_future(nil, default_executor = self.default_executor) ⇒ Event +
    +
    +

    Returns resolved event.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + nil + + + (nil) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + + — +

      resolved event.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(a_future, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a future which will be resolved when a_future is.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + a_future + + + (Future) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a future which will be resolved when a_future is.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(an_event, default_executor = self.default_executor) ⇒ Event +
    +
    +

    Returns an event which will be resolved when an_event is.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + an_event + + + (Event) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + + — +

      an event which will be resolved when an_event is.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(exception, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a rejected future with the exception as its reason.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + exception + + + (Exception) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a rejected future with the exception as its reason.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(value, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a fulfilled future with the value.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + value + + + (Object) + + + + — +

      when none of the above overloads fits

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a fulfilled future with the value.

      +
      + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +

See Also:

+
    + +
  • resolved_event, fulfilled_future
  • + +
+ +
+ + + + +
+
+
+
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 172
+
+def make_future(argument = nil, default_executor = self.default_executor)
+  case argument
+  when AbstractEventFuture
+    # returning wrapper would change nothing
+    argument
+  when Exception
+    rejected_future argument, default_executor
+  when nil
+    resolved_event default_executor
+  else
+    fulfilled_future argument, default_executor
+  end
+end
+
+
+ +
+

+ + .rejected_future(reason, default_executor = self.default_executor) ⇒ Future + + + + + +

+
+

Creates resolved future with will be rejected with the given reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + reason + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+134
+135
+136
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 134
+
+def rejected_future(reason, default_executor = self.default_executor)
+  resolved_future false, nil, reason, default_executor
+end
+
+
+ +
+

+ + .resolvable_eventResolvableEvent + + + + + +

+
+

Shortcut of #resolvable_event_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+61
+62
+63
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 61
+
+def resolvable_event
+  resolvable_event_on default_executor
+end
+
+
+ +
+

+ + .resolvable_event_on(default_executor = self.default_executor) ⇒ ResolvableEvent + + + + + +

+
+

Created resolvable event, user is responsible for resolving the event once by +ResolvableEvent#resolve.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+70
+71
+72
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 70
+
+def resolvable_event_on(default_executor = self.default_executor)
+  ResolvableEventPromise.new(default_executor).future
+end
+
+
+ +
+

+ + .resolvable_futureResolvableFuture + + + + + +

+
+

Shortcut of #resolvable_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+76
+77
+78
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 76
+
+def resolvable_future
+  resolvable_future_on default_executor
+end
+
+
+ +
+

+ + .resolvable_future_on(default_executor = self.default_executor) ⇒ ResolvableFuture + + + + + +

+
+

Creates resolvable future, user is responsible for resolving the future once by +ResolvableFuture#resolve, ResolvableFuture#fulfill, +or ResolvableFuture#reject

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+86
+87
+88
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 86
+
+def resolvable_future_on(default_executor = self.default_executor)
+  ResolvableFuturePromise.new(default_executor).future
+end
+
+
+ +
+

+ + .resolved_event(default_executor = self.default_executor) ⇒ Event + + + + + +

+
+

Creates resolved event.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+142
+143
+144
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 142
+
+def resolved_event(default_executor = self.default_executor)
+  ImmediateEventPromise.new(default_executor).event
+end
+
+
+ +
+

+ + .resolved_future(fulfilled, value, reason, default_executor = self.default_executor) ⇒ Future + + + + + +

+
+

Creates resolved future with will be either fulfilled with the given value or rejection with +the given reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + fulfilled + + + (true, false) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
  • + + reason + + + (Object) + + + +
  • + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+116
+117
+118
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 116
+
+def resolved_future(fulfilled, value, reason, default_executor = self.default_executor)
+  ImmediateFuturePromise.new(default_executor, fulfilled, value, reason).future
+end
+
+
+ +
+

+ + .schedule(intended_time, *args, &task) ⇒ Future, Event + + + + + +

+
+

Shortcut of #schedule_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+212
+213
+214
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 212
+
+def schedule(intended_time, *args, &task)
+  schedule_on default_executor, intended_time, *args, &task
+end
+
+
+ +
+

+ + + #schedule_on(default_executor, intended_time, *args) {|*args| ... } ⇒ Future + + #schedule_on(default_executor, intended_time) ⇒ Event + + + + + + +

+
+

Creates new event or future which is resolved in intended_time.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #schedule_on(default_executor, intended_time, *args) {|*args| ... } ⇒ Future +
    +
    +

    If task is provided it returns a Concurrent::Promises::Future representing the result of the task.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + args + + + (Object) + + + + — +

      arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

      +
      + +
    • + +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Returns:

    + +

    Returns:

    +
      + +
    • + + + (Future) + + + +
    • + +
    + +
    +
  • + + +
  • + #schedule_on(default_executor, intended_time) ⇒ Event +
    +
    +

    If no task is provided, it returns an Event

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + intended_time + + + (Numeric, Time) + + + + — +

    Numeric means to run in intended_time seconds. +Time means to run on intended_time.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+231
+232
+233
+234
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 231
+
+def schedule_on(default_executor, intended_time, *args, &task)
+  event = ScheduledPromise.new(default_executor, intended_time).event
+  task ? event.chain(*args, &task) : event
+end
+
+
+ +
+

+ + .zip_events(*futures_and_or_events) ⇒ Event + + + + + +

+
+

Shortcut of #zip_events_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+260
+261
+262
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 260
+
+def zip_events(*futures_and_or_events)
+  zip_events_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + .zip_events_on(default_executor, *futures_and_or_events) ⇒ Event + + + + + +

+
+

Creates new event which is resolved after all futures_and_or_events are resolved. +(Future is resolved when fulfilled or rejected.)

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+270
+271
+272
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 270
+
+def zip_events_on(default_executor, *futures_and_or_events)
+  ZipEventsPromise.new_blocked_by(futures_and_or_events, default_executor).event
+end
+
+
+ +
+

+ + .zip_futures(*futures_and_or_events) ⇒ Future + + + + Also known as: + zip + + + + +

+
+

Shortcut of #zip_futures_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+238
+239
+240
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 238
+
+def zip_futures(*futures_and_or_events)
+  zip_futures_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + .zip_futures_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + +

+
+

Creates new future which is resolved after all futures_and_or_events are resolved. +Its value is array of zipped future values. Its reason is array of reasons for rejection. +If there is an error it rejects. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+252
+253
+254
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 252
+
+def zip_futures_on(default_executor, *futures_and_or_events)
+  ZipFuturesPromise.new_blocked_by(futures_and_or_events, default_executor).future
+end
+
+
+ +
+

+ + .zip_futures_over(enumerable, &future_factory) ⇒ Future + + + + + +

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Shortcut of #zip_futures_over_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+72
+73
+74
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 72
+
+def zip_futures_over(enumerable, &future_factory)
+  zip_futures_over_on default_executor, enumerable, &future_factory
+end
+
+
+ +
+

+ + .zip_futures_over_on(default_executor, enumerable) {|element| ... } ⇒ Future + + + + + +

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Creates new future which is resolved after all the futures created by future_factory from +enumerable elements are resolved. Simplified it does: +zip(*enumerable.map { |e| future e, &future_factory })

+ + +
+
+
+ +
+

Examples:

+ + +
# `#succ` calls are executed in parallel
+zip_futures_over_on(:io, [1, 2], &:succ).value! # => [2, 3]
+ +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + enumerable + + + (Enumerable) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    a task to be executed in future

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + element + + + (Object) + + + + — +

    from enumerable

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    a value of the future

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+90
+91
+92
+93
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 90
+
+def zip_futures_over_on(default_executor, enumerable, &future_factory)
+  # ZipFuturesPromise.new_blocked_by(futures_and_or_events, default_executor).future
+  zip_futures_on(default_executor, *enumerable.map { |e| future e, &future_factory })
+end
+
+
+ +
+

+ + .default_executorExecutor, :io, :fast + + + + + + + Originally defined in module + Configuration + + +

+
+

Returns the executor which is used when none is supplied +to a factory method. The method can be overridden in the receivers of +include FactoryMethod.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Executor, :io, :fast) + + + + — +

    the executor which is used when none is supplied +to a factory method. The method can be overridden in the receivers of +include FactoryMethod

    +
    + +
  • + +
+ +
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #any_event(*futures_and_or_events) ⇒ Future + + + + + +

+
+

Shortcut of #any_event_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+317
+318
+319
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 317
+
+def any_event(*futures_and_or_events)
+  any_event_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + #any_event_on(default_executor, *futures_and_or_events) ⇒ Event + + + + + +

+
+

Creates new event which becomes resolved after first of the futures_and_or_events resolves. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+327
+328
+329
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 327
+
+def any_event_on(default_executor, *futures_and_or_events)
+  AnyResolvedEventPromise.new_blocked_by(futures_and_or_events, default_executor).event
+end
+
+
+ +
+

+ + #any_fulfilled_future(*futures_and_or_events) ⇒ Future + + + + + +

+
+

Shortcut of #any_fulfilled_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+298
+299
+300
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 298
+
+def any_fulfilled_future(*futures_and_or_events)
+  any_fulfilled_future_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + #any_fulfilled_future_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + +

+
+

Creates new future which is resolved after first of futures_and_or_events is fulfilled. +Its result equals result of the first resolved future or if all futures_and_or_events reject, +it has reason of the last resolved future. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+311
+312
+313
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 311
+
+def any_fulfilled_future_on(default_executor, *futures_and_or_events)
+  AnyFulfilledFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future
+end
+
+
+ +
+

+ + #any_resolved_future(*futures_and_or_events) ⇒ Future + + + + Also known as: + any + + + + +

+
+

Shortcut of #any_resolved_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+276
+277
+278
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 276
+
+def any_resolved_future(*futures_and_or_events)
+  any_resolved_future_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + #any_resolved_future_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + +

+
+

Creates new future which is resolved after first futures_and_or_events is resolved. +Its result equals result of the first resolved future. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+292
+293
+294
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 292
+
+def any_resolved_future_on(default_executor, *futures_and_or_events)
+  AnyResolvedFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future
+end
+
+
+ +
+

+ + #delay(*args, &task) ⇒ Future, Event + + + + + +

+
+

Shortcut of #delay_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+188
+189
+190
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 188
+
+def delay(*args, &task)
+  delay_on default_executor, *args, &task
+end
+
+
+ +
+

+ + + #delay_on(default_executor, *args) {|*args| ... } ⇒ Future + + #delay_on(default_executor) ⇒ Event + + + + + + +

+
+

Creates new event or future which is resolved only after it is touched, +see AbstractEventFuture#touch.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #delay_on(default_executor, *args) {|*args| ... } ⇒ Future +
    +
    +

    If task is provided it returns a Concurrent::Promises::Future representing the result of the task.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + args + + + (Object) + + + + — +

      arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

      +
      + +
    • + +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Returns:

    + +

    Returns:

    +
      + +
    • + + + (Future) + + + +
    • + +
    + +
    +
  • + + +
  • + #delay_on(default_executor) ⇒ Event +
    +
    +

    If no task is provided, it returns an Event

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+205
+206
+207
+208
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 205
+
+def delay_on(default_executor, *args, &task)
+  event = DelayPromise.new(default_executor).event
+  task ? event.chain(*args, &task) : event
+end
+
+
+ +
+

+ + #fulfilled_future(value, default_executor = self.default_executor) ⇒ Future + + + + + +

+
+

Creates resolved future with will be fulfilled with the given value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+125
+126
+127
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 125
+
+def fulfilled_future(value, default_executor = self.default_executor)
+  resolved_future true, value, nil, default_executor
+end
+
+
+ +
+

+ + #future(*args, &task) ⇒ Future + + + + + +

+
+

Shortcut of #future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+92
+93
+94
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 92
+
+def future(*args, &task)
+  future_on(default_executor, *args, &task)
+end
+
+
+ +
+

+ + #future_on(default_executor, *args) {|*args| ... } ⇒ Future + + + + + +

+
+

Constructs new Future which will be resolved after block is evaluated on default executor. +Evaluation begins immediately.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (*args) + + + + — +

    to the task.

    +
    + +
  • + +
+

Yield Returns:

+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+104
+105
+106
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 104
+
+def future_on(default_executor, *args, &task)
+  ImmediateEventPromise.new(default_executor).future.then(*args, &task)
+end
+
+
+ +
+

+ + + #make_future(nil, default_executor = self.default_executor) ⇒ Event + + #make_future(a_future, default_executor = self.default_executor) ⇒ Future + + #make_future(an_event, default_executor = self.default_executor) ⇒ Event + + #make_future(exception, default_executor = self.default_executor) ⇒ Future + + #make_future(value, default_executor = self.default_executor) ⇒ Future + + + + + + +

+
+

General constructor. Behaves differently based on the argument's type. It's provided for convenience +but it's better to be explicit.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #make_future(nil, default_executor = self.default_executor) ⇒ Event +
    +
    +

    Returns resolved event.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + nil + + + (nil) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + + — +

      resolved event.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(a_future, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a future which will be resolved when a_future is.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + a_future + + + (Future) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a future which will be resolved when a_future is.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(an_event, default_executor = self.default_executor) ⇒ Event +
    +
    +

    Returns an event which will be resolved when an_event is.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + an_event + + + (Event) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + + — +

      an event which will be resolved when an_event is.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(exception, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a rejected future with the exception as its reason.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + exception + + + (Exception) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a rejected future with the exception as its reason.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(value, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a fulfilled future with the value.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + value + + + (Object) + + + + — +

      when none of the above overloads fits

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a fulfilled future with the value.

      +
      + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +

See Also:

+
    + +
  • resolved_event, fulfilled_future
  • + +
+ +
+ + + + +
+
+
+
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 172
+
+def make_future(argument = nil, default_executor = self.default_executor)
+  case argument
+  when AbstractEventFuture
+    # returning wrapper would change nothing
+    argument
+  when Exception
+    rejected_future argument, default_executor
+  when nil
+    resolved_event default_executor
+  else
+    fulfilled_future argument, default_executor
+  end
+end
+
+
+ +
+

+ + #rejected_future(reason, default_executor = self.default_executor) ⇒ Future + + + + + +

+
+

Creates resolved future with will be rejected with the given reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + reason + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+134
+135
+136
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 134
+
+def rejected_future(reason, default_executor = self.default_executor)
+  resolved_future false, nil, reason, default_executor
+end
+
+
+ +
+

+ + #resolvable_eventResolvableEvent + + + + + +

+
+

Shortcut of #resolvable_event_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+61
+62
+63
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 61
+
+def resolvable_event
+  resolvable_event_on default_executor
+end
+
+
+ +
+

+ + #resolvable_event_on(default_executor = self.default_executor) ⇒ ResolvableEvent + + + + + +

+
+

Created resolvable event, user is responsible for resolving the event once by +ResolvableEvent#resolve.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+70
+71
+72
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 70
+
+def resolvable_event_on(default_executor = self.default_executor)
+  ResolvableEventPromise.new(default_executor).future
+end
+
+
+ +
+

+ + #resolvable_futureResolvableFuture + + + + + +

+
+

Shortcut of #resolvable_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+76
+77
+78
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 76
+
+def resolvable_future
+  resolvable_future_on default_executor
+end
+
+
+ +
+

+ + #resolvable_future_on(default_executor = self.default_executor) ⇒ ResolvableFuture + + + + + +

+
+

Creates resolvable future, user is responsible for resolving the future once by +ResolvableFuture#resolve, ResolvableFuture#fulfill, +or ResolvableFuture#reject

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+86
+87
+88
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 86
+
+def resolvable_future_on(default_executor = self.default_executor)
+  ResolvableFuturePromise.new(default_executor).future
+end
+
+
+ +
+

+ + #resolved_event(default_executor = self.default_executor) ⇒ Event + + + + + +

+
+

Creates resolved event.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+142
+143
+144
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 142
+
+def resolved_event(default_executor = self.default_executor)
+  ImmediateEventPromise.new(default_executor).event
+end
+
+
+ +
+

+ + #resolved_future(fulfilled, value, reason, default_executor = self.default_executor) ⇒ Future + + + + + +

+
+

Creates resolved future with will be either fulfilled with the given value or rejection with +the given reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + fulfilled + + + (true, false) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
  • + + reason + + + (Object) + + + +
  • + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+116
+117
+118
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 116
+
+def resolved_future(fulfilled, value, reason, default_executor = self.default_executor)
+  ImmediateFuturePromise.new(default_executor, fulfilled, value, reason).future
+end
+
+
+ +
+

+ + #schedule(intended_time, *args, &task) ⇒ Future, Event + + + + + +

+
+

Shortcut of #schedule_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+212
+213
+214
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 212
+
+def schedule(intended_time, *args, &task)
+  schedule_on default_executor, intended_time, *args, &task
+end
+
+
+ +
+

+ + + #schedule_on(default_executor, intended_time, *args) {|*args| ... } ⇒ Future + + #schedule_on(default_executor, intended_time) ⇒ Event + + + + + + +

+
+

Creates new event or future which is resolved in intended_time.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #schedule_on(default_executor, intended_time, *args) {|*args| ... } ⇒ Future +
    +
    +

    If task is provided it returns a Concurrent::Promises::Future representing the result of the task.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + args + + + (Object) + + + + — +

      arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

      +
      + +
    • + +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Returns:

    + +

    Returns:

    +
      + +
    • + + + (Future) + + + +
    • + +
    + +
    +
  • + + +
  • + #schedule_on(default_executor, intended_time) ⇒ Event +
    +
    +

    If no task is provided, it returns an Event

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + intended_time + + + (Numeric, Time) + + + + — +

    Numeric means to run in intended_time seconds. +Time means to run on intended_time.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+231
+232
+233
+234
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 231
+
+def schedule_on(default_executor, intended_time, *args, &task)
+  event = ScheduledPromise.new(default_executor, intended_time).event
+  task ? event.chain(*args, &task) : event
+end
+
+
+ +
+

+ + #zip_events(*futures_and_or_events) ⇒ Event + + + + + +

+
+

Shortcut of #zip_events_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+260
+261
+262
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 260
+
+def zip_events(*futures_and_or_events)
+  zip_events_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + #zip_events_on(default_executor, *futures_and_or_events) ⇒ Event + + + + + +

+
+

Creates new event which is resolved after all futures_and_or_events are resolved. +(Future is resolved when fulfilled or rejected.)

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+270
+271
+272
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 270
+
+def zip_events_on(default_executor, *futures_and_or_events)
+  ZipEventsPromise.new_blocked_by(futures_and_or_events, default_executor).event
+end
+
+
+ +
+

+ + #zip_futures(*futures_and_or_events) ⇒ Future + + + + Also known as: + zip + + + + +

+
+

Shortcut of #zip_futures_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+238
+239
+240
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 238
+
+def zip_futures(*futures_and_or_events)
+  zip_futures_on default_executor, *futures_and_or_events
+end
+
+
+ +
+

+ + #zip_futures_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + +

+
+

Creates new future which is resolved after all futures_and_or_events are resolved. +Its value is array of zipped future values. Its reason is array of reasons for rejection. +If there is an error it rejects. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+252
+253
+254
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 252
+
+def zip_futures_on(default_executor, *futures_and_or_events)
+  ZipFuturesPromise.new_blocked_by(futures_and_or_events, default_executor).future
+end
+
+
+ +
+

+ + #zip_futures_over(enumerable, &future_factory) ⇒ Future + + + + + +

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Shortcut of #zip_futures_over_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+72
+73
+74
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 72
+
+def zip_futures_over(enumerable, &future_factory)
+  zip_futures_over_on default_executor, enumerable, &future_factory
+end
+
+
+ +
+

+ + #zip_futures_over_on(default_executor, enumerable) {|element| ... } ⇒ Future + + + + + +

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Creates new future which is resolved after all the futures created by future_factory from +enumerable elements are resolved. Simplified it does: +zip(*enumerable.map { |e| future e, &future_factory })

+ + +
+
+
+ +
+

Examples:

+ + +
# `#succ` calls are executed in parallel
+zip_futures_over_on(:io, [1, 2], &:succ).value! # => [2, 3]
+ +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + enumerable + + + (Enumerable) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    a task to be executed in future

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + element + + + (Object) + + + + — +

    from enumerable

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    a value of the future

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+90
+91
+92
+93
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 90
+
+def zip_futures_over_on(default_executor, enumerable, &future_factory)
+  # ZipFuturesPromise.new_blocked_by(futures_and_or_events, default_executor).future
+  zip_futures_on(default_executor, *enumerable.map { |e| future e, &future_factory })
+end
+
+
+ +
+

+ + #default_executorExecutor, :io, :fast + + + + + + + Originally defined in module + Configuration + + +

+
+

Returns the executor which is used when none is supplied +to a factory method. The method can be overridden in the receivers of +include FactoryMethod.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Executor, :io, :fast) + + + + — +

    the executor which is used when none is supplied +to a factory method. The method can be overridden in the receivers of +include FactoryMethod

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/FactoryMethods/Configuration.html b/docs/1.1.10/Concurrent/Promises/FactoryMethods/Configuration.html new file mode 100644 index 000000000..6dd37ae77 --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/FactoryMethods/Configuration.html @@ -0,0 +1,220 @@ + + + + + + + Module: Concurrent::Promises::FactoryMethods::Configuration + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Promises::FactoryMethods::Configuration + + + +

+
+ + + + + + + + + +
+
Included in:
+
Concurrent::Promises::FactoryMethods
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #default_executorExecutor, :io, :fast + + + + + +

+
+

Returns the executor which is used when none is supplied +to a factory method. The method can be overridden in the receivers of +include FactoryMethod.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Executor, :io, :fast) + + + + — +

    the executor which is used when none is supplied +to a factory method. The method can be overridden in the receivers of +include FactoryMethod

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+52
+53
+54
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 52
+
+def default_executor
+  :io
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/Future.html b/docs/1.1.10/Concurrent/Promises/Future.html new file mode 100644 index 000000000..af0a5a32b --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/Future.html @@ -0,0 +1,3789 @@ + + + + + + + Class: Concurrent::Promises::Future + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Promises::Future + + + +

+
+ +
+
Inherits:
+
+ AbstractEventFuture + + + show all + +
+
+ + + + + + +
+
Includes:
+
ActorIntegration, FlatShortcuts, NewChannelIntegration
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb,
+ lib/concurrent-ruby-edge/concurrent/edge/promises.rb,
lib/concurrent-ruby-edge/concurrent/edge/promises.rb,
lib/concurrent-ruby-edge/concurrent/edge/old_channel_integration.rb
+
+
+ +
+ +

Overview

+
+

Represents a value which will become available in future. May reject with a reason instead, +e.g. when the tasks raises an exception.

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

ResolvableFuture

+
+

Defined Under Namespace

+

+ + + Modules: ActorIntegration, FlatShortcuts, NewChannelIntegration + + + + +

+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #any(event_or_future) ⇒ Future + + + + Also known as: + | + + + + +

+
+

Creates a new event which will be resolved when the first of receiver, event_or_future +resolves. Returning future will have value nil if event_or_future is event and resolves +first.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1074
+1075
+1076
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1074
+
+def any(event_or_future)
+  AnyResolvedFuturePromise.new_blocked_by2(self, event_or_future, @DefaultExecutor).future
+end
+
+
+ +
+

+ + #delayFuture + + + + + +

+
+

Creates new future dependent on receiver which will not evaluate until touched, see AbstractEventFuture#touch. +In other words, it inserts delay into the chain of Futures making rest of it lazy evaluated.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1084
+1085
+1086
+1087
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1084
+
+def delay
+  event = DelayPromise.new(@DefaultExecutor).event
+  ZipFutureEventPromise.new_blocked_by2(self, event, @DefaultExecutor).future
+end
+
+
+ +
+

+ + #exception(*args) ⇒ Exception + + + + + +

+
+

Allows rejected Future to be risen with raise method. +If the reason is not an exception Runtime.new(reason) is returned.

+ + +
+
+
+ +
+

Examples:

+ + +
raise Promises.rejected_future(StandardError.new("boom"))
+raise Promises.rejected_future("or just boom")
+ +
+ +

Returns:

+
    + +
  • + + + (Exception) + + + +
  • + +
+

Raises:

+
    + +
  • + + + (Concurrent::Error) + + + + — +

    when raising not rejected future

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1002
+
+def exception(*args)
+  raise Concurrent::Error, 'it is not rejected' unless rejected?
+  raise ArgumentError unless args.size <= 1
+  reason = Array(internal_state.reason).flatten.compact
+  if reason.size > 1
+    ex = Concurrent::MultipleErrors.new reason
+    ex.set_backtrace(caller)
+    ex
+  else
+    ex = if reason[0].respond_to? :exception
+           reason[0].exception(*args)
+         else
+           RuntimeError.new(reason[0]).exception(*args)
+         end
+    ex.set_backtrace Array(ex.backtrace) + caller
+    ex
+  end
+end
+
+
+ +
+

+ + #flat_eventEvent + + + + + +

+
+

Creates new event which will be resolved when the returned event by receiver is. +Be careful if the receiver rejects it will just resolve since Event does not hold reason.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1119
+1120
+1121
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1119
+
+def flat_event
+  FlatEventPromise.new_blocked_by1(self, @DefaultExecutor).event
+end
+
+
+ +
+

+ + #flat_future(level = 1) ⇒ Future + + + + Also known as: + flat + + + + +

+
+

Creates new future which will have result of the future returned by receiver. If receiver +rejects it will have its rejection.

+ + +
+
+
+

Parameters:

+
    + +
  • + + level + + + (Integer) + + + (defaults to: 1) + + + — +

    how many levels of futures should flatten

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1109
+1110
+1111
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1109
+
+def flat_future(level = 1)
+  FlatFuturePromise.new_blocked_by1(self, level, @DefaultExecutor).future
+end
+
+
+ +
+

+ + #fulfilled?Boolean + + + + + +

+
+

Is it in fulfilled state?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+910
+911
+912
+913
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 910
+
+def fulfilled?
+  state = internal_state
+  state.resolved? && state.fulfilled?
+end
+
+
+ +
+

+ + #on_fulfillment(*args, &callback) ⇒ self + + + + + +

+
+

Shortcut of #on_fulfillment_using with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1125
+1126
+1127
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1125
+
+def on_fulfillment(*args, &callback)
+  on_fulfillment_using @DefaultExecutor, *args, &callback
+end
+
+
+ +
+

+ + #on_fulfillment!(*args) {|value, *args| ... } ⇒ self + + + + + +

+
+

Stores the callback to be executed synchronously on resolving thread after it is +fulfilled. Does nothing on rejection.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (value, *args) + + + + — +

    to the callback.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + + + + + +

    is forgotten.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1136
+1137
+1138
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1136
+
+def on_fulfillment!(*args, &callback)
+  add_callback :callback_on_fulfillment, args, callback
+end
+
+
+ +
+

+ + #on_fulfillment_using(executor, *args) {|value, *args| ... } ⇒ self + + + + + +

+
+

Stores the callback to be executed asynchronously on executor after it is +fulfilled. Does nothing on rejection.

+ + +
+
+
+

Parameters:

+
    + +
  • + + executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. The task is executed on it, default executor remains unchanged.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (value, *args) + + + + — +

    to the callback.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + + + + + +

    is forgotten.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1148
+1149
+1150
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1148
+
+def on_fulfillment_using(executor, *args, &callback)
+  add_callback :async_callback_on_fulfillment, executor, args, callback
+end
+
+
+ +
+

+ + #on_rejection(*args, &callback) ⇒ self + + + + + +

+
+

Shortcut of #on_rejection_using with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1154
+1155
+1156
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1154
+
+def on_rejection(*args, &callback)
+  on_rejection_using @DefaultExecutor, *args, &callback
+end
+
+
+ +
+

+ + #on_rejection!(*args) {|reason, *args| ... } ⇒ self + + + + + +

+
+

Stores the callback to be executed synchronously on resolving thread after it is +rejected. Does nothing on fulfillment.

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (reason, *args) + + + + — +

    to the callback.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + + + + + +

    is forgotten.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1165
+1166
+1167
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1165
+
+def on_rejection!(*args, &callback)
+  add_callback :callback_on_rejection, args, callback
+end
+
+
+ +
+

+ + #on_rejection_using(executor, *args) {|reason, *args| ... } ⇒ self + + + + + +

+
+

Stores the callback to be executed asynchronously on executor after it is +rejected. Does nothing on fulfillment.

+ + +
+
+
+

Parameters:

+
    + +
  • + + executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. The task is executed on it, default executor remains unchanged.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (reason, *args) + + + + — +

    to the callback.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + + + + + +

    is forgotten.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1177
+1178
+1179
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1177
+
+def on_rejection_using(executor, *args, &callback)
+  add_callback :async_callback_on_rejection, executor, args, callback
+end
+
+
+ +
+

+ + #reason(timeout = nil, timeout_value = nil) ⇒ Object, timeout_value + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until the Future is resolved. +Be careful it can deadlock. Try to chain instead.

+
+
+ +
+ Note: +

Make sure returned nil is not confused with timeout, no value when rejected, +no reason when fulfilled, etc. +Use more exact methods if needed, like AbstractEventFuture#wait, #value!, #result, etc.

+
+
+ +

Returns reason of future's rejection. +Calls AbstractEventFuture#touch.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
  • + + timeout_value + + + (Object) + + + (defaults to: nil) + + + — +

    a value returned by the method when it times out

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, timeout_value) + + + + — +

    the reason, or timeout_value on timeout, or nil on fulfillment.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+955
+956
+957
+958
+959
+960
+961
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 955
+
+def reason(timeout = nil, timeout_value = nil)
+  if wait_until_resolved timeout
+    internal_state.reason
+  else
+    timeout_value
+  end
+end
+
+
+ +
+

+ + #rejected?Boolean + + + + + +

+
+

Is it in rejected state?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+917
+918
+919
+920
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 917
+
+def rejected?
+  state = internal_state
+  state.resolved? && !state.fulfilled?
+end
+
+
+ +
+

+ + #rescue(*args, &task) ⇒ Future + + + + + +

+
+

Shortcut of #rescue_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1041
+1042
+1043
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1041
+
+def rescue(*args, &task)
+  rescue_on @DefaultExecutor, *args, &task
+end
+
+
+ +
+

+ + #rescue_on(executor, *args) {|reason, *args| ... } ⇒ Future + + + + + +

+
+

Chains the task to be executed asynchronously on executor after it rejects. Does not run +the task if it fulfills. It will resolve though, triggering any dependent futures.

+ + +
+
+
+

Parameters:

+
    + +
  • + + executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. The task is executed on it, default executor remains unchanged.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (reason, *args) + + + + — +

    to the task.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + + + + + +

    will become result of the returned Future. +Its returned value becomes #value fulfilling it, +raised exception becomes #reason rejecting it.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1053
+1054
+1055
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1053
+
+def rescue_on(executor, *args, &task)
+  RescuePromise.new_blocked_by1(self, @DefaultExecutor, executor, args, &task).future
+end
+
+
+ +
+

+ + #result(timeout = nil) ⇒ Array(Boolean, Object, Object), nil + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until the Future is resolved. +Be careful it can deadlock. Try to chain instead.

+
+
+ +

Returns triplet fulfilled?, value, reason. +Calls AbstractEventFuture#touch.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Array(Boolean, Object, Object), nil) + + + + — +

    triplet of fulfilled?, value, reason, or nil +on timeout.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+970
+971
+972
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 970
+
+def result(timeout = nil)
+  internal_state.result if wait_until_resolved timeout
+end
+
+
+ +
+

+ + #run(run_test = method(:run_test)) ⇒ Future + + + + + +

+
+

Allows to use futures as green threads. The receiver has to evaluate to a future which +represents what should be done next. It basically flattens indefinitely until non Future +values is returned which becomes result of the returned future. Any encountered exception +will become reason of the returned future.

+ + +
+
+
+ +
+

Examples:

+ + +
body = lambda do |v|
+  v += 1
+  v < 5 ? Promises.future(v, &body) : v
+end
+Promises.future(0, &body).run.value! # => 5
+ +
+

Parameters:

+
    + +
  • + + run_test + + + (#call(value)) + + + (defaults to: method(:run_test)) + + + — +

    an object which when called returns either Future to keep running with +or nil, then the run completes with the value. +The run_test can be used to extract the Future from deeper structure, +or to distinguish Future which is a resulting value from a future +which is suppose to continue running.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1199
+1200
+1201
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1199
+
+def run(run_test = method(:run_test))
+  RunFuturePromise.new_blocked_by1(self, @DefaultExecutor, run_test).future
+end
+
+
+ +
+

+ + #schedule(intended_time) ⇒ Future + + + + + +

+
+

Creates new event dependent on receiver scheduled to execute on/in intended_time. +In time is interpreted from the moment the receiver is resolved, therefore it inserts +delay into the chain.

+ + +
+
+
+

Parameters:

+
    + +
  • + + intended_time + + + (Numeric, Time) + + + + — +

    Numeric means to run in intended_time seconds. +Time means to run on intended_time.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1091
+1092
+1093
+1094
+1095
+1096
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1091
+
+def schedule(intended_time)
+  chain do
+    event = ScheduledPromise.new(@DefaultExecutor, intended_time).event
+    ZipFutureEventPromise.new_blocked_by2(self, event, @DefaultExecutor).future
+  end.flat
+end
+
+
+ +
+

+ + #then(*args, &task) ⇒ Future + + + + + +

+
+

Shortcut of #then_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1023
+1024
+1025
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1023
+
+def then(*args, &task)
+  then_on @DefaultExecutor, *args, &task
+end
+
+
+ +
+

+ + #then_on(executor, *args) {|value, *args| ... } ⇒ Future + + + + + +

+
+

Chains the task to be executed asynchronously on executor after it fulfills. Does not run +the task if it rejects. It will resolve though, triggering any dependent futures.

+ + +
+
+
+

Parameters:

+
    + +
  • + + executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. The task is executed on it, default executor remains unchanged.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (value, *args) + + + + — +

    to the task.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + + + + + +

    will become result of the returned Future. +Its returned value becomes #value fulfilling it, +raised exception becomes #reason rejecting it.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1035
+1036
+1037
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1035
+
+def then_on(executor, *args, &task)
+  ThenPromise.new_blocked_by1(self, @DefaultExecutor, executor, args, &task).future
+end
+
+
+ +
+

+ + #to_eventEvent + + + + + +

+
+

Converts future to event which is resolved when future is resolved by fulfillment or rejection.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1211
+1212
+1213
+1214
+1215
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1211
+
+def to_event
+  event = Promises.resolvable_event
+ensure
+  chain_resolvable(event)
+end
+
+
+ +
+

+ + #to_futureFuture + + + + + +

+
+

Returns self, since this is a future

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1219
+1220
+1221
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1219
+
+def to_future
+  self
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    Short string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1224
+
+def to_s
+  if resolved?
+    format '%s with %s>', super[0..-2], (fulfilled? ? value : reason).inspect
+  else
+    super
+  end
+end
+
+
+ +
+

+ + #value(timeout = nil, timeout_value = nil) ⇒ Object, nil, timeout_value + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until the Future is resolved. +Be careful it can deadlock. Try to chain instead.

+
+
+ +
+ Note: +

Make sure returned nil is not confused with timeout, no value when rejected, +no reason when fulfilled, etc. +Use more exact methods if needed, like AbstractEventFuture#wait, #value!, #result, etc.

+
+
+ +

Return value of the future. +Calls AbstractEventFuture#touch.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
  • + + timeout_value + + + (Object) + + + (defaults to: nil) + + + — +

    a value returned by the method when it times out

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil, timeout_value) + + + + — +

    the value of the Future when fulfilled, +timeout_value on timeout, +nil on rejection.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+939
+940
+941
+942
+943
+944
+945
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 939
+
+def value(timeout = nil, timeout_value = nil)
+  if wait_until_resolved timeout
+    internal_state.value
+  else
+    timeout_value
+  end
+end
+
+
+ +
+

+ + #value!(timeout = nil, timeout_value = nil) ⇒ Object, nil, timeout_value + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until the Future is resolved. +Be careful it can deadlock. Try to chain instead.

+
+
+ +
+ Note: +

Make sure returned nil is not confused with timeout, no value when rejected, +no reason when fulfilled, etc. +Use more exact methods if needed, like AbstractEventFuture#wait, #value!, #result, etc.

+
+
+ +

Return value of the future. +Calls AbstractEventFuture#touch.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
  • + + timeout_value + + + (Object) + + + (defaults to: nil) + + + — +

    a value returned by the method when it times out

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil, timeout_value) + + + + — +

    the value of the Future when fulfilled, +or nil on rejection, +or timeout_value on timeout.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    #reason on rejection

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+986
+987
+988
+989
+990
+991
+992
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 986
+
+def value!(timeout = nil, timeout_value = nil)
+  if wait_until_resolved! timeout
+    internal_state.value
+  else
+    timeout_value
+  end
+end
+
+
+ +
+

+ + #wait!(timeout = nil) ⇒ self, true, false + + + + + +

+
+ +
+ Note: +

This function potentially blocks current thread until the Future is resolved. +Be careful it can deadlock. Try to chain instead.

+
+
+ +

Wait (block the Thread) until receiver is AbstractEventFuture#resolved?. +Calls AbstractEventFuture#touch.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, true, false) + + + + — +

    self implies timeout was not used, true implies timeout was used +and it was resolved, false implies it was not resolved within timeout.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    #reason on rejection

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+976
+977
+978
+979
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 976
+
+def wait!(timeout = nil)
+  result = wait_until_resolved!(timeout)
+  timeout ? result : self
+end
+
+
+ +
+

+ + #with_default_executor(executor) ⇒ Future + + + + + +

+
+

Crates new object with same class with the executor set as its new default executor. +Any futures depending on it will use the new default executor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1100
+1101
+1102
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1100
+
+def with_default_executor(executor)
+  FutureWrapperPromise.new_blocked_by1(self, executor).future
+end
+
+
+ +
+

+ + #zip(other) ⇒ Future + + + + Also known as: + & + + + + +

+
+

Creates a new event or a future which will be resolved when receiver and other are. +Returns an event if receiver and other are events, otherwise returns a future. +If just one of the parties is Future then the result +of the returned future is equal to the result of the supplied future. If both are futures +then the result is as described in Concurrent::Promises::FactoryMethods#zip_futures_on.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1059
+
+def zip(other)
+  if other.is_a?(Future)
+    ZipFuturesPromise.new_blocked_by2(self, other, @DefaultExecutor).future
+  else
+    ZipFutureEventPromise.new_blocked_by2(self, other, @DefaultExecutor).future
+  end
+end
+
+
+ +
+

+ + #then_ask(actor) ⇒ Future + + + + + + + Originally defined in module + ActorIntegration + + +

+
+

Asks the actor with its value.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + + — +

    new future with the response form the actor

    +
    + +
  • + +
+ +
+
+ +
+

+ + #then_channel_push(channel) ⇒ Future + + + + + + + Originally defined in module + NewChannelIntegration + + +

+
+

Returns a future which is fulfilled after the message is pushed to the channel. +May take a moment if the channel is full.

+ + +
+
+
+

Parameters:

+
    + +
  • + + channel + + + (Channel) + + + + — +

    to push to.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + + — +

    a future which is fulfilled after the message is pushed to the channel. +May take a moment if the channel is full.

    +
    + +
  • + +
+ +
+
+ +
+

+ + #then_flat_event(*args, &block) ⇒ Event + + + + + + + Originally defined in module + FlatShortcuts + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+
+ +
+

+ + #then_flat_event_on(executor, *args, &block) ⇒ Event + + + + + + + Originally defined in module + FlatShortcuts + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+
+ +
+

+ + #then_flat_future(*args, &block) ⇒ Future + + + + Also known as: + then_flat + + + + + + Originally defined in module + FlatShortcuts + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + #then_flat_future_on(executor, *args, &block) ⇒ Future + + + + Also known as: + then_flat_on + + + + + + Originally defined in module + FlatShortcuts + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/Future/ActorIntegration.html b/docs/1.1.10/Concurrent/Promises/Future/ActorIntegration.html new file mode 100644 index 000000000..7ca7bae8a --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/Future/ActorIntegration.html @@ -0,0 +1,241 @@ + + + + + + + Module: Concurrent::Promises::Future::ActorIntegration + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Promises::Future::ActorIntegration + + + +

+
+ + + + + + + + + +
+
Included in:
+
Concurrent::Promises::Future
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/promises.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ + + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #then_ask(actor) ⇒ Future + + + + + +

+
+

Asks the actor with its value.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + + — +

    new future with the response form the actor

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 14
+
+def then_ask(actor)
+  self.then(actor) { |v, a| a.ask_op(v) }.flat
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/Future/FlatShortcuts.html b/docs/1.1.10/Concurrent/Promises/Future/FlatShortcuts.html new file mode 100644 index 000000000..5e73aea00 --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/Future/FlatShortcuts.html @@ -0,0 +1,469 @@ + + + + + + + Module: Concurrent::Promises::Future::FlatShortcuts + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Promises::Future::FlatShortcuts + + + +

+
+ + + + + + + + + +
+
Included in:
+
Concurrent::Promises::Future
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/promises.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ + + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #then_flat_event(*args, &block) ⇒ Event + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+39
+40
+41
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 39
+
+def then_flat_event(*args, &block)
+  self.then(*args, &block).flat_event
+end
+
+
+ +
+

+ + #then_flat_event_on(executor, *args, &block) ⇒ Event + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+44
+45
+46
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 44
+
+def then_flat_event_on(executor, *args, &block)
+  self.then_on(executor, *args, &block).flat_event
+end
+
+
+ +
+

+ + #then_flat_future(*args, &block) ⇒ Future + + + + Also known as: + then_flat + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 25
+
+def then_flat_future(*args, &block)
+  self.then(*args, &block).flat_future
+end
+
+
+ +
+

+ + #then_flat_future_on(executor, *args, &block) ⇒ Future + + + + Also known as: + then_flat_on + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+32
+33
+34
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 32
+
+def then_flat_future_on(executor, *args, &block)
+  self.then_on(executor, *args, &block).flat_future
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/Future/NewChannelIntegration.html b/docs/1.1.10/Concurrent/Promises/Future/NewChannelIntegration.html new file mode 100644 index 000000000..d495aba4c --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/Future/NewChannelIntegration.html @@ -0,0 +1,262 @@ + + + + + + + Module: Concurrent::Promises::Future::NewChannelIntegration + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Promises::Future::NewChannelIntegration + + + +

+
+ + + + + + + + + +
+
Included in:
+
Concurrent::Promises::Future
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/promises.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ + + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #then_channel_push(channel) ⇒ Future + + + + + +

+
+

Returns a future which is fulfilled after the message is pushed to the channel. +May take a moment if the channel is full.

+ + +
+
+
+

Parameters:

+
    + +
  • + + channel + + + (Channel) + + + + — +

    to push to.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + + — +

    a future which is fulfilled after the message is pushed to the channel. +May take a moment if the channel is full.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+59
+60
+61
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 59
+
+def then_channel_push(channel)
+  self.then(channel) { |value, ch| ch.push_op value }.flat_future
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/Resolvable.html b/docs/1.1.10/Concurrent/Promises/Resolvable.html new file mode 100644 index 000000000..a77fcab3b --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/Resolvable.html @@ -0,0 +1,586 @@ + + + + + + + Module: Concurrent::Promises::Resolvable + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Promises::Resolvable + + + +

+
+ + + + + + + + + +
+
Included in:
+
ResolvableEvent, ResolvableFuture
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb,
+ lib/concurrent-ruby-edge/concurrent/edge/promises.rb
+
+
+ +
+ +

Overview

+
+

Marker module of Future, Event resolved manually.

+ + +
+
+
+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Class Method Details

+ + +
+

+ + .atomic_resolution(resolvable_map) ⇒ true, false + + + + + +

+
+

Resolves all passed events and futures to the given resolutions +if possible (all are unresolved) or none.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolvable_map + + + (Hash{Resolvable=>resolve_arguments}, Array<Array(Resolvable, resolve_arguments)>) + + + + — +

    collection of resolvable events and futures which should be resolved all at once +and what should they be resolved to, examples:

    + +
    { a_resolvable_future1 => [true, :val, nil],
    +  a_resolvable_future2 => [false, nil, :err],
    +  a_resolvable_event => [] }
    +
    + +

    or

    + +
    [[a_resolvable_future1, [true, :val, nil]],
    + [a_resolvable_future2, [false, nil, :err]],
    + [a_resolvable_event, []]]
    +
    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    if success

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 150
+
+def self.atomic_resolution(resolvable_map)
+  # atomic_resolution event => [], future => [true, :v, nil]
+  sorted = resolvable_map.to_a.sort_by { |resolvable, _| locking_order_by resolvable }
+
+  reserved = 0
+  while reserved < sorted.size && sorted[reserved].first.reserve
+    reserved += 1
+  end
+
+  if reserved == sorted.size
+    sorted.each { |resolvable, args| resolvable.resolve(*args, true, true) }
+    true
+  else
+    while reserved > 0
+      reserved -= 1
+      raise 'has to be reserved' unless sorted[reserved].first.release
+    end
+    false
+  end
+end
+
+
+ +
+

+ + .locking_order_by(resolvable) ⇒ Comparable + + + + + +

+
+

Returns an item to sort the resolvable events or futures +by to get the right global locking order of resolvable events or futures.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Comparable) + + + + — +

    an item to sort the resolvable events or futures +by to get the right global locking order of resolvable events or futures

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+128
+129
+130
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 128
+
+def self.locking_order_by(resolvable)
+  resolvable.object_id
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #releasetrue, false + + + + + +

+
+

Returns on successful release of the reservation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    on successful release of the reservation

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+121
+122
+123
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 121
+
+def release
+  compare_and_set_internal_state(RESERVED, PENDING)
+end
+
+
+ +
+

+ + #reservetrue, false + + + + + +

+
+

Reserves the event or future, if reserved others are prevented from resolving it. +Advanced feature. +Be careful about the order of reservation to avoid deadlocks, +the method blocks if the future or event is already reserved +until it is released or resolved.

+ + +
+
+
+ +
+

Examples:

+ + +
f = Concurrent::Promises.resolvable_future
+reserved = f.reserve
+Thread.new { f.resolve true, :val, nil } # fails
+f.resolve true, :val, nil, true if reserved # must be called only if reserved
+ +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    on successful reservation

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+111
+112
+113
+114
+115
+116
+117
+118
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/promises.rb', line 111
+
+def reserve
+  while true
+    return true if compare_and_set_internal_state(PENDING, RESERVED)
+    return false if resolved?
+    # FIXME (pitr-ch 17-Jan-2019): sleep until given up or resolved instead of busy wait
+    Thread.pass
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/ResolvableEvent.html b/docs/1.1.10/Concurrent/Promises/ResolvableEvent.html new file mode 100644 index 000000000..1f78d20c0 --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/ResolvableEvent.html @@ -0,0 +1,651 @@ + + + + + + + Class: Concurrent::Promises::ResolvableEvent + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Promises::ResolvableEvent + + + +

+
+ +
+
Inherits:
+
+ Event + + + show all + +
+
+ + + + + + +
+
Includes:
+
Resolvable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb
+
+ +
+ +

Overview

+
+

A Event which can be resolved by user.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #resolve(raise_on_reassign = true, reserved = false) ⇒ self, false + + + + + +

+
+

Makes the event resolved, which triggers all dependent futures.

+ + +
+
+
+

Parameters:

+
    + +
  • + + raise_on_reassign + + + (Boolean) + + + (defaults to: true) + + + — +

    should method raise exception if already resolved

    +
    + +
  • + +
  • + + reserved + + + (true, false) + + + (defaults to: false) + + + — +

    Set to true if the resolvable is Concurrent::Promises::Resolvable#reserved by you, +marks resolution of reserved resolvable events and futures explicitly. +Advanced feature, ignore unless you use Concurrent::Promises::Resolvable#reserve from edge.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, false) + + + + — +

    false is returner when raise_on_reassign is false and the receiver +is already resolved.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+1313
+1314
+1315
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1313
+
+def resolve(raise_on_reassign = true, reserved = false)
+  resolve_with RESOLVED, raise_on_reassign, reserved
+end
+
+
+ +
+

+ + #wait(timeout = nil, resolve_on_timeout = false) ⇒ self, true, false + + + + + +

+
+

Behaves as AbstractEventFuture#wait but has one additional optional argument +resolve_on_timeout.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolve_on_timeout + + + (true, false) + + + (defaults to: false) + + + — +

    If it times out and the argument is true it will also resolve the event.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, true, false) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1331
+
+def wait(timeout = nil, resolve_on_timeout = false)
+  super(timeout) or if resolve_on_timeout
+                      # if it fails to resolve it was resolved in the meantime
+                      # so return true as if there was no timeout
+                      !resolve(false)
+                    else
+                      false
+                    end
+end
+
+
+ +
+

+ + #with_hidden_resolvableEvent + + + + + +

+
+

Creates new event wrapping receiver, effectively hiding the resolve method.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1320
+1321
+1322
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1320
+
+def with_hidden_resolvable
+  @with_hidden_resolvable ||= EventWrapperPromise.new_blocked_by1(self, @DefaultExecutor).event
+end
+
+
+ +
+

+ + #releasetrue, false + + + + + + + Originally defined in module + Resolvable + + +

+
+

Returns on successful release of the reservation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    on successful release of the reservation

    +
    + +
  • + +
+ +
+
+ +
+

+ + #reservetrue, false + + + + + + + Originally defined in module + Resolvable + + +

+
+

Reserves the event or future, if reserved others are prevented from resolving it. +Advanced feature. +Be careful about the order of reservation to avoid deadlocks, +the method blocks if the future or event is already reserved +until it is released or resolved.

+ + +
+
+
+ +
+

Examples:

+ + +
f = Concurrent::Promises.resolvable_future
+reserved = f.reserve
+Thread.new { f.resolve true, :val, nil } # fails
+f.resolve true, :val, nil, true if reserved # must be called only if reserved
+ +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    on successful reservation

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Promises/ResolvableFuture.html b/docs/1.1.10/Concurrent/Promises/ResolvableFuture.html new file mode 100644 index 000000000..d2f978338 --- /dev/null +++ b/docs/1.1.10/Concurrent/Promises/ResolvableFuture.html @@ -0,0 +1,1881 @@ + + + + + + + Class: Concurrent::Promises::ResolvableFuture + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Promises::ResolvableFuture + + + +

+
+ +
+
Inherits:
+
+ Future + + + show all + +
+
+ + + + + + +
+
Includes:
+
Resolvable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/promises.rb
+
+ +
+ +

Overview

+
+

A Future which can be resolved by user.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #evaluate_to(*args) {|*args| ... } ⇒ self + + + + + +

+
+

Evaluates the block and sets its result as future's value fulfilling, if the block raises +an exception the future rejects with it.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (*args) + + + + — +

    to the block.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1384
+1385
+1386
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1384
+
+def evaluate_to(*args, &block)
+  promise.evaluate_to(*args, block)
+end
+
+
+ +
+

+ + #evaluate_to!(*args) {|*args| ... } ⇒ self + + + + + +

+
+

Evaluates the block and sets its result as future's value fulfilling, if the block raises +an exception the future rejects with it.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + (*args) + + + + — +

    to the block.

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    value

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    also raise reason on rejection.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+1395
+1396
+1397
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1395
+
+def evaluate_to!(*args, &block)
+  promise.evaluate_to(*args, block).wait!
+end
+
+
+ +
+

+ + #fulfill(value, raise_on_reassign = true, reserved = false) ⇒ self, false + + + + + +

+
+

Makes the future fulfilled with value, +which triggers all dependent futures.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + +
  • + +
  • + + raise_on_reassign + + + (Boolean) + + + (defaults to: true) + + + — +

    should method raise exception if already resolved

    +
    + +
  • + +
  • + + reserved + + + (true, false) + + + (defaults to: false) + + + — +

    Set to true if the resolvable is Concurrent::Promises::Resolvable#reserved by you, +marks resolution of reserved resolvable events and futures explicitly. +Advanced feature, ignore unless you use Concurrent::Promises::Resolvable#reserve from edge.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, false) + + + + — +

    false is returner when raise_on_reassign is false and the receiver +is already resolved.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+1364
+1365
+1366
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1364
+
+def fulfill(value, raise_on_reassign = true, reserved = false)
+  resolve_with Fulfilled.new(value), raise_on_reassign, reserved
+end
+
+
+ +
+

+ + #reason(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ Exception, timeout_value, nil + + + + + +

+
+

Behaves as Future#reason but has one additional optional argument +resolve_on_timeout.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolve_on_timeout + + + (::Array(true, Object, nil), ::Array(false, nil, Exception), nil) + + + (defaults to: nil) + + + — +

    If it times out and the argument is not nil it will also resolve the future +to the provided resolution.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Exception, timeout_value, nil) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1492
+
+def reason(timeout = nil, timeout_value = nil, resolve_on_timeout = nil)
+  if wait_until_resolved timeout
+    internal_state.reason
+  else
+    if resolve_on_timeout
+      unless resolve(*resolve_on_timeout, false)
+        # if it fails to resolve it was resolved in the meantime
+        # so return value as if there was no timeout
+        return internal_state.reason
+      end
+    end
+    timeout_value
+  end
+end
+
+
+ +
+

+ + #reject(reason, raise_on_reassign = true, reserved = false) ⇒ self, false + + + + + +

+
+

Makes the future rejected with reason, +which triggers all dependent futures.

+ + +
+
+
+

Parameters:

+
    + +
  • + + reason + + + (Object) + + + +
  • + +
  • + + raise_on_reassign + + + (Boolean) + + + (defaults to: true) + + + — +

    should method raise exception if already resolved

    +
    + +
  • + +
  • + + reserved + + + (true, false) + + + (defaults to: false) + + + — +

    Set to true if the resolvable is Concurrent::Promises::Resolvable#reserved by you, +marks resolution of reserved resolvable events and futures explicitly. +Advanced feature, ignore unless you use Concurrent::Promises::Resolvable#reserve from edge.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, false) + + + + — +

    false is returner when raise_on_reassign is false and the receiver +is already resolved.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+1374
+1375
+1376
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1374
+
+def reject(reason, raise_on_reassign = true, reserved = false)
+  resolve_with Rejected.new(reason), raise_on_reassign, reserved
+end
+
+
+ +
+

+ + #resolve(fulfilled = true, value = nil, reason = nil, raise_on_reassign = true, reserved = false) ⇒ self, false + + + + + +

+
+

Makes the future resolved with result of triplet fulfilled?, value, reason, +which triggers all dependent futures.

+ + +
+
+
+

Parameters:

+
    + +
  • + + fulfilled + + + (true, false) + + + (defaults to: true) + + +
  • + +
  • + + value + + + (Object) + + + (defaults to: nil) + + +
  • + +
  • + + reason + + + (Object) + + + (defaults to: nil) + + +
  • + +
  • + + raise_on_reassign + + + (Boolean) + + + (defaults to: true) + + + — +

    should method raise exception if already resolved

    +
    + +
  • + +
  • + + reserved + + + (true, false) + + + (defaults to: false) + + + — +

    Set to true if the resolvable is Concurrent::Promises::Resolvable#reserved by you, +marks resolution of reserved resolvable events and futures explicitly. +Advanced feature, ignore unless you use Concurrent::Promises::Resolvable#reserve from edge.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, false) + + + + — +

    false is returner when raise_on_reassign is false and the receiver +is already resolved.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+1354
+1355
+1356
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1354
+
+def resolve(fulfilled = true, value = nil, reason = nil, raise_on_reassign = true, reserved = false)
+  resolve_with(fulfilled ? Fulfilled.new(value) : Rejected.new(reason), raise_on_reassign, reserved)
+end
+
+
+ +
+

+ + #result(timeout = nil, resolve_on_timeout = nil) ⇒ ::Array(Boolean, Object, Exception), nil + + + + + +

+
+

Behaves as Future#result but has one additional optional argument +resolve_on_timeout.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolve_on_timeout + + + (::Array(true, Object, nil), ::Array(false, nil, Exception), nil) + + + (defaults to: nil) + + + — +

    If it times out and the argument is not nil it will also resolve the future +to the provided resolution.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (::Array(Boolean, Object, Exception), nil) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1513
+
+def result(timeout = nil, resolve_on_timeout = nil)
+  if wait_until_resolved timeout
+    internal_state.result
+  else
+    if resolve_on_timeout
+      unless resolve(*resolve_on_timeout, false)
+        # if it fails to resolve it was resolved in the meantime
+        # so return value as if there was no timeout
+        internal_state.result
+      end
+    end
+    # otherwise returns nil
+  end
+end
+
+
+ +
+

+ + #value(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ Object, timeout_value, nil + + + + + +

+
+

Behaves as Future#value but has one additional optional argument +resolve_on_timeout.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolve_on_timeout + + + (::Array(true, Object, nil), ::Array(false, nil, Exception), nil) + + + (defaults to: nil) + + + — +

    If it times out and the argument is not nil it will also resolve the future +to the provided resolution.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, timeout_value, nil) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1448
+
+def value(timeout = nil, timeout_value = nil, resolve_on_timeout = nil)
+  if wait_until_resolved timeout
+    internal_state.value
+  else
+    if resolve_on_timeout
+      unless resolve(*resolve_on_timeout, false)
+        # if it fails to resolve it was resolved in the meantime
+        # so return value as if there was no timeout
+        return internal_state.value
+      end
+    end
+    timeout_value
+  end
+end
+
+
+ +
+

+ + #value!(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ Object, timeout_value, nil + + + + + +

+
+

Behaves as Future#value! but has one additional optional argument +resolve_on_timeout.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolve_on_timeout + + + (::Array(true, Object, nil), ::Array(false, nil, Exception), nil) + + + (defaults to: nil) + + + — +

    If it times out and the argument is not nil it will also resolve the future +to the provided resolution.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, timeout_value, nil) + + + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    #reason on rejection

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1470
+
+def value!(timeout = nil, timeout_value = nil, resolve_on_timeout = nil)
+  if wait_until_resolved! timeout
+    internal_state.value
+  else
+    if resolve_on_timeout
+      unless resolve(*resolve_on_timeout, false)
+        # if it fails to resolve it was resolved in the meantime
+        # so return value as if there was no timeout
+        raise self if rejected?
+        return internal_state.value
+      end
+    end
+    timeout_value
+  end
+end
+
+
+ +
+

+ + #wait(timeout = nil, resolve_on_timeout = nil) ⇒ self, true, false + + + + + +

+
+

Behaves as AbstractEventFuture#wait but has one additional optional argument +resolve_on_timeout.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolve_on_timeout + + + (::Array(true, Object, nil), ::Array(false, nil, Exception), nil) + + + (defaults to: nil) + + + — +

    If it times out and the argument is not nil it will also resolve the future +to the provided resolution.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, true, false) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1410
+
+def wait(timeout = nil, resolve_on_timeout = nil)
+  super(timeout) or if resolve_on_timeout
+                      # if it fails to resolve it was resolved in the meantime
+                      # so return true as if there was no timeout
+                      !resolve(*resolve_on_timeout, false)
+                    else
+                      false
+                    end
+end
+
+
+ +
+

+ + #wait!(timeout = nil, resolve_on_timeout = nil) ⇒ self, true, false + + + + + +

+
+

Behaves as Future#wait! but has one additional optional argument +resolve_on_timeout.

+ + +
+
+
+

Parameters:

+
    + +
  • + + resolve_on_timeout + + + (::Array(true, Object, nil), ::Array(false, nil, Exception), nil) + + + (defaults to: nil) + + + — +

    If it times out and the argument is not nil it will also resolve the future +to the provided resolution.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self, true, false) + + + +
  • + +
+

Raises:

+
    + +
  • + + + (Exception) + + + + — +

    #reason on rejection

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1427
+
+def wait!(timeout = nil, resolve_on_timeout = nil)
+  super(timeout) or if resolve_on_timeout
+                      if resolve(*resolve_on_timeout, false)
+                        false
+                      else
+                        # if it fails to resolve it was resolved in the meantime
+                        # so return true as if there was no timeout
+                        raise self if rejected?
+                        true
+                      end
+                    else
+                      false
+                    end
+end
+
+
+ +
+

+ + #with_hidden_resolvableFuture + + + + + +

+
+

Creates new future wrapping receiver, effectively hiding the resolve method and similar.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+ + + + +
+
+
+
+1531
+1532
+1533
+
+
# File 'lib/concurrent-ruby/concurrent/promises.rb', line 1531
+
+def with_hidden_resolvable
+  @with_hidden_resolvable ||= FutureWrapperPromise.new_blocked_by1(self, @DefaultExecutor).future
+end
+
+
+ +
+

+ + #releasetrue, false + + + + + + + Originally defined in module + Resolvable + + +

+
+

Returns on successful release of the reservation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    on successful release of the reservation

    +
    + +
  • + +
+ +
+
+ +
+

+ + #reservetrue, false + + + + + + + Originally defined in module + Resolvable + + +

+
+

Reserves the event or future, if reserved others are prevented from resolving it. +Advanced feature. +Be careful about the order of reservation to avoid deadlocks, +the method blocks if the future or event is already reserved +until it is released or resolved.

+ + +
+
+
+ +
+

Examples:

+ + +
f = Concurrent::Promises.resolvable_future
+reserved = f.reserve
+Thread.new { f.resolve true, :val, nil } # fails
+f.resolve true, :val, nil, true if reserved # must be called only if reserved
+ +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    on successful reservation

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ReInclude.html b/docs/1.1.10/Concurrent/ReInclude.html new file mode 100644 index 000000000..369d7037d --- /dev/null +++ b/docs/1.1.10/Concurrent/ReInclude.html @@ -0,0 +1,164 @@ + + + + + + + Module: Concurrent::ReInclude + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::ReInclude + + + +

+
+ + + + + + + + + +
+
Included in:
+
Promises::FactoryMethods
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/re_include.rb
+
+ +
+ +

Overview

+
+

Methods form module A included to a module B, which is already included into class C, +will not be visible in the C class. If this module is extended to B then A's methods +are correctly made visible to C.

+ + +
+
+
+ +
+

Examples:

+ + +
module A
+  def a
+    :a
+  end
+end
+
+module B1
+end
+
+class C1
+  include B1
+end
+
+module B2
+  extend Concurrent::ReInclude
+end
+
+class C2
+  include B2
+end
+
+B1.send :include, A
+B2.send :include, A
+
+C1.new.respond_to? :a # => false
+C2.new.respond_to? :a # => true
+ +
+ + +
+ + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ReadWriteLock.html b/docs/1.1.10/Concurrent/ReadWriteLock.html new file mode 100644 index 000000000..04d7970f6 --- /dev/null +++ b/docs/1.1.10/Concurrent/ReadWriteLock.html @@ -0,0 +1,1199 @@ + + + + + + + Class: Concurrent::ReadWriteLock + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ReadWriteLock + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Do not try to acquire the write lock while already holding a read lock +or try to acquire the write lock while you already have it. +This will lead to deadlock

+
+
+ +

Ruby read-write lock implementation

+ +

Allows any number of concurrent readers, but only one concurrent writer +(And if the "write" lock is taken, any readers who come along will have to wait)

+ +

If readers are already active when a writer comes along, the writer will wait for +all the readers to finish before going ahead. +Any additional readers that come when the writer is already waiting, will also +wait (so writers are not starved).

+ +

This implementation is based on java.util.concurrent.ReentrantReadWriteLock.

+ + +
+
+
+ +
+

Examples:

+ + +
lock = Concurrent::ReadWriteLock.new
+lock.with_read_lock  { data.retrieve }
+lock.with_write_lock { data.modify! }
+ +
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initializeReadWriteLock + + + + + +

+
+

Create a new ReadWriteLock in the unlocked state.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+58
+59
+60
+61
+62
+63
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 58
+
+def initialize
+  super()
+  @Counter   = AtomicFixnum.new(0) # single integer which represents lock state
+  @ReadLock  = Synchronization::Lock.new
+  @WriteLock = Synchronization::Lock.new
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #acquire_read_lockBoolean + + + + + +

+
+

Acquire a read lock. If a write lock has been acquired will block until +it is released. Will not block if other read locks have been acquired.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully acquired

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 110
+
+def acquire_read_lock
+  while true
+    c = @Counter.value
+    raise ResourceLimitError.new('Too many reader threads') if max_readers?(c)
+
+    # If a writer is waiting when we first queue up, we need to wait
+    if waiting_writer?(c)
+      @ReadLock.wait_until { !waiting_writer? }
+
+      # after a reader has waited once, they are allowed to "barge" ahead of waiting writers
+      # but if a writer is *running*, the reader still needs to wait (naturally)
+      while true
+        c = @Counter.value
+        if running_writer?(c)
+          @ReadLock.wait_until { !running_writer? }
+        else
+          return if @Counter.compare_and_set(c, c+1)
+        end
+      end
+    else
+      break if @Counter.compare_and_set(c, c+1)
+    end
+  end
+  true
+end
+
+
+ +
+

+ + #acquire_write_lockBoolean + + + + + +

+
+

Acquire a write lock. Will block and wait for all active readers and writers.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully acquired

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 159
+
+def acquire_write_lock
+  while true
+    c = @Counter.value
+    raise ResourceLimitError.new('Too many writer threads') if max_writers?(c)
+
+    if c == 0 # no readers OR writers running
+      # if we successfully swap the RUNNING_WRITER bit on, then we can go ahead
+      break if @Counter.compare_and_set(0, RUNNING_WRITER)
+    elsif @Counter.compare_and_set(c, c+WAITING_WRITER)
+      while true
+        # Now we have successfully incremented, so no more readers will be able to increment
+        #   (they will wait instead)
+        # However, readers OR writers could decrement right here, OR another writer could increment
+        @WriteLock.wait_until do
+          # So we have to do another check inside the synchronized section
+          # If a writer OR reader is running, then go to sleep
+          c = @Counter.value
+          !running_writer?(c) && !running_readers?(c)
+        end
+
+        # We just came out of a wait
+        # If we successfully turn the RUNNING_WRITER bit on with an atomic swap,
+        # Then we are OK to stop waiting and go ahead
+        # Otherwise go back and wait again
+        c = @Counter.value
+        break if !running_writer?(c) && !running_readers?(c) && @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER)
+      end
+      break
+    end
+  end
+  true
+end
+
+
+ +
+

+ + #has_waiters?Boolean + + + + + +

+
+

Queries whether any threads are waiting to acquire the read or write lock.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if any threads are waiting for a lock else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+213
+214
+215
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 213
+
+def has_waiters?
+  waiting_writer?(@Counter.value)
+end
+
+
+ +
+

+ + #release_read_lockBoolean + + + + + +

+
+

Release a previously acquired read lock.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully released

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 139
+
+def release_read_lock
+  while true
+    c = @Counter.value
+    if @Counter.compare_and_set(c, c-1)
+      # If one or more writers were waiting, and we were the last reader, wake a writer up
+      if waiting_writer?(c) && running_readers(c) == 1
+        @WriteLock.signal
+      end
+      break
+    end
+  end
+  true
+end
+
+
+ +
+

+ + #release_write_lockBoolean + + + + + +

+
+

Release a previously acquired write lock.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully released

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+195
+196
+197
+198
+199
+200
+201
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 195
+
+def release_write_lock
+  return true unless running_writer?
+  c = @Counter.update { |counter| counter - RUNNING_WRITER }
+  @ReadLock.broadcast
+  @WriteLock.signal if waiting_writers(c) > 0
+  true
+end
+
+
+ +
+

+ + #with_read_lock { ... } ⇒ Object + + + + + +

+
+

Execute a block operation within a read lock.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the task to be performed within the lock.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the result of the block operation.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    when no block is given.

    +
    + +
  • + +
  • + + + (Concurrent::ResourceLimitError) + + + + — +

    if the maximum number of readers +is exceeded.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+74
+75
+76
+77
+78
+79
+80
+81
+82
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 74
+
+def with_read_lock
+  raise ArgumentError.new('no block given') unless block_given?
+  acquire_read_lock
+  begin
+    yield
+  ensure
+    release_read_lock
+  end
+end
+
+
+ +
+

+ + #with_write_lock { ... } ⇒ Object + + + + + +

+
+

Execute a block operation within a write lock.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the task to be performed within the lock.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the result of the block operation.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    when no block is given.

    +
    + +
  • + +
  • + + + (Concurrent::ResourceLimitError) + + + + — +

    if the maximum number of readers +is exceeded.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+93
+94
+95
+96
+97
+98
+99
+100
+101
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 93
+
+def with_write_lock
+  raise ArgumentError.new('no block given') unless block_given?
+  acquire_write_lock
+  begin
+    yield
+  ensure
+    release_write_lock
+  end
+end
+
+
+ +
+

+ + #write_locked?Boolean + + + + + +

+
+

Queries if the write lock is held by any thread.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the write lock is held else false`

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+206
+207
+208
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb', line 206
+
+def write_locked?
+  @Counter.value >= RUNNING_WRITER
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ReentrantReadWriteLock.html b/docs/1.1.10/Concurrent/ReentrantReadWriteLock.html new file mode 100644 index 000000000..843273652 --- /dev/null +++ b/docs/1.1.10/Concurrent/ReentrantReadWriteLock.html @@ -0,0 +1,1360 @@ + + + + + + + Class: Concurrent::ReentrantReadWriteLock + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ReentrantReadWriteLock + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb
+
+ +
+ +

Overview

+
+

Re-entrant read-write lock implementation

+ +

Allows any number of concurrent readers, but only one concurrent writer +(And while the "write" lock is taken, no read locks can be obtained either. +Hence, the write lock can also be called an "exclusive" lock.)

+ +

If another thread has taken a read lock, any thread which wants a write lock +will block until all the readers release their locks. However, once a thread +starts waiting to obtain a write lock, any additional readers that come along +will also wait (so writers are not starved).

+ +

A thread can acquire both a read and write lock at the same time. A thread can +also acquire a read lock OR a write lock more than once. Only when the read (or +write) lock is released as many times as it was acquired, will the thread +actually let it go, allowing other threads which might have been waiting +to proceed. Therefore the lock can be upgraded by first acquiring +read lock and then write lock and that the lock can be downgraded by first +having both read and write lock a releasing just the write lock.

+ +

If both read and write locks are acquired by the same thread, it is not strictly +necessary to release them in the same order they were acquired. In other words, +the following code is legal:

+ +

This implementation was inspired by java.util.concurrent.ReentrantReadWriteLock.

+ + +
+
+
+ +
+

Examples:

+ + +
lock = Concurrent::ReentrantReadWriteLock.new
+lock.acquire_write_lock
+lock.acquire_read_lock
+lock.release_write_lock
+# At this point, the current thread is holding only a read lock, not a write
+# lock. So other threads can take read locks, but not a write lock.
+lock.release_read_lock
+# Now the current thread is not holding either a read or write lock, so
+# another thread could potentially acquire a write lock.
+ + +
lock = Concurrent::ReentrantReadWriteLock.new
+lock.with_read_lock  { data.retrieve }
+lock.with_write_lock { data.modify! }
+ +
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initializeReentrantReadWriteLock + + + + + +

+
+

Create a new ReentrantReadWriteLock in the unlocked state.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+107
+108
+109
+110
+111
+112
+113
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 107
+
+def initialize
+  super()
+  @Counter    = AtomicFixnum.new(0)       # single integer which represents lock state
+  @ReadQueue  = Synchronization::Lock.new # used to queue waiting readers
+  @WriteQueue = Synchronization::Lock.new # used to queue waiting writers
+  @HeldCount  = ThreadLocalVar.new(0)     # indicates # of R & W locks held by this thread
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #acquire_read_lockBoolean + + + + + +

+
+

Acquire a read lock. If a write lock is held by another thread, will block +until it is released.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully acquired

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 160
+
+def acquire_read_lock
+  if (held = @HeldCount.value) > 0
+    # If we already have a lock, there's no need to wait
+    if held & READ_LOCK_MASK == 0
+      # But we do need to update the counter, if we were holding a write
+      #   lock but not a read lock
+      @Counter.update { |c| c + 1 }
+    end
+    @HeldCount.value = held + 1
+    return true
+  end
+
+  while true
+    c = @Counter.value
+    raise ResourceLimitError.new('Too many reader threads') if max_readers?(c)
+
+    # If a writer is waiting OR running when we first queue up, we need to wait
+    if waiting_or_running_writer?(c)
+      # Before going to sleep, check again with the ReadQueue mutex held
+      @ReadQueue.synchronize do
+        @ReadQueue.ns_wait if waiting_or_running_writer?
+      end
+      # Note: the above 'synchronize' block could have used #wait_until,
+      #   but that waits repeatedly in a loop, checking the wait condition
+      #   each time it wakes up (to protect against spurious wakeups)
+      # But we are already in a loop, which is only broken when we successfully
+      #   acquire the lock! So we don't care about spurious wakeups, and would
+      #   rather not pay the extra overhead of using #wait_until
+
+      # After a reader has waited once, they are allowed to "barge" ahead of waiting writers
+      # But if a writer is *running*, the reader still needs to wait (naturally)
+      while true
+        c = @Counter.value
+        if running_writer?(c)
+          @ReadQueue.synchronize do
+            @ReadQueue.ns_wait if running_writer?
+          end
+        elsif @Counter.compare_and_set(c, c+1)
+          @HeldCount.value = held + 1
+          return true
+        end
+      end
+    elsif @Counter.compare_and_set(c, c+1)
+      @HeldCount.value = held + 1
+      return true
+    end
+  end
+end
+
+
+ +
+

+ + #acquire_write_lockBoolean + + + + + +

+
+

Acquire a write lock. Will block and wait for all active readers and writers.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully acquired

    +
    + +
  • + +
+

Raises:

+ + +
+ + + + +
+
+
+
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 255
+
+def acquire_write_lock
+  if (held = @HeldCount.value) >= WRITE_LOCK_HELD
+    # if we already have a write (exclusive) lock, there's no need to wait
+    @HeldCount.value = held + WRITE_LOCK_HELD
+    return true
+  end
+
+  while true
+    c = @Counter.value
+    raise ResourceLimitError.new('Too many writer threads') if max_writers?(c)
+
+    # To go ahead and take the lock without waiting, there must be no writer
+    #   running right now, AND no writers who came before us still waiting to
+    #   acquire the lock
+    # Additionally, if any read locks have been taken, we must hold all of them
+    if held > 0 && @Counter.compare_and_set(1, c+RUNNING_WRITER)
+      # If we are the only one reader and successfully swap the RUNNING_WRITER bit on, then we can go ahead
+      @HeldCount.value = held + WRITE_LOCK_HELD
+      return true
+    elsif @Counter.compare_and_set(c, c+WAITING_WRITER)
+      while true
+        # Now we have successfully incremented, so no more readers will be able to increment
+        #   (they will wait instead)
+        # However, readers OR writers could decrement right here
+        @WriteQueue.synchronize do
+          # So we have to do another check inside the synchronized section
+          # If a writer OR another reader is running, then go to sleep
+          c = @Counter.value
+          @WriteQueue.ns_wait if running_writer?(c) || running_readers(c) != held
+        end
+        # Note: if you are thinking of replacing the above 'synchronize' block
+        # with #wait_until, read the comment in #acquire_read_lock first!
+
+        # We just came out of a wait
+        # If we successfully turn the RUNNING_WRITER bit on with an atomic swap,
+        #   then we are OK to stop waiting and go ahead
+        # Otherwise go back and wait again
+        c = @Counter.value
+        if !running_writer?(c) &&
+           running_readers(c) == held &&
+           @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER)
+          @HeldCount.value = held + WRITE_LOCK_HELD
+          return true
+        end
+      end
+    end
+  end
+end
+
+
+ +
+

+ + #release_read_lockBoolean + + + + + +

+
+

Release a previously acquired read lock.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully released

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 234
+
+def release_read_lock
+  held = @HeldCount.value = @HeldCount.value - 1
+  rlocks_held = held & READ_LOCK_MASK
+  if rlocks_held == 0
+    c = @Counter.update { |counter| counter - 1 }
+    # If one or more writers were waiting, and we were the last reader, wake a writer up
+    if waiting_or_running_writer?(c) && running_readers(c) == 0
+      @WriteQueue.signal
+    end
+  elsif rlocks_held == READ_LOCK_MASK
+    raise IllegalOperationError, "Cannot release a read lock which is not held"
+  end
+  true
+end
+
+
+ +
+

+ + #release_write_lockBoolean + + + + + +

+
+

Release a previously acquired write lock.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully released

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 327
+
+def release_write_lock
+  held = @HeldCount.value = @HeldCount.value - WRITE_LOCK_HELD
+  wlocks_held = held & WRITE_LOCK_MASK
+  if wlocks_held == 0
+    c = @Counter.update { |counter| counter - RUNNING_WRITER }
+    @ReadQueue.broadcast
+    @WriteQueue.signal if waiting_writers(c) > 0
+  elsif wlocks_held == WRITE_LOCK_MASK
+    raise IllegalOperationError, "Cannot release a write lock which is not held"
+  end
+  true
+end
+
+
+ +
+

+ + #try_read_lockBoolean + + + + + +

+
+

Try to acquire a read lock and return true if we succeed. If it cannot be +acquired immediately, return false.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully acquired

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 213
+
+def try_read_lock
+  if (held = @HeldCount.value) > 0
+    if held & READ_LOCK_MASK == 0
+      # If we hold a write lock, but not a read lock...
+      @Counter.update { |c| c + 1 }
+    end
+    @HeldCount.value = held + 1
+    return true
+  else
+    c = @Counter.value
+    if !waiting_or_running_writer?(c) && @Counter.compare_and_set(c, c+1)
+      @HeldCount.value = held + 1
+      return true
+    end
+  end
+  false
+end
+
+
+ +
+

+ + #try_write_lockBoolean + + + + + +

+
+

Try to acquire a write lock and return true if we succeed. If it cannot be +acquired immediately, return false.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the lock is successfully acquired

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 308
+
+def try_write_lock
+  if (held = @HeldCount.value) >= WRITE_LOCK_HELD
+    @HeldCount.value = held + WRITE_LOCK_HELD
+    return true
+  else
+    c = @Counter.value
+    if !waiting_or_running_writer?(c) &&
+       running_readers(c) == held &&
+       @Counter.compare_and_set(c, c+RUNNING_WRITER)
+       @HeldCount.value = held + WRITE_LOCK_HELD
+      return true
+    end
+  end
+  false
+end
+
+
+ +
+

+ + #with_read_lock { ... } ⇒ Object + + + + + +

+
+

Execute a block operation within a read lock.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the task to be performed within the lock.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the result of the block operation.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    when no block is given.

    +
    + +
  • + +
  • + + + (Concurrent::ResourceLimitError) + + + + — +

    if the maximum number of readers +is exceeded.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+124
+125
+126
+127
+128
+129
+130
+131
+132
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 124
+
+def with_read_lock
+  raise ArgumentError.new('no block given') unless block_given?
+  acquire_read_lock
+  begin
+    yield
+  ensure
+    release_read_lock
+  end
+end
+
+
+ +
+

+ + #with_write_lock { ... } ⇒ Object + + + + + +

+
+

Execute a block operation within a write lock.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the task to be performed within the lock.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the result of the block operation.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    when no block is given.

    +
    + +
  • + +
  • + + + (Concurrent::ResourceLimitError) + + + + — +

    if the maximum number of readers +is exceeded.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+143
+144
+145
+146
+147
+148
+149
+150
+151
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb', line 143
+
+def with_write_lock
+  raise ArgumentError.new('no block given') unless block_given?
+  acquire_write_lock
+  begin
+    yield
+  ensure
+    release_write_lock
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/SafeTaskExecutor.html b/docs/1.1.10/Concurrent/SafeTaskExecutor.html new file mode 100644 index 000000000..0a6ea69b0 --- /dev/null +++ b/docs/1.1.10/Concurrent/SafeTaskExecutor.html @@ -0,0 +1,337 @@ + + + + + + + Class: Concurrent::SafeTaskExecutor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::SafeTaskExecutor + + + +

+
+ +
+
Inherits:
+
+ Concurrent::Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb
+
+ +
+ +

Overview

+
+

A simple utility class that executes a callable and returns and array of three elements: +success - indicating if the callable has been executed without errors +value - filled by the callable result if it has been executed without errors, nil otherwise +reason - the error risen by the callable if it has been executed with errors, nil otherwise

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(task, opts = {}) ⇒ SafeTaskExecutor + + + + + +

+
+

Returns a new instance of SafeTaskExecutor.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+11
+12
+13
+14
+15
+
+
# File 'lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb', line 11
+
+def initialize(task, opts = {})
+  @task            = task
+  @exception_class = opts.fetch(:rescue_exception, false) ? Exception : StandardError
+  super() # ensures visibility
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #execute(*args) ⇒ Array + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Array) + + + +
  • + +
+ +
+ + + + +
+
+
+
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+
+
# File 'lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb', line 18
+
+def execute(*args)
+  success = true
+  value   = reason = nil
+
+  synchronize do
+    begin
+      value   = @task.call(*args)
+      success = true
+    rescue @exception_class => ex
+      reason  = ex
+      success = false
+    end
+  end
+
+  [success, value, reason]
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ScheduledTask.html b/docs/1.1.10/Concurrent/ScheduledTask.html new file mode 100644 index 000000000..f6efe64b8 --- /dev/null +++ b/docs/1.1.10/Concurrent/ScheduledTask.html @@ -0,0 +1,1604 @@ + + + + + + + Class: Concurrent::ScheduledTask + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ScheduledTask + + + +

+
+ +
+
Inherits:
+
+ IVar + +
    +
  • Object
  • + + + + + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Comparable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/scheduled_task.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Time calculations on all platforms and languages are sensitive to +changes to the system clock. To alleviate the potential problems +associated with changing the system clock while an application is running, +most modern operating systems provide a monotonic clock that operates +independently of the system clock. A monotonic clock cannot be used to +determine human-friendly clock times. A monotonic clock is used exclusively +for calculating time intervals. Not all Ruby platforms provide access to an +operating system monotonic clock. On these platforms a pure-Ruby monotonic +clock will be used as a fallback. An operating system monotonic clock is both +faster and more reliable than the pure-Ruby implementation. The pure-Ruby +implementation should be fast and reliable enough for most non-realtime +operations. At this time the common Ruby platforms that provide access to an +operating system monotonic clock are MRI 2.1 and above and JRuby (all versions).

+
+
+ +

ScheduledTask is a close relative of Concurrent::Future but with one +important difference: A Future is set to execute as soon as possible +whereas a ScheduledTask is set to execute after a specified delay. This +implementation is loosely based on Java's +ScheduledExecutorService. +It is a more feature-rich variant of timer.

+ +

The intended schedule time of task execution is set on object construction +with the delay argument. The delay is a numeric (floating point or integer) +representing a number of seconds in the future. Any other value or a numeric +equal to or less than zero will result in an exception. The actual schedule +time of task execution is set when the execute method is called.

+ +

The constructor can also be given zero or more processing options. Currently +the only supported options are those recognized by the +Dereferenceable module.

+ +

The final constructor argument is a block representing the task to be performed. +If no block is given an ArgumentError will be raised.

+ +

States

+ +

ScheduledTask mixes in the Obligation module thus giving it +"future" behavior. This includes the expected lifecycle states. ScheduledTask +has one additional state, however. While the task (block) is being executed the +state of the object will be :processing. This additional state is necessary +because it has implications for task cancellation.

+ +

Cancellation

+ +

A :pending task can be cancelled using the #cancel method. A task in any +other state, including :processing, cannot be cancelled. The #cancel +method returns a boolean indicating the success of the cancellation attempt. +A cancelled ScheduledTask cannot be restarted. It is immutable.

+ +

Obligation and Observation

+ +

The result of a ScheduledTask can be obtained either synchronously or +asynchronously. ScheduledTask mixes in both the Obligation +module and the +Observable +module from the Ruby standard library. With one exception ScheduledTask +behaves identically to Future with regard to these modules.

+ +

Copy Options

+ +

Object references in Ruby are mutable. This can lead to serious +problems when the Concern::Obligation#value of an object is a mutable reference. Which +is always the case unless the value is a Fixnum, Symbol, or similar +"primitive" data type. Each instance can be configured with a few +options that can help protect the program from potentially dangerous +operations. Each of these options can be optionally set when the object +instance is created:

+ +
    +
  • :dup_on_deref When true the object will call the #dup method on +the value object every time the #value method is called +(default: false)
  • +
  • :freeze_on_deref When true the object will call the #freeze +method on the value object every time the #value method is called +(default: false)
  • +
  • :copy_on_deref When given a Proc object the Proc will be run +every time the #value method is called. The Proc will be given +the current value as its only argument and the result returned by +the block will be the return value of the #value call. When nil +this option will be ignored (default: nil)
  • +
+ +

When multiple deref options are set the order of operations is strictly defined. +The order of deref operations is:

+ +
    +
  • :copy_on_deref
  • +
  • :dup_on_deref
  • +
  • :freeze_on_deref
  • +
+ +

Because of this ordering there is no need to #freeze an object created by a +provided :copy_on_deref block. Simply set :freeze_on_deref to true. +Setting both :dup_on_deref to true and :freeze_on_deref to true is +as close to the behavior of a "pure" functional language (like Erlang, Clojure, +or Haskell) as we are likely to get in Ruby.

+ + +
+
+
+ +
+

Examples:

+ + +

Basic usage

+

+ +

+require 'concurrent'
+require 'csv'
+require 'open-uri'
+
+class Ticker
+  def get_year_end_closing(symbol, year, api_key)
+   uri = "https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=#{symbol}&apikey=#{api_key}&datatype=csv"
+   data = []
+   csv = URI.parse(uri).read
+   if csv.include?('call frequency')
+     return :rate_limit_exceeded
+   end
+   CSV.parse(csv, headers: true) do |row|
+     data << row['close'].to_f if row['timestamp'].include?(year.to_s)
+   end
+   year_end = data.first
+   year_end
+ rescue => e
+   p e
+ end
+end
+
+api_key = ENV['ALPHAVANTAGE_KEY']
+abort(error_message) unless api_key
+
+# Future
+price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013, api_key) }
+price.state #=> :pending
+price.pending? #=> true
+price.value(0) #=> nil (does not block)
+
+ sleep(1)    # do other stuff
+
+price.value #=> 63.65 (after blocking if necessary)
+price.state #=> :fulfilled
+price.fulfilled? #=> true
+price.value #=> 63.65
+ + +

Successful task execution

+

+ +

+task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }
+task.state         #=> :unscheduled
+task.execute
+task.state         #=> pending
+
+# wait for it...
+sleep(3)
+
+task.unscheduled? #=> false
+task.pending?     #=> false
+task.fulfilled?   #=> true
+task.rejected?    #=> false
+task.value        #=> 'What does the fox say?'
+ + +

One line creation and execution

+

+ +

+task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }.execute
+task.state         #=> pending
+
+task = Concurrent::ScheduledTask.execute(2){ 'What do you get when you multiply 6 by 9?' }
+task.state         #=> pending
+ + +

Failed task execution

+

+ +

+task = Concurrent::ScheduledTask.execute(2){ raise StandardError.new('Call me maybe?') }
+task.pending?      #=> true
+
+# wait for it...
+sleep(3)
+
+task.unscheduled? #=> false
+task.pending?     #=> false
+task.fulfilled?   #=> false
+task.rejected?    #=> true
+task.value        #=> nil
+task.reason       #=> #<StandardError: Call me maybe?>
+ + +

Task execution with observation

+

+ +

+observer = Class.new{
+  def update(time, value, reason)
+    puts "The task completed at #{time} with value '#{value}'"
+  end
+}.new
+
+task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }
+task.add_observer(observer)
+task.execute
+task.pending?      #=> true
+
+# wait for it...
+sleep(3)
+
+#>> The task completed at 2013-11-07 12:26:09 -0500 with value 'What does the fox say?'
+ +
+ + +

See Also:

+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(delay, opts = {}) { ... } ⇒ ScheduledTask + + + + + +

+
+

Schedule a task for execution at a specified future time.

+ + +
+
+
+

Parameters:

+
    + +
  • + + delay + + + (Float) + + + + — +

    the number of seconds to wait for before executing the task

    +
    + +
  • + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Obligation#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
  • + :args + (object, Array) + + + + + —

    zero or more arguments to be passed the task +block on execution

    +
    + +
  • + +
+ + +

Yields:

+
    + +
  • + + + + + + + +

    the task to be performed

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    When no block is given

    +
    + +
  • + +
  • + + + (ArgumentError) + + + + — +

    When given a time that is in the past

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 178
+
+def initialize(delay, opts = {}, &task)
+  raise ArgumentError.new('no block given') unless block_given?
+  raise ArgumentError.new('seconds must be greater than zero') if delay.to_f < 0.0
+
+  super(NULL, opts, &nil)
+
+  synchronize do
+    ns_set_state(:unscheduled)
+    @parent = opts.fetch(:timer_set, Concurrent.global_timer_set)
+    @args = get_arguments_from(opts)
+    @delay = delay.to_f
+    @task = task
+    @time = nil
+    @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor
+    self.observers = Collection::CopyOnNotifyObserverSet.new
+  end
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .execute(delay, opts = {}, &task) ⇒ ScheduledTask + + + + + +

+
+

Create a new ScheduledTask object with the given block, execute it, and return the +:pending object.

+ + +
+
+
+

Parameters:

+
    + +
  • + + delay + + + (Float) + + + + — +

    the number of seconds to wait for before executing the task

    +
    + +
  • + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to define the behavior at update and deref +and to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :io returns the global pool for +long, blocking (IO) tasks, :fast returns the global pool for short, fast +operations, and :immediate returns the global ImmediateExecutor object.

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Obligation#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Obligation#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
+ + + + +

Returns:

+
    + +
  • + + + (ScheduledTask) + + + + — +

    the newly created ScheduledTask in the :pending state

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if no block is given

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+290
+291
+292
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 290
+
+def self.execute(delay, opts = {}, &task)
+  new(delay, opts, &task).execute
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #cancelBoolean + + + + + +

+
+

Cancel this task and prevent it from executing. A task can only be +cancelled if it is pending or unscheduled.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if successfully cancelled else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 235
+
+def cancel
+  if compare_and_set_state(:cancelled, :pending, :unscheduled)
+    complete(false, nil, CancelledOperationError.new)
+    # To avoid deadlocks this call must occur outside of #synchronize
+    # Changing the state above should prevent redundant calls
+    @parent.send(:remove_task, self)
+  else
+    false
+  end
+end
+
+
+ +
+

+ + #cancelled?Boolean + + + + + +

+
+

Has the task been cancelled?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the task is in the given state else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+220
+221
+222
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 220
+
+def cancelled?
+  synchronize { ns_check_state?(:cancelled) }
+end
+
+
+ +
+

+ + #executeScheduledTask + + + + + +

+
+

Execute an :unscheduled ScheduledTask. Immediately sets the state to :pending +and starts counting down toward execution. Does nothing if the ScheduledTask is +in any state other than :unscheduled.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (ScheduledTask) + + + + — +

    a reference to self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+273
+274
+275
+276
+277
+278
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 273
+
+def execute
+  if compare_and_set_state(:pending, :unscheduled)
+    synchronize{ ns_schedule(@delay) }
+  end
+  self
+end
+
+
+ +
+

+ + #initial_delayFloat + + + + + +

+
+

The delay value given at instanciation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Float) + + + + — +

    the initial delay.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+199
+200
+201
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 199
+
+def initial_delay
+  synchronize { @delay }
+end
+
+
+ +
+

+ + #processing?Boolean + + + + + +

+
+

In the task execution in progress?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the task is in the given state else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+227
+228
+229
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 227
+
+def processing?
+  synchronize { ns_check_state?(:processing) }
+end
+
+
+ +
+

+ + #reschedule(delay) ⇒ Boolean + + + + + +

+
+

Reschedule the task using the given delay and the current time. +A task can only be reset while it is :pending.

+ + +
+
+
+

Parameters:

+
    + +
  • + + delay + + + (Float) + + + + — +

    the number of seconds to wait for before executing the task

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if successfully rescheduled else false

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    When given a time that is in the past

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+262
+263
+264
+265
+266
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 262
+
+def reschedule(delay)
+  delay = delay.to_f
+  raise ArgumentError.new('seconds must be greater than zero') if delay < 0.0
+  synchronize{ ns_reschedule(delay) }
+end
+
+
+ +
+

+ + #resetBoolean + + + + + +

+
+

Reschedule the task using the original delay and the current time. +A task can only be reset while it is :pending.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if successfully rescheduled else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+250
+251
+252
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 250
+
+def reset
+  synchronize{ ns_reschedule(@delay) }
+end
+
+
+ +
+

+ + #schedule_timeFloat + + + + + +

+
+

The monotonic time at which the the task is scheduled to be executed.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Float) + + + + — +

    the schedule time or nil if unscheduled

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+206
+207
+208
+
+
# File 'lib/concurrent-ruby/concurrent/scheduled_task.rb', line 206
+
+def schedule_time
+  synchronize { @time }
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Semaphore.html b/docs/1.1.10/Concurrent/Semaphore.html new file mode 100644 index 000000000..9460f4683 --- /dev/null +++ b/docs/1.1.10/Concurrent/Semaphore.html @@ -0,0 +1,841 @@ + + + + + + + Class: Concurrent::Semaphore + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Semaphore + + + +

+
+ +
+
Inherits:
+
+ SemaphoreImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/semaphore.rb
+
+ +
+ +

Overview

+
+

A counting semaphore. Conceptually, a semaphore maintains a set of +permits. Each #acquire blocks if necessary until a permit is +available, and then takes it. Each #release adds a permit, potentially +releasing a blocking acquirer. +However, no actual permit objects are used; the Semaphore just keeps a +count of the number available and acts accordingly. +Alternatively, permits may be acquired within a block, and automatically +released after the block finishes executing.

+ + +
+
+
+ +
+

Examples:

+ + +
semaphore = Concurrent::Semaphore.new(2)
+
+t1 = Thread.new do
+  semaphore.acquire
+  puts "Thread 1 acquired semaphore"
+end
+
+t2 = Thread.new do
+  semaphore.acquire
+  puts "Thread 2 acquired semaphore"
+end
+
+t3 = Thread.new do
+  semaphore.acquire
+  puts "Thread 3 acquired semaphore"
+end
+
+t4 = Thread.new do
+  sleep(2)
+  puts "Thread 4 releasing semaphore"
+  semaphore.release
+end
+
+[t1, t2, t3, t4].each(&:join)
+
+# prints:
+# Thread 3 acquired semaphore
+# Thread 2 acquired semaphore
+# Thread 4 releasing semaphore
+# Thread 1 acquired semaphore
+ + +
semaphore = Concurrent::Semaphore.new(1)
+
+puts semaphore.available_permits
+semaphore.acquire do
+  puts semaphore.available_permits
+end
+puts semaphore.available_permits
+
+# prints:
+# 1
+# 0
+# 1
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(count) ⇒ undocumented + + + + + +

+
+

Create a new Semaphore with the initial count.

+ + +
+
+
+

Parameters:

+
    + +
  • + + count + + + (Fixnum) + + + + — +

    the initial count

    +
    + +
  • + +
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if count is not an integer or is less than zero

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+164
+165
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/semaphore.rb', line 164
+
+class Semaphore < SemaphoreImplementation
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #acquire(permits = 1) ⇒ nil, BasicObject + + + + + +

+
+

Acquires the given number of permits from this semaphore, + blocking until all are available. If a block is given, + yields to it and releases the permits afterwards.

+ +

is given, its return value is returned.

+ + +
+
+
+

Parameters:

+
    + +
  • + + permits + + + (Fixnum) + + + (defaults to: 1) + + + — +

    Number of permits to acquire

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (nil, BasicObject) + + + + — +

    Without a block, nil is returned. If a block

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if permits is not an integer or is less than +one

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+164
+165
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/semaphore.rb', line 164
+
+class Semaphore < SemaphoreImplementation
+end
+
+
+ +
+

+ + #available_permitsInteger + + + + + +

+
+

Returns the current number of permits available in this semaphore.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + +
  • + +
+ +
+ + + + +
+
+
+
+164
+165
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/semaphore.rb', line 164
+
+class Semaphore < SemaphoreImplementation
+end
+
+
+ +
+

+ + #drain_permitsInteger + + + + + +

+
+

Acquires and returns all permits that are immediately available.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + +
  • + +
+ +
+ + + + +
+
+
+
+164
+165
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/semaphore.rb', line 164
+
+class Semaphore < SemaphoreImplementation
+end
+
+
+ +
+

+ + #release(permits = 1) ⇒ nil + + + + + +

+
+

Releases the given number of permits, returning them to the semaphore.

+ + +
+
+
+

Parameters:

+
    + +
  • + + permits + + + (Fixnum) + + + (defaults to: 1) + + + — +

    Number of permits to return to the semaphore.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (nil) + + + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if permits is not a number or is less than one

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+164
+165
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/semaphore.rb', line 164
+
+class Semaphore < SemaphoreImplementation
+end
+
+
+ +
+

+ + #try_acquire(permits = 1, timeout = nil) ⇒ true, false, nil, BasicObject + + + + + +

+
+

Acquires the given number of permits from this semaphore, + only if all are available at the time of invocation or within + timeout interval. If a block is given, yields to it if the permits + were successfully acquired, and releases them afterward, returning the + block's return value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + permits + + + (Fixnum) + + + (defaults to: 1) + + + — +

    the number of permits to acquire

    +
    + +
  • + +
  • + + timeout + + + (Fixnum) + + + (defaults to: nil) + + + — +

    the number of seconds to wait for the counter +or nil to return immediately

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false, nil, BasicObject) + + + + — +

    false if no permits are +available, true when acquired a permit. If a block is given, the +block's return value is returned if the permits were acquired; if not, +nil is returned.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if permits is not an integer or is less than +one

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+164
+165
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/semaphore.rb', line 164
+
+class Semaphore < SemaphoreImplementation
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/SerializedExecution.html b/docs/1.1.10/Concurrent/SerializedExecution.html new file mode 100644 index 000000000..4b1d5f72f --- /dev/null +++ b/docs/1.1.10/Concurrent/SerializedExecution.html @@ -0,0 +1,520 @@ + + + + + + + Class: Concurrent::SerializedExecution + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::SerializedExecution + + + +

+
+ +
+
Inherits:
+
+ Concurrent::Synchronization::LockableObject + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/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 +

+ + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initializeSerializedExecution + + + + + +

+
+

Returns a new instance of SerializedExecution.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+11
+12
+13
+14
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution.rb', line 11
+
+def initialize()
+  super()
+  synchronize { ns_initialize }
+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

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+34
+35
+36
+37
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution.rb', line 34
+
+def post(executor, *args, &task)
+  posts [[executor, args, task]]
+  true
+end
+
+
+ +
+

+ + #posts(posts) ⇒ undocumented + + + + + +

+
+

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(ExecutorService, Array<Object>, Proc)>) + + + + — +

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

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution.rb', line 44
+
+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
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/SerializedExecution/Job.html b/docs/1.1.10/Concurrent/SerializedExecution/Job.html new file mode 100644 index 000000000..70006459b --- /dev/null +++ b/docs/1.1.10/Concurrent/SerializedExecution/Job.html @@ -0,0 +1,467 @@ + + + + + + + Class: Concurrent::SerializedExecution::Job + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::SerializedExecution::Job + + + +

+
+ +
+
Inherits:
+
+ Struct + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/serialized_execution.rb
+
+ +
+ + + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Attribute Details

+ + + +
+

+ + #argsObject + + + + + +

+
+

Returns the value of attribute args

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of args

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution.rb', line 16
+
+def args
+  @args
+end
+
+
+ + + +
+

+ + #blockObject + + + + + +

+
+

Returns the value of attribute block

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of block

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution.rb', line 16
+
+def block
+  @block
+end
+
+
+ + + +
+

+ + #executorObject + + + + + +

+
+

Returns the value of attribute executor

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of executor

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution.rb', line 16
+
+def executor
+  @executor
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #callundocumented + + + + + +

+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution.rb', line 17
+
+def call
+  block.call(*args)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/SerializedExecutionDelegator.html b/docs/1.1.10/Concurrent/SerializedExecutionDelegator.html new file mode 100644 index 000000000..1d2f0ab5f --- /dev/null +++ b/docs/1.1.10/Concurrent/SerializedExecutionDelegator.html @@ -0,0 +1,388 @@ + + + + + + + Class: Concurrent::SerializedExecutionDelegator + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::SerializedExecutionDelegator + + + +

+
+ +
+
Inherits:
+
+ SimpleDelegator + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb
+
+ +
+ +

Overview

+
+

A wrapper/delegator for any ExecutorService that +guarantees serialized execution of tasks.

+ + +
+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(executor) ⇒ SerializedExecutionDelegator + + + + + +

+
+

Returns a new instance of SerializedExecutionDelegator.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb', line 15
+
+def initialize(executor)
+  @executor   = executor
+  @serializer = SerializedExecution.new
+  super(executor)
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #post(*args) { ... } ⇒ Boolean + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + 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

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+22
+23
+24
+25
+26
+
+
# File 'lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb', line 22
+
+def post(*args, &task)
+  raise ArgumentError.new('no block given') unless block_given?
+  return false unless running?
+  @serializer.post(@executor, *args, &task)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Set.html b/docs/1.1.10/Concurrent/Set.html new file mode 100644 index 000000000..309cb3f2e --- /dev/null +++ b/docs/1.1.10/Concurrent/Set.html @@ -0,0 +1,161 @@ + + + + + + + Class: Concurrent::Set + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Set + + + +

+
+ +
+
Inherits:
+
+ SetImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/set.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

a += b is not a thread-safe operation on +Concurrent::Set. It reads Set a, then it creates new Concurrent::Set +which is union of a and b, then it writes the union to a. +The read and write are independent operations they do not form a single atomic +operation therefore when two += operations are executed concurrently updates +may be lost. Use #merge instead.

+
+
+ +

A thread-safe subclass of Set. This version locks against the object +itself for every method call, ensuring only one thread can be reading +or writing at a time. This includes iteration methods like #each.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/SettableStruct.html b/docs/1.1.10/Concurrent/SettableStruct.html new file mode 100644 index 000000000..81436bde3 --- /dev/null +++ b/docs/1.1.10/Concurrent/SettableStruct.html @@ -0,0 +1,1402 @@ + + + + + + + Module: Concurrent::SettableStruct + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::SettableStruct + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/settable_struct.rb
+
+ +
+ +

Overview

+
+

An thread-safe, write-once variation of Ruby's standard Struct. +Each member can have its value set at most once, either at construction +or any time thereafter. Attempting to assign a value to a member +that has already been set will result in a Concurrent::ImmutabilityError.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #==(other) ⇒ Boolean + + + + + +

+
+

Equality

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if other has the same struct subclass and has +equal member values (according to Object#==)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+50
+51
+52
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 50
+
+def ==(other)
+  synchronize { ns_equality(other) }
+end
+
+
+ +
+

+ + #[](member) ⇒ Object + + + + + +

+
+

Attribute Reference

+ + +
+
+
+

Parameters:

+
    + +
  • + + member + + + (Symbol, String, Integer) + + + + — +

    the string or symbol name of the member +for which to obtain the value or the member's index

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value of the given struct member or the member at the given index.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NameError) + + + + — +

    if the member does not exist

    +
    + +
  • + +
  • + + + (IndexError) + + + + — +

    if the index is out of range.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+45
+46
+47
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 45
+
+def [](member)
+  synchronize { ns_get(member) }
+end
+
+
+ +
+

+ + #[]=(member, value) ⇒ Object + + + + + +

+
+

Attribute Assignment

+ +

Sets the value of the given struct member or the member at the given index.

+ + +
+
+
+

Parameters:

+
    + +
  • + + member + + + (Symbol, String, Integer) + + + + — +

    the string or symbol name of the member +for which to obtain the value or the member's index

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value of the given struct member or the member at the given index.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (NameError) + + + + — +

    if the name does not exist

    +
    + +
  • + +
  • + + + (IndexError) + + + + — +

    if the index is out of range.

    +
    + +
  • + +
  • + + + (Concurrent::ImmutabilityError) + + + + — +

    if the given member has already been set

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 75
+
+def []=(member, value)
+  if member.is_a? Integer
+    length = synchronize { @values.length }
+    if member >= length
+      raise IndexError.new("offset #{member} too large for struct(size:#{length})")
+    end
+    synchronize do
+      unless @values[member].nil?
+        raise Concurrent::ImmutabilityError.new('struct member has already been set')
+      end
+      @values[member] = value
+    end
+  else
+    send("#{member}=", value)
+  end
+rescue NoMethodError
+  raise NameError.new("no member '#{member}' in struct")
+end
+
+
+ +
+

+ + #each {|value| ... } ⇒ undocumented + + + + + +

+
+

Yields the value of each struct member in order. If no block is given +an enumerator is returned.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+55
+56
+57
+58
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 55
+
+def each(&block)
+  return enum_for(:each) unless block_given?
+  synchronize { ns_each(&block) }
+end
+
+
+ +
+

+ + #each_pair {|member, value| ... } ⇒ undocumented + + + + + +

+
+

Yields the name and value of each struct member in order. If no block is +given an enumerator is returned.

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member/value pair

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + member + + + (Object) + + + + — +

    each struct member (in order)

    +
    + +
  • + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+61
+62
+63
+64
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 61
+
+def each_pair(&block)
+  return enum_for(:each_pair) unless block_given?
+  synchronize { ns_each_pair(&block) }
+end
+
+
+ +
+

+ + #inspectString + + + + Also known as: + to_s + + + + +

+
+

Describe the contents of this struct in a string.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    the contents of this struct in a string

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+29
+30
+31
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 29
+
+def inspect
+  synchronize { ns_inspect }
+end
+
+
+ +
+

+ + #merge(other) {|member, selfvalue, othervalue| ... } ⇒ Synchronization::AbstractStruct + + + + + +

+
+

Returns a new struct containing the contents of other and the contents +of self. If no block is specified, the value for entries with duplicate +keys will be that of other. Otherwise the value for each duplicate key +is determined by calling the block with the key, its value in self and +its value in other.

+ + +
+
+
+

Parameters:

+
    + +
  • + + other + + + (Hash) + + + + — +

    the hash from which to set the new values

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    an options block for resolving duplicate keys

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + member + + + (String, Symbol) + + + + — +

    the name of the member which is duplicated

    +
    + +
  • + +
  • + + selfvalue + + + (Object) + + + + — +

    the value of the member in self

    +
    + +
  • + +
  • + + othervalue + + + (Object) + + + + — +

    the value of the member in other

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Synchronization::AbstractStruct) + + + + — +

    a new struct with the new values

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    of given a member that is not defined in the struct

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+35
+36
+37
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 35
+
+def merge(other, &block)
+  synchronize { ns_merge(other, &block) }
+end
+
+
+ +
+

+ + #select {|value| ... } ⇒ Array + + + + + +

+
+

Yields each member value from the struct to the block and returns an Array +containing the member values from the struct for which the given block +returns a true value (equivalent to Enumerable#select).

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed on each struct member

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    each struct value (in order)

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Array) + + + + — +

    an array containing each value for which the block returns true

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+67
+68
+69
+70
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 67
+
+def select(&block)
+  return enum_for(:select) unless block_given?
+  synchronize { ns_select(&block) }
+end
+
+
+ +
+

+ + #to_hHash + + + + + +

+
+

Returns a hash containing the names and values for the struct’s members.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +

    the names and values for the struct’s members

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+40
+41
+42
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 40
+
+def to_h
+  synchronize { ns_to_h }
+end
+
+
+ +
+

+ + #valuesArray + + + + Also known as: + to_a + + + + +

+
+

Returns the values for this struct as an Array.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Array) + + + + — +

    the values for this struct

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+18
+19
+20
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 18
+
+def values
+  synchronize { ns_values }
+end
+
+
+ +
+

+ + #values_at(*indexes) ⇒ undocumented + + + + + +

+
+

Returns the struct member values for each selector as an Array.

+ +

A selector may be either an Integer offset or a Range of offsets (as in Array#values_at).

+ + +
+
+
+

Parameters:

+
    + +
  • + + indexes + + + (Fixnum, Range) + + + + — +

    the index(es) from which to obatin the values (in order)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+24
+25
+26
+
+
# File 'lib/concurrent-ruby/concurrent/settable_struct.rb', line 24
+
+def values_at(*indexes)
+  synchronize { ns_values_at(indexes) }
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/SimpleExecutorService.html b/docs/1.1.10/Concurrent/SimpleExecutorService.html new file mode 100644 index 000000000..aaf7deb6a --- /dev/null +++ b/docs/1.1.10/Concurrent/SimpleExecutorService.html @@ -0,0 +1,1198 @@ + + + + + + + Class: Concurrent::SimpleExecutorService + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::SimpleExecutorService + + + +

+
+ +
+
Inherits:
+
+ RubyExecutorService + +
    +
  • Object
  • + + + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Intended for use primarily in testing and debugging.

+
+
+ +

An executor service in which every operation spawns a new, +independently operating thread.

+ +

This is perhaps the most inefficient executor service in this +library. It exists mainly for testing an debugging. Thread creation +and management is expensive in Ruby and this executor performs no +resource pooling. This can be very beneficial during testing and +debugging because it decouples the using code from the underlying +executor implementation. In production this executor will likely +lead to suboptimal performance.

+ + +
+
+
+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + + + +
+

Class Method Details

+ + +
+

+ + .<<(task) ⇒ self + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + task + + + (Proc) + + + + — +

    the asynchronous task to perform

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + + — +

    returns itself

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+31
+32
+33
+34
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 31
+
+def self.<<(task)
+  post(&task)
+  self
+end
+
+
+ +
+

+ + .post(*args) { ... } ⇒ Boolean + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + 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

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+21
+22
+23
+24
+25
+26
+27
+28
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 21
+
+def self.post(*args)
+  raise ArgumentError.new('no block given') unless block_given?
+  Thread.new(*args) do
+    Thread.current.abort_on_exception = false
+    yield(*args)
+  end
+  true
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #<<(task) ⇒ self + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + task + + + (Proc) + + + + — +

    the asynchronous task to perform

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + + — +

    returns itself

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 53
+
+def <<(task)
+  post(&task)
+  self
+end
+
+
+ +
+

+ + #killundocumented + + + + + +

+
+

Begin an immediate shutdown. In-progress tasks will be allowed to +complete but enqueued tasks will be dismissed and no new tasks +will be accepted. Has no additional effect if the thread pool is +not running.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+81
+82
+83
+84
+85
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 81
+
+def kill
+  @running.make_false
+  @stopped.set
+  true
+end
+
+
+ +
+

+ + #post(*args) { ... } ⇒ Boolean + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + 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

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 37
+
+def post(*args, &task)
+  raise ArgumentError.new('no block given') unless block_given?
+  return false unless running?
+  @count.increment
+  Thread.new(*args) do
+    Thread.current.abort_on_exception = false
+    begin
+      yield(*args)
+    ensure
+      @count.decrement
+      @stopped.set if @running.false? && @count.value == 0
+    end
+  end
+end
+
+
+ +
+

+ + #running?Boolean + + + + + +

+
+

Is the executor running?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when running, false when shutting down or shutdown

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+59
+60
+61
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 59
+
+def running?
+  @running.true?
+end
+
+
+ +
+

+ + #shutdownundocumented + + + + + +

+
+

Begin an orderly shutdown. Tasks already in the queue will be executed, +but no new tasks will be accepted. Has no additional effect if the +thread pool is not running.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+74
+75
+76
+77
+78
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 74
+
+def shutdown
+  @running.make_false
+  @stopped.set if @count.value == 0
+  true
+end
+
+
+ +
+

+ + #shutdown?Boolean + + + + + +

+
+

Is the executor shutdown?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when shutdown, false when shutting down or running

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+69
+70
+71
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 69
+
+def shutdown?
+  @stopped.set?
+end
+
+
+ +
+

+ + #shuttingdown?Boolean + + + + + +

+
+

Is the executor shuttingdown?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when not running and not shutdown, else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+64
+65
+66
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 64
+
+def shuttingdown?
+  @running.false? && ! @stopped.set?
+end
+
+
+ +
+

+ + #wait_for_termination(timeout = nil) ⇒ Boolean + + + + + +

+
+ +
+ Note: +

Does not initiate shutdown or termination. Either shutdown or kill +must be called before this method (or on another thread).

+
+
+ +

Block until executor shutdown is complete or until timeout seconds have +passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Integer) + + + (defaults to: nil) + + + — +

    the maximum number of seconds to wait for shutdown to complete

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if shutdown complete or false on timeout

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+88
+89
+90
+
+
# File 'lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb', line 88
+
+def wait_for_termination(timeout = nil)
+  @stopped.wait(timeout)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/SingleThreadExecutor.html b/docs/1.1.10/Concurrent/SingleThreadExecutor.html new file mode 100644 index 000000000..ec7930f15 --- /dev/null +++ b/docs/1.1.10/Concurrent/SingleThreadExecutor.html @@ -0,0 +1,1767 @@ + + + + + + + Class: Concurrent::SingleThreadExecutor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::SingleThreadExecutor + + + +

+
+ +
+
Inherits:
+
+ SingleThreadExecutorImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb
+
+ +
+ +

Overview

+
+

A thread pool with a single thread an unlimited queue. Should the thread +die for any reason it will be removed and replaced, thus ensuring that +the executor will always remain viable and available to process jobs.

+ +

A common pattern for background processing is to create a single thread +on which an infinite loop is run. The thread's loop blocks on an input +source (perhaps blocking I/O or a queue) and processes each input as it +is received. This pattern has several issues. The thread itself is highly +susceptible to errors during processing. Also, the thread itself must be +constantly monitored and restarted should it die. SingleThreadExecutor +encapsulates all these bahaviors. The task processor is highly resilient +to errors from within tasks. Also, should the thread die it will +automatically be restarted.

+ +

The API and behavior of this class are based on Java's SingleThreadExecutor.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Instance Attribute Details

+ + + +
+

+ + #fallback_policySymbol (readonly) + + + + + +

+
+

Returns The fallback policy in effect. Either :abort, :discard, or :caller_runs.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Symbol) + + + + — +

    The fallback policy in effect. Either :abort, :discard, or :caller_runs.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #<<(task) ⇒ self + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + task + + + (Proc) + + + + — +

    the asynchronous task to perform

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + + — +

    returns itself

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #auto_terminate=(value) ⇒ Boolean + + + + + +

+
+
Deprecated.

Has no effect

+
+

Set the auto-terminate behavior for this executor.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Boolean) + + + + — +

    The new auto-terminate value to set for this executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when auto-termination is enabled else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #auto_terminate?Boolean + + + + + +

+
+

Is the executor auto-terminate when the application exits?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when auto-termination is enabled else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #can_overflow?Boolean + + + + + +

+
+

Does the task queue have a maximum size?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if the task queue has a maximum size else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #killundocumented + + + + + +

+
+

Begin an immediate shutdown. In-progress tasks will be allowed to +complete but enqueued tasks will be dismissed and no new tasks +will be accepted. Has no additional effect if the thread pool is +not running.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #post(*args) { ... } ⇒ Boolean + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + 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

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #running?Boolean + + + + + +

+
+

Is the executor running?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when running, false when shutting down or shutdown

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #serialized?Boolean + + + + + +

+
+

Does this executor guarantee serialization of its operations?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if the executor guarantees that all operations +will be post in the order they are received and no two operations may +occur simultaneously. Else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #shutdownundocumented + + + + + +

+
+

Begin an orderly shutdown. Tasks already in the queue will be executed, +but no new tasks will be accepted. Has no additional effect if the +thread pool is not running.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #shutdown?Boolean + + + + + +

+
+

Is the executor shutdown?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when shutdown, false when shutting down or running

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #shuttingdown?Boolean + + + + + +

+
+

Is the executor shuttingdown?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when not running and not shutdown, else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+

+ + #wait_for_termination(timeout = nil) ⇒ Boolean + + + + + +

+
+ +
+ Note: +

Does not initiate shutdown or termination. Either shutdown or kill +must be called before this method (or on another thread).

+
+
+ +

Block until executor shutdown is complete or until timeout seconds have +passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Integer) + + + (defaults to: nil) + + + — +

    the maximum number of seconds to wait for shutdown to complete

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if shutdown complete or false on timeout

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb', line 37
+
+class SingleThreadExecutor < SingleThreadExecutorImplementation
+
+  # @!macro single_thread_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @option opts [Symbol] :fallback_policy (:discard) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
+  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
+
+  # @!method initialize(opts = {})
+  #   @!macro single_thread_executor_method_initialize
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Synchronization.html b/docs/1.1.10/Concurrent/Synchronization.html new file mode 100644 index 000000000..fa2e0e01a --- /dev/null +++ b/docs/1.1.10/Concurrent/Synchronization.html @@ -0,0 +1,500 @@ + + + + + + + Module: Concurrent::Synchronization + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Synchronization + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/synchronization.rb,
+ lib/concurrent-ruby/concurrent/synchronization/lock.rb,
lib/concurrent-ruby/concurrent/synchronization/object.rb,
lib/concurrent-ruby/concurrent/synchronization/volatile.rb,
lib/concurrent-ruby/concurrent/synchronization/condition.rb,
lib/concurrent-ruby/concurrent/synchronization/mri_object.rb,
lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb,
lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb,
lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb,
lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb,
lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb,
lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb,
lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb,
lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb,
lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb,
lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb
+
+
+ +
+ +

Overview

+
+

noinspection RubyInstanceVariableNamingConvention

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: Object + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
Volatile = +
+
+

Volatile adds the attr_volatile class method when included.

+ +

foo = Foo.new + foo.bar + => 1 + foo.bar = 2 + => 2

+ + +
+
+
+ +
+

Examples:

+ + +
class Foo
+  include Concurrent::Synchronization::Volatile
+
+  attr_volatile :bar
+
+  def initialize
+    self.bar = 1
+  end
+end
+ +
+ + +
+
+
case
+when Concurrent.on_cruby?
+  MriAttrVolatile
+when Concurrent.on_jruby?
+  JRubyAttrVolatile
+when Concurrent.on_rbx?
+  RbxAttrVolatile
+when Concurrent.on_truffleruby?
+  TruffleRubyAttrVolatile
+else
+  MriAttrVolatile
+end
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #broadcastundocumented + + + + + +

+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 67
+
+
+
+
+ +
+

+ + #initialize(*args, &block) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 52
+
+
+
+
+ +
+

+ + #signalundocumented + + + + + +

+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 64
+
+
+
+
+ +
+

+ + #synchronizeundocumented + + + + + +

+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 55
+
+
+
+
+ +
+

+ + #wait(timeout = nil) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 61
+
+
+
+
+ +
+

+ + #wait_until(timeout = nil, &condition) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 58
+
+
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Synchronization/JRubyAttrVolatile/ClassMethods.html b/docs/1.1.10/Concurrent/Synchronization/JRubyAttrVolatile/ClassMethods.html new file mode 100644 index 000000000..1b5896c9a --- /dev/null +++ b/docs/1.1.10/Concurrent/Synchronization/JRubyAttrVolatile/ClassMethods.html @@ -0,0 +1,213 @@ + + + + + + + Module: Concurrent::Synchronization::JRubyAttrVolatile::ClassMethods + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Synchronization::JRubyAttrVolatile::ClassMethods + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #attr_volatile(*names) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb', line 13
+
+def attr_volatile(*names)
+  names.each do |name|
+
+    ivar = :"@volatile_#{name}"
+
+    class_eval <<-RUBY, __FILE__, __LINE__ + 1
+      def #{name}
+        instance_variable_get_volatile(:#{ivar})
+      end
+
+      def #{name}=(value)
+        instance_variable_set_volatile(:#{ivar}, value)
+      end
+    RUBY
+
+  end
+  names.map { |n| [n, :"#{n}="] }.flatten
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Synchronization/MriAttrVolatile/ClassMethods.html b/docs/1.1.10/Concurrent/Synchronization/MriAttrVolatile/ClassMethods.html new file mode 100644 index 000000000..8832e6b3b --- /dev/null +++ b/docs/1.1.10/Concurrent/Synchronization/MriAttrVolatile/ClassMethods.html @@ -0,0 +1,207 @@ + + + + + + + Module: Concurrent::Synchronization::MriAttrVolatile::ClassMethods + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Synchronization::MriAttrVolatile::ClassMethods + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/synchronization/mri_object.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #attr_volatile(*names) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/mri_object.rb', line 11
+
+def attr_volatile(*names)
+  names.each do |name|
+    ivar = :"@volatile_#{name}"
+    class_eval <<-RUBY, __FILE__, __LINE__ + 1
+      def #{name}
+        #{ivar}
+      end
+
+      def #{name}=(value)
+        #{ivar} = value
+      end
+    RUBY
+  end
+  names.map { |n| [n, :"#{n}="] }.flatten
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Synchronization/Object.html b/docs/1.1.10/Concurrent/Synchronization/Object.html new file mode 100644 index 000000000..eb5eb36ff --- /dev/null +++ b/docs/1.1.10/Concurrent/Synchronization/Object.html @@ -0,0 +1,996 @@ + + + + + + + Class: Concurrent::Synchronization::Object + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Synchronization::Object + + + +

+
+ +
+
Inherits:
+
+ ObjectImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/synchronization/object.rb
+
+ +
+ +

Overview

+
+

Abstract object providing final, volatile, ans CAS extensions to build other concurrent abstractions.

+ + + + +
+
+
+ + +
+ + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeObject + + + + + +

+
+

Has to be called by children.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+36
+37
+38
+39
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 36
+
+def initialize
+  super
+  __initialize_atomic_fields__
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .atomic_attribute?(name) ⇒ true, false + + + + + +

+
+

Returns is the attribute with name atomic?.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    is the attribute with name atomic?

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+157
+158
+159
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 157
+
+def self.atomic_attribute?(name)
+  atomic_attributes.include? name
+end
+
+
+ +
+

+ + .atomic_attributes(inherited = true) ⇒ ::Array<Symbol> + + + + + +

+
+

Returns defined volatile with CAS fields on this class.

+ + +
+
+
+

Parameters:

+
    + +
  • + + inherited + + + (true, false) + + + (defaults to: true) + + + — +

    should inherited volatile with CAS fields be returned?

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (::Array<Symbol>) + + + + — +

    Returns defined volatile with CAS fields on this class.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+151
+152
+153
+154
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 151
+
+def self.atomic_attributes(inherited = true)
+  @__atomic_fields__ ||= []
+  ((superclass.atomic_attributes if superclass.respond_to?(:atomic_attributes) && inherited) || []) + @__atomic_fields__
+end
+
+
+ +
+

+ + .attr_atomic(*names) ⇒ ::Array<Symbol> + + + + + +

+
+

Creates methods for reading and writing to a instance variable with +volatile (Java) semantic as attr_volatile does. +The instance variable should be accessed oly through generated methods. +This method generates following methods: value, value=(new_value) #=> new_value, +swap_value(new_value) #=> old_value, +compare_and_set_value(expected, value) #=> true || false, update_value(&block).

+ + +
+
+
+

Parameters:

+
    + +
  • + + names + + + (::Array<Symbol>) + + + + — +

    of the instance variables to be volatile with CAS.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (::Array<Symbol>) + + + + — +

    names of defined method names.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 116
+
+def self.attr_atomic(*names)
+  @__atomic_fields__ ||= []
+  @__atomic_fields__ += names
+  safe_initialization!
+  define_initialize_atomic_fields
+
+  names.each do |name|
+    ivar = :"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }}"
+    class_eval <<-RUBY, __FILE__, __LINE__ + 1
+      def #{name}
+        #{ivar}.get
+      end
+
+      def #{name}=(value)
+        #{ivar}.set value
+      end
+
+      def swap_#{name}(value)
+        #{ivar}.swap value
+      end
+
+      def compare_and_set_#{name}(expected, value)
+        #{ivar}.compare_and_set expected, value
+      end
+
+      def update_#{name}(&block)
+        #{ivar}.update(&block)
+      end
+    RUBY
+  end
+  names.flat_map { |n| [n, :"#{n}=", :"swap_#{n}", :"compare_and_set_#{n}", :"update_#{n}"] }
+end
+
+
+ +
+

+ + .attr_volatile(*names) ⇒ ::Array<Symbol> + + + + + +

+
+

Creates methods for reading and writing (as attr_accessor does) to a instance variable with +volatile (Java) semantic. The instance variable should be accessed only through generated methods.

+ + +
+
+
+

Parameters:

+
    + +
  • + + names + + + (::Array<Symbol>) + + + + — +

    of the instance variables to be volatile

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (::Array<Symbol>) + + + + — +

    names of defined method names

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 28
+
+
+
+
+ +
+

+ + .ensure_safe_initialization_when_final_fields_are_presenttrue + + + + + +

+
+

For testing purposes, quite slow. Injects assert code to new method which will raise if class instance contains +any instance variables with CamelCase names and isn't safe_initialization?.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + +
  • + +
+

Raises:

+
    + +
  • + + + + + + + +

    when offend found

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 77
+
+def self.ensure_safe_initialization_when_final_fields_are_present
+  Object.class_eval do
+    def self.new(*args, &block)
+      object = super(*args, &block)
+    ensure
+      has_final_field = object.instance_variables.any? { |v| v.to_s =~ /^@[A-Z]/ }
+      if has_final_field && !safe_initialization?
+        raise "there was an instance of #{object.class} with final field but not marked with safe_initialization!"
+      end
+    end
+  end
+  true
+end
+
+
+ +
+

+ + .safe_initialization!true + + + + + +

+
+

By calling this method on a class, it and all its children are marked to be constructed safely. Meaning that +all writes (ivar initializations) are made visible to all readers of newly constructed object. It ensures +same behaviour as Java's final fields.

+ + +
+
+
+ +
+

Examples:

+ + +
class AClass < Concurrent::Synchronization::Object
+  safe_initialization!
+
+  def initialize
+    @AFinalValue = 'value' # published safely, does not have to be synchronized
+  end
+end
+ +
+ +

Returns:

+
    + +
  • + + + (true) + + + +
  • + +
+ +
+ + + + +
+
+
+
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 53
+
+def self.safe_initialization!
+  # define only once, and not again in children
+  return if safe_initialization?
+
+  # @!visibility private
+  def self.new(*args, &block)
+    object = super(*args, &block)
+  ensure
+    object.full_memory_barrier if object
+  end
+
+  @safe_initialization = true
+end
+
+
+ +
+

+ + .safe_initialization?true, false + + + + + +

+
+

Returns if this class is safely initialized.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    if this class is safely initialized.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+68
+69
+70
+71
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/object.rb', line 68
+
+def self.safe_initialization?
+  @safe_initialization = false unless defined? @safe_initialization
+  @safe_initialization || (superclass.respond_to?(:safe_initialization?) && superclass.safe_initialization?)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Synchronization/RbxAttrVolatile/ClassMethods.html b/docs/1.1.10/Concurrent/Synchronization/RbxAttrVolatile/ClassMethods.html new file mode 100644 index 000000000..951da34c6 --- /dev/null +++ b/docs/1.1.10/Concurrent/Synchronization/RbxAttrVolatile/ClassMethods.html @@ -0,0 +1,211 @@ + + + + + + + Module: Concurrent::Synchronization::RbxAttrVolatile::ClassMethods + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Synchronization::RbxAttrVolatile::ClassMethods + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #attr_volatile(*names) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb', line 12
+
+def attr_volatile(*names)
+  names.each do |name|
+    ivar = :"@volatile_#{name}"
+    class_eval <<-RUBY, __FILE__, __LINE__ + 1
+      def #{name}
+        Rubinius.memory_barrier
+        #{ivar}
+      end
+
+      def #{name}=(value)
+        #{ivar} = value
+        Rubinius.memory_barrier
+      end
+    RUBY
+  end
+  names.map { |n| [n, :"#{n}="] }.flatten
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Synchronization/TruffleRubyAttrVolatile/ClassMethods.html b/docs/1.1.10/Concurrent/Synchronization/TruffleRubyAttrVolatile/ClassMethods.html new file mode 100644 index 000000000..fbfe01ac1 --- /dev/null +++ b/docs/1.1.10/Concurrent/Synchronization/TruffleRubyAttrVolatile/ClassMethods.html @@ -0,0 +1,215 @@ + + + + + + + Module: Concurrent::Synchronization::TruffleRubyAttrVolatile::ClassMethods + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Synchronization::TruffleRubyAttrVolatile::ClassMethods + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #attr_volatile(*names) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+
+
# File 'lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb', line 11
+
+def attr_volatile(*names)
+  names.each do |name|
+    ivar = :"@volatile_#{name}"
+
+    class_eval <<-RUBY, __FILE__, __LINE__ + 1
+      def #{name}
+        full_memory_barrier
+        #{ivar}                  
+      end
+
+      def #{name}=(value)
+        #{ivar} = value
+        full_memory_barrier
+      end
+    RUBY
+  end
+
+  names.map { |n| [n, :"#{n}="] }.flatten
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/TVar.html b/docs/1.1.10/Concurrent/TVar.html new file mode 100644 index 000000000..ad8d2ca3a --- /dev/null +++ b/docs/1.1.10/Concurrent/TVar.html @@ -0,0 +1,603 @@ + + + + + + + Class: Concurrent::TVar + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::TVar + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/tvar.rb
+
+ +
+ +

Overview

+
+

A TVar is a transactional variable - a single-element container that +is used as part of a transaction - see Concurrent::atomically.

+ +

Thread-safe Variable Classes

+ +

Each of the thread-safe variable classes is designed to solve a different +problem. In general:

+ +
    +
  • Agent: Shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately.
  • +
  • Atom: Shared, mutable variable providing independent, +uncoordinated, synchronous change of individual values. Best used when +the value will undergo frequent reads but only occasional, though complex, +updates. Suitable when the result of an update must be known immediately.
  • +
  • AtomicReference: A simple object reference that can be updated +atomically. Updates are synchronous but fast. Best used when updates a +simple set operations. Not suitable when updates are complex. +AtomicBoolean and AtomicFixnum are similar +but optimized for the given data type.
  • +
  • Exchanger: Shared, stateless synchronization point. Used +when two or more threads need to exchange data. The threads will pair then +block on each other until the exchange is complete.
  • +
  • MVar: Shared synchronization point. Used when one thread +must give a value to another, which must take the value. The threads will +block on each other until the exchange is complete.
  • +
  • ThreadLocalVar: Shared, mutable, isolated variable which +holds a different value for each thread which has access. Often used as +an instance variable in objects which must maintain different state +for different threads.
  • +
  • TVar: Shared, mutable variables which provide +coordinated, synchronous, change of many stated. Used when multiple +value must change together, in an all-or-nothing transaction. +TVar and atomically implement a software transactional memory. A TVar is a +single item container that always contains exactly one value. The atomically +method allows you to modify a set of TVar objects with the guarantee that all +of the updates are collectively atomic - they either all happen or none of them +do - consistent - a TVar will never enter an illegal state - and isolated - +atomic blocks never interfere with each other when they are running. You may +recognise these properties from database transactions.

    + +

    There are some very important and unusual semantics that you must be aware of:

    + +
      +
    • Most importantly, the block that you pass to atomically may be executed more +than once. In most cases your code should be free of side-effects, except for +via TVar.

    • +
    • If an exception escapes an atomically block it will abort the transaction.

    • +
    • It is undefined behaviour to use callcc or Fiber with atomically.

    • +
    • If you create a new thread within an atomically, it will not be part of +the transaction. Creating a thread counts as a side-effect.

    • +
    + +

    We implement nested transactions by flattening.

    + +

    We only support strong isolation if you use the API correctly. In order words, +we do not support strong isolation.

    + +

    Our implementation uses a very simple algorithm that locks each TVar when it +is first read or written. If it cannot lock a TVar it aborts and retries. +There is no contention manager so competing transactions may retry eternally.

    + +
    require 'concurrent-ruby'
    +
    +v1 = Concurrent::TVar.new(0)
    +v2 = Concurrent::TVar.new(0)
    +
    +2.times.map{
    +  Thread.new do
    +    while true
    +      Concurrent::atomically do
    +        t1 = v1.value
    +        t2 = v2.value
    +        raise [t1, t2].inspect if t1 != t2 # detect zombie transactions
    +      end
    +    end
    +  end
    +
    +  Thread.new do
    +    100_000.times do
    +      Concurrent::atomically do
    +        v1.value += 1
    +        v2.value += 1
    +      end
    +    end
    +  end
    +}.each { |t| p t.join }
    +
    + +

    However, the inconsistent reads are detected correctly at commit time. This +means the script below will always print [2000000, 200000].

    + +
    require 'concurrent-ruby'
    +
    +v1 = Concurrent::TVar.new(0)
    +v2 = Concurrent::TVar.new(0)
    +
    +2.times.map{
    +  Thread.new do
    +    while true
    +      Concurrent::atomically do
    +        t1 = v1.value
    +        t2 = v2.value
    +      end
    +    end
    +  end
    +
    +  Thread.new do
    +    100_000.times do
    +      Concurrent::atomically do
    +        v1.value += 1
    +        v2.value += 1
    +      end
    +    end
    +  end
    +}.each { |t| p t.join }
    +
    +p [v1.value, v2.value]
    +
    + +

    This is called a lack of opacity. In the future we will look at more advanced +algorithms, contention management and using existing Java implementations when +in JRuby.

    + +

    Motivation

    + +

    Consider an application that transfers money between bank accounts. We want to +transfer money from one account to another. It is very important that we don't +lose any money! But it is also important that we can handle many account +transfers at the same time, so we run them concurrently, and probably also in +parallel.

    + +

    This code shows us transferring ten pounds from one account to another.

    + +
    a = BankAccount.new(100_000)
    +b = BankAccount.new(100)
    +
    +a.value -= 10
    +b.value += 10
    +
    + +

    Before we even start to talk about to talk about concurrency and parallelism, is +this code safe? What happens if after removing money from account a, we get an +exception? It's a slightly contrived example, but if the account totals were +very large, adding to them could involve the stack allocation of a BigNum, and +so could cause out of memory exceptions. In that case the money would have +disappeared from account a, but not appeared in account b. Disaster!

    + +

    So what do we really need to do?

    + +
    a = BankAccount.new(100_000)
    +b = BankAccount.new(100)
    +
    +original_a = a.value
    +a.value -= 10
    +
    +begin
    +  b.value += 10
    +rescue e =>
    +  a.value = original_a
    +  raise e
    +end
    +
    + +

    This rescues any exceptions raised when setting b and will roll back the change +we have already made to b. We'll keep this rescue code in mind, but we'll leave +it out of future examples for simplicity.

    + +

    That might have made the code work when it only runs sequentially. Lets start to +consider some concurrency. It's obvious that we want to make the transfer of +money mutually exclusive with any other transfers - in order words it is a +critical section.

    + +

    The usual solution to this would be to use a lock.

    + +
    lock.synchronize do
    +  a.value -= 10
    +  b.value += 10
    +end
    +
    + +

    That should work. Except we said we'd like these transfer to run concurrently, +and in parallel. With a single lock like that we'll only let one transfer take +place at a time. Perhaps we need more locks? We could have one per account:

    + +
    a.lock.synchronize do
    +  b.lock.synchronize do
    +    a.value -= 10
    +    b.value += 10
    +  end
    +end
    +
    + +

    However this is vulnerable to deadlock. If we tried to transfer from a to b, at +the same time as from b to a, it's possible that the first transfer locks a, the +second transfer locks b, and then they both sit there waiting forever to get the +other lock. Perhaps we can solve that by applying a total ordering to the locks +and always acquire them in the same order?

    + +
    locks_needed = [a.lock, b.lock]
    +locks_in_order = locks_needed.sort{ |x, y| x.number <=> y.number }
    +
    +locks_in_order[0].synchronize do
    +  locks_in_order[1].synchronize do
    +    a.value -= 10
    +    b.value += 10
    +  end
    +end
    +
    + +

    That might work. But we need to know exactly what locks we're going to need +before we start. If there were conditions in side the transfer this might be +more complicated. We also need to remember the rescue code we had above to deal +with exceptions. This is getting out of hand - and it's where TVar comes in.

    + +

    We'll model the accounts as TVar - transactional variable, and instead of +locks we'll use Concurrent::atomically.

    + +
    a = TVar.new(100_000)
    +b = TVar.new(100)
    +
    +Concurrent::atomically do
    +  a.value -= 10
    +  b.value += 10
    +end
    +
    + +

    That short piece of code effectively solves all the concerns we identified +above. How it does it is described in the reference above. You just need to be +happy that any two atomically blocks (we call them transactions) that use an +overlapping set of TVar objects will appear to have happened as if there was a +big global lock on them, and that if any exception is raised in the block, it +will be as if the block never happened. But also keep in mind the important +points we detailed right at the start of the article about side effects and +repeated execution.

  • +
+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(value) ⇒ TVar + + + + + +

+
+

Create a new TVar with an initial value.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+19
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 16
+
+def initialize(value)
+  @value = value
+  @lock = Mutex.new
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #valueundocumented + + + + + +

+
+

Get the value of a TVar.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+22
+23
+24
+25
+26
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 22
+
+def value
+  Concurrent::atomically do
+    Transaction::current.read(self)
+  end
+end
+
+
+ +
+

+ + #value=(value) ⇒ undocumented + + + + + +

+
+

Set the value of a TVar.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+29
+30
+31
+32
+33
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 29
+
+def value=(value)
+  Concurrent::atomically do
+    Transaction::current.write(self, value)
+  end
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ThreadLocalVar.html b/docs/1.1.10/Concurrent/ThreadLocalVar.html new file mode 100644 index 000000000..a57e71f23 --- /dev/null +++ b/docs/1.1.10/Concurrent/ThreadLocalVar.html @@ -0,0 +1,622 @@ + + + + + + + Class: Concurrent::ThreadLocalVar + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ThreadLocalVar + + + +

+
+ +
+
Inherits:
+
+ ThreadLocalVarImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb
+
+ +
+ +

Overview

+
+

A ThreadLocalVar is a variable where the value is different for each thread. +Each variable may have a default value, but when you modify the variable only +the current thread will ever see that change.

+ +

Thread-safe Variable Classes

+ +

Each of the thread-safe variable classes is designed to solve a different +problem. In general:

+ +
    +
  • Agent: Shared, mutable variable providing independent, +uncoordinated, asynchronous change of individual values. Best used when +the value will undergo frequent, complex updates. Suitable when the result +of an update does not need to be known immediately.
  • +
  • Atom: Shared, mutable variable providing independent, +uncoordinated, synchronous change of individual values. Best used when +the value will undergo frequent reads but only occasional, though complex, +updates. Suitable when the result of an update must be known immediately.
  • +
  • AtomicReference: A simple object reference that can be updated +atomically. Updates are synchronous but fast. Best used when updates a +simple set operations. Not suitable when updates are complex. +AtomicBoolean and AtomicFixnum are similar +but optimized for the given data type.
  • +
  • Exchanger: Shared, stateless synchronization point. Used +when two or more threads need to exchange data. The threads will pair then +block on each other until the exchange is complete.
  • +
  • MVar: Shared synchronization point. Used when one thread +must give a value to another, which must take the value. The threads will +block on each other until the exchange is complete.
  • +
  • ThreadLocalVar: Shared, mutable, isolated variable which +holds a different value for each thread which has access. Often used as +an instance variable in objects which must maintain different state +for different threads.
  • +
  • TVar: Shared, mutable variables which provide +coordinated, synchronous, change of many stated. Used when multiple +value must change together, in an all-or-nothing transaction.
  • +
+ + +
+
+
+ +
+

Examples:

+ + +
v = ThreadLocalVar.new(14)
+v.value #=> 14
+v.value = 2
+v.value #=> 2
+ + +
v = ThreadLocalVar.new(14)
+
+t1 = Thread.new do
+  v.value #=> 14
+  v.value = 1
+  v.value #=> 1
+end
+
+t2 = Thread.new do
+  v.value #=> 14
+  v.value = 2
+  v.value #=> 2
+end
+
+v.value #=> 14
+ +
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(default = nil, &default_block) ⇒ undocumented + + + + + +

+
+

Creates a thread local variable.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default + + + (Object) + + + (defaults to: nil) + + + — +

    the default value when otherwise unset

    +
    + +
  • + +
  • + + default_block + + + (Proc) + + + + — +

    Optional block that gets called to obtain the +default value for each thread

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+102
+103
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb', line 102
+
+class ThreadLocalVar < ThreadLocalVarImplementation
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #bind(value) { ... } ⇒ Object + + + + + +

+
+

Bind the given value to thread local storage during +execution of the given block.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the value to bind

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the operation to be performed with the bound variable

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+102
+103
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb', line 102
+
+class ThreadLocalVar < ThreadLocalVarImplementation
+end
+
+
+ +
+

+ + #valueObject + + + + + +

+
+

Returns the value in the current thread's copy of this thread-local variable.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+102
+103
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb', line 102
+
+class ThreadLocalVar < ThreadLocalVarImplementation
+end
+
+
+ +
+

+ + #value=(value) ⇒ Object + + + + + +

+
+

Sets the current thread's copy of this thread-local variable to the specified value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Object) + + + + — +

    the value to set

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+102
+103
+
+
# File 'lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb', line 102
+
+class ThreadLocalVar < ThreadLocalVarImplementation
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ThreadPoolExecutor.html b/docs/1.1.10/Concurrent/ThreadPoolExecutor.html new file mode 100644 index 000000000..23a808f5d --- /dev/null +++ b/docs/1.1.10/Concurrent/ThreadPoolExecutor.html @@ -0,0 +1,3756 @@ + + + + + + + Class: Concurrent::ThreadPoolExecutor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::ThreadPoolExecutor + + + +

+
+ +
+
Inherits:
+
+ ThreadPoolExecutorImplementation + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Failure to properly shutdown a thread pool can lead to unpredictable results. +Please read Shutting Down Thread Pools for more information.

+
+
+ +

An abstraction composed of one or more threads and a task queue. Tasks +(blocks or proc objects) are submitted to the pool and added to the queue. +The threads in the pool remove the tasks and execute them in the order +they were received.

+ +

A ThreadPoolExecutor will automatically adjust the pool size according +to the bounds set by min-threads and max-threads. When a new task is +submitted and fewer than min-threads threads are running, a new thread +is created to handle the request, even if other worker threads are idle. +If there are more than min-threads but less than max-threads threads +running, a new thread will be created only if the queue is full.

+ +

Threads that are idle for too long will be garbage collected, down to the +configured minimum options. Should a thread crash it, too, will be garbage collected.

+ +

ThreadPoolExecutor is based on the Java class of the same name. From +the official Java documentation;

+ +
+

Thread pools address two different problems: they usually provide +improved performance when executing large numbers of asynchronous tasks, +due to reduced per-task invocation overhead, and they provide a means +of bounding and managing the resources, including threads, consumed +when executing a collection of tasks. Each ThreadPoolExecutor also +maintains some basic statistics, such as the number of completed tasks.

+ +

To be useful across a wide range of contexts, this class provides many +adjustable parameters and extensibility hooks. However, programmers are +urged to use the more convenient Executors factory methods +CachedThreadPool, +FixedThreadPool and SingleThreadExecutor, that preconfigure settings for the most common usage +scenarios.

+
+ +

Thread Pool Options

+ +

Thread pools support several configuration options:

+ +
    +
  • idletime: The number of seconds that a thread may be idle before being reclaimed.
  • +
  • name: The name of the executor (optional). Printed in the executor's #to_s output and +a <name>-worker-<id> name is given to its threads if supported by used Ruby +implementation. <id> is uniq for each thread.
  • +
  • max_queue: The maximum number of tasks that may be waiting in the work queue at +any one time. When the queue size reaches max_queue and no new threads can be created, +subsequent tasks will be rejected in accordance with the configured fallback_policy.
  • +
  • auto_terminate: When true (default), the threads started will be marked as daemon.
  • +
  • fallback_policy: The policy defining how rejected tasks are handled.
  • +
+ +

Three fallback policies are supported:

+ +
    +
  • :abort: Raise a RejectedExecutionError exception and discard the task.
  • +
  • :discard: Discard the task and return false.
  • +
  • :caller_runs: Execute the task on the calling thread.
  • +
+ +

Shutting Down Thread Pools

+ +

Killing a thread pool while tasks are still being processed, either by calling +the #kill method or at application exit, will have unpredictable results. There +is no way for the thread pool to know what resources are being used by the +in-progress tasks. When those tasks are killed the impact on those resources +cannot be predicted. The best practice is to explicitly shutdown all thread +pools using the provided methods:

+ +
    +
  • Call #shutdown to initiate an orderly termination of all in-progress tasks
  • +
  • Call #wait_for_termination with an appropriate timeout interval an allow +the orderly shutdown to complete
  • +
  • Call #kill only when the thread pool fails to shutdown in the allotted time
  • +
+ +

On some runtime platforms (most notably the JVM) the application will not +exit until all thread pools have been shutdown. To prevent applications from +"hanging" on exit, all threads can be marked as daemon according to the +:auto_terminate option.

+ +
pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon
+pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon
+
+ + +
+
+
+

Direct Known Subclasses

+

CachedThreadPool, FixedThreadPool

+
+ + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Instance Attribute Details

+ + + +
+

+ + #completed_task_countInteger (readonly) + + + + + +

+
+

The number of tasks that have been completed by the pool since construction.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The number of tasks that have been completed by the pool since construction.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #fallback_policySymbol (readonly) + + + + + +

+
+

Returns The fallback policy in effect. Either :abort, :discard, or :caller_runs.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Symbol) + + + + — +

    The fallback policy in effect. Either :abort, :discard, or :caller_runs.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #idletimeInteger (readonly) + + + + + +

+
+

The number of seconds that a thread may be idle before being reclaimed.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The number of seconds that a thread may be idle before being reclaimed.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #largest_lengthInteger (readonly) + + + + + +

+
+

The largest number of threads that have been created in the pool since construction.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The largest number of threads that have been created in the pool since construction.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #lengthInteger (readonly) + + + + + +

+
+

The number of threads currently in the pool.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The number of threads currently in the pool.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #max_lengthInteger (readonly) + + + + + +

+
+

The maximum number of threads that may be created in the pool.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The maximum number of threads that may be created in the pool.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #max_queueInteger (readonly) + + + + + +

+
+

The maximum number of tasks that may be waiting in the work queue at any one time. +When the queue size reaches max_queue subsequent tasks will be rejected in +accordance with the configured fallback_policy.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The maximum number of tasks that may be waiting in the work queue at any one time. +When the queue size reaches max_queue subsequent tasks will be rejected in +accordance with the configured fallback_policy.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #min_lengthInteger (readonly) + + + + + +

+
+

The minimum number of threads that may be retained in the pool.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The minimum number of threads that may be retained in the pool.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #queue_lengthInteger (readonly) + + + + + +

+
+

The number of tasks in the queue awaiting execution.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The number of tasks in the queue awaiting execution.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #remaining_capacityInteger (readonly) + + + + + +

+
+

Number of tasks that may be enqueued before reaching max_queue and rejecting +new tasks. A value of -1 indicates that the queue may grow without bound.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    Number of tasks that may be enqueued before reaching max_queue and rejecting +new tasks. A value of -1 indicates that the queue may grow without bound.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ + + +
+

+ + #scheduled_task_countInteger (readonly) + + + + + +

+
+

The number of tasks that have been scheduled for execution on the pool since construction.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The number of tasks that have been scheduled for execution on the pool since construction.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #<<(task) ⇒ self + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + task + + + (Proc) + + + + — +

    the asynchronous task to perform

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (self) + + + + — +

    returns itself

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #auto_terminate=(value) ⇒ Boolean + + + + + +

+
+
Deprecated.

Has no effect

+
+

Set the auto-terminate behavior for this executor.

+ + +
+
+
+

Parameters:

+
    + +
  • + + value + + + (Boolean) + + + + — +

    The new auto-terminate value to set for this executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when auto-termination is enabled else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #auto_terminate?Boolean + + + + + +

+
+

Is the executor auto-terminate when the application exits?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when auto-termination is enabled else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #can_overflow?Boolean + + + + + +

+
+

Does the task queue have a maximum size?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if the task queue has a maximum size else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #killundocumented + + + + + +

+
+

Begin an immediate shutdown. In-progress tasks will be allowed to +complete but enqueued tasks will be dismissed and no new tasks +will be accepted. Has no additional effect if the thread pool is +not running.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #post(*args) { ... } ⇒ Boolean + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + 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

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #prune_poolundocumented + + + + + +

+
+

Prune the thread pool of unneeded threads

+ +

What is being pruned is controlled by the min_threads and idletime +parameters passed at pool creation time

+ +

This is a no-op on some pool implementation (e.g. the Java one). The Ruby +pool will auto-prune each time a new job is posted. You will need to call +this method explicitely in case your application post jobs in bursts (a +lot of jobs and then nothing for long periods)

+ + +
+
+
+ + +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #running?Boolean + + + + + +

+
+

Is the executor running?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when running, false when shutting down or shutdown

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #serialized?Boolean + + + + + +

+
+

Does this executor guarantee serialization of its operations?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if the executor guarantees that all operations +will be post in the order they are received and no two operations may +occur simultaneously. Else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #shutdownundocumented + + + + + +

+
+

Begin an orderly shutdown. Tasks already in the queue will be executed, +but no new tasks will be accepted. Has no additional effect if the +thread pool is not running.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #shutdown?Boolean + + + + + +

+
+

Is the executor shutdown?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when shutdown, false when shutting down or running

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #shuttingdown?Boolean + + + + + +

+
+

Is the executor shuttingdown?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when not running and not shutdown, else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+

+ + #wait_for_termination(timeout = nil) ⇒ Boolean + + + + + +

+
+ +
+ Note: +

Does not initiate shutdown or termination. Either shutdown or kill +must be called before this method (or on another thread).

+
+
+ +

Block until executor shutdown is complete or until timeout seconds have +passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Integer) + + + (defaults to: nil) + + + — +

    the maximum number of seconds to wait for shutdown to complete

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if shutdown complete or false on timeout

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb', line 56
+
+class ThreadPoolExecutor < ThreadPoolExecutorImplementation
+
+  # @!macro thread_pool_executor_method_initialize
+  #
+  #   Create a new thread pool.
+  #
+  #   @param [Hash] opts the options which configure the thread pool.
+  #
+  #   @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
+  #     number of threads to be created
+  #   @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
+  #      and fewer than `min_threads` are running, a new thread is created
+  #   @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
+  #     number of seconds a thread may be idle before being reclaimed
+  #   @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
+  #     number of tasks allowed in the work queue at any one time; a value of
+  #     zero means the queue may grow without bound
+  #   @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
+  #     tasks that are received when the queue size has reached
+  #     `max_queue` or the executor has shut down
+  #   @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0
+  #     for :max_queue means the queue must perform direct hand-off rather than unbounded.
+  #   @raise [ArgumentError] if `:max_threads` is less than one
+  #   @raise [ArgumentError] if `:min_threads` is less than zero
+  #   @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
+  #     in `FALLBACK_POLICIES`
+  #
+  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
+
+  # @!method initialize(opts = {})
+  #   @!macro thread_pool_executor_method_initialize
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/ThreadSafe/Util/XorShiftRandom.html b/docs/1.1.10/Concurrent/ThreadSafe/Util/XorShiftRandom.html new file mode 100644 index 000000000..88378f86f --- /dev/null +++ b/docs/1.1.10/Concurrent/ThreadSafe/Util/XorShiftRandom.html @@ -0,0 +1,452 @@ + + + + + + + Module: Concurrent::ThreadSafe::Util::XorShiftRandom + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::ThreadSafe::Util::XorShiftRandom + + + +

+
+ + + + +
+
Extended by:
+
XorShiftRandom
+
+ + + + + + +
+
Included in:
+
XorShiftRandom
+
+ + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb
+
+ +
+ +

Overview

+
+

A xorshift random number (positive +Fixnum+s) generator, provides +reasonably cheap way to generate thread local random numbers without +contending for the global +Kernel.rand+.

+ +

Usage: + x = XorShiftRandom.get # uses Kernel.rand to generate an initial seed + while true + if (x = XorShiftRandom.xorshift).odd? # thread-localy generate a next random number + do_something_at_random + end + end

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
MAX_XOR_SHIFTABLE_INT = + +
+
MAX_INT - 1
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .getundocumented + + + + + +

+
+

Generates an initial non-zero positive +Fixnum+ via +Kernel.rand+.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb', line 27
+
+def get
+  Kernel.rand(MAX_XOR_SHIFTABLE_INT) + 1 # 0 can't be xorshifted
+end
+
+
+ +
+

+ + .xorshift(x) ⇒ undocumented + + + + + +

+
+

using the "yˆ=y>>a; yˆ=y<>c;" transform with the (a,b,c) tuple with values (1,1,54) to minimise Bignum overflows

+ + +
+
+
+ + +
+ + + + +
+
+
+
+34
+35
+36
+37
+38
+
+
# File 'lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb', line 34
+
+def xorshift(x)
+  x ^= x >> 3
+  x ^= (x << 1) & MAX_INT # cut-off Bignum overflow
+  x ^= x >> 14
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #getundocumented + + + + + +

+
+

Generates an initial non-zero positive +Fixnum+ via +Kernel.rand+.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb', line 27
+
+def get
+  Kernel.rand(MAX_XOR_SHIFTABLE_INT) + 1 # 0 can't be xorshifted
+end
+
+
+ +
+

+ + #xorshift(x) ⇒ undocumented + + + + + +

+
+

using the "yˆ=y>>a; yˆ=y<>c;" transform with the (a,b,c) tuple with values (1,1,54) to minimise Bignum overflows

+ + +
+
+
+ + +
+ + + + +
+
+
+
+34
+35
+36
+37
+38
+
+
# File 'lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb', line 34
+
+def xorshift(x)
+  x ^= x >> 3
+  x ^= (x << 1) & MAX_INT # cut-off Bignum overflow
+  x ^= x >> 14
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Throttle.html b/docs/1.1.10/Concurrent/Throttle.html new file mode 100644 index 000000000..a5f2da541 --- /dev/null +++ b/docs/1.1.10/Concurrent/Throttle.html @@ -0,0 +1,4374 @@ + + + + + + + Class: Concurrent::Throttle + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Throttle + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + +
+
Includes:
+
Promises::FactoryMethods
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/edge/throttle.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

A tool managing concurrency level of tasks. +The maximum capacity is set in constructor. +Each acquire will lower the available capacity and release will increase it. +When there is no available capacity the current thread may either be blocked or +an event is returned which will be resolved when capacity becomes available.

+ +

The more common usage of the Throttle is with a proxy executor +a_throttle.on(Concurrent.global_io_executor). +Anything executed on the proxy executor will be throttled and +execute on the given executor. There can be more than one proxy executors. +All abstractions which execute tasks have option to specify executor, +therefore the proxy executor can be injected to any abstraction +throttling its concurrency level.

+ +

Examples

+ +

Limiting concurrency level of a concurrently executed block to two

+ +
max_two = Concurrent::Throttle.new 2
+# => #
+
+# used to track concurrency level
+concurrency_level = Concurrent::AtomicFixnum.new
+# => #
+job = -> do
+  # increase the current level at the beginning of the throttled block    
+  concurrency_level.increment
+  # work, takes some time
+  do_stuff
+  # read the current concurrency level 
+  current_concurrency_level = concurrency_level.value
+  # decrement the concurrency level back at the end of the block            
+  concurrency_level.decrement
+  # return the observed concurrency level 
+  current_concurrency_level
+end 
+
+# create 10 threads running concurrently the jobs
+Array.new(10) do  
+  Thread.new do
+    max_two.acquire(&job)   
+  end
+# wait for all the threads to finish and read the observed 
+# concurrency level in each of them   
+end.map(&:value)                         # => [2, 2, 1, 1, 1, 2, 2, 2, 2, 1]
+
+ +

Notice that the returned array has no number bigger than 2 therefore +the concurrency level of the block with the do_stuff was never bigger than 2.

+ +
# runs a block, and returns he observed concurrency level during the execution
+def monitor_concurrency_level(concurrency_level, &block)
+  concurrency_level.increment
+  block.call
+  current_concurrency_level = concurrency_level.value
+  concurrency_level.decrement
+  # return the observed concurrency level
+  return current_concurrency_level 
+end 
+
+throttle = Concurrent::Throttle.new 3
+# => #
+concurrency_level = Concurrent::AtomicFixnum.new 
+# => #
+
+Array.new(10) do |i|
+  # create throttled future
+  throttle.future(i) do |arg|
+    monitor_concurrency_level(concurrency_level) { do_stuff arg }  
+    # fulfill with the observed concurrency level
+  end
+# collect observed concurrency levels   
+end.map(&:value!)                        # => [3, 2, 1, 2, 1, 3, 3, 1, 2, 1]
+
+ +

The concurrency level does not rise above 3.

+ +

It works by setting the executor of the future created from the throttle. +The executor is a proxy executor for the Concurrent::Promises.default_executor +which can be obtained using #on method. +Therefore the above example could be instead more explicitly written as follows

+ +
# ...
+Array.new(10) do |i|
+  # create throttled future
+  Concurrent::Promises.future_on(throttle.on(Concurrent::Promises.default_executor)) do
+    # ...
+  end
+end.map(&:value!) 
+
+ +

Anything executed on the proxy executor is throttled. +A throttle can have more proxy executors for different executors, +all jobs share the same capacity provided by the throttle.

+ +

Since the proxy executor becomes the executor of the future, +any chained futures will also be throttled. +It can be changed by using different executor. +It the following example the first 2 futures in the chain are throttled, +the last is not.

+ +
concurrency_level_throttled   = Concurrent::AtomicFixnum.new 
+concurrency_level_unthrottled = Concurrent::AtomicFixnum.new 
+Array.new(10) do |i|
+  throttle.future(i) do 
+    monitor_concurrency_level(concurrency_level_throttled) { do_stuff } 
+  end.then do |v|
+    [v, monitor_concurrency_level(concurrency_level_throttled) { do_stuff }]
+  end.then_on(:io) do |l1, l2|
+    [l1, l2, monitor_concurrency_level(concurrency_level_unthrottled) { 5.times { do_stuff } }]
+  end
+end.map(&:value!) 
+# => [[3, 3, 7],
+#     [3, 2, 9],
+#     [3, 3, 10],
+#     [3, 3, 6],
+#     [3, 3, 5],
+#     [3, 3, 8],
+#     [3, 3, 3],
+#     [3, 3, 4],
+#     [3, 2, 2],
+#     [3, 1, 1]]
+
+ +

In the output you can see that the first 2 columns do not cross the 3 capacity limit +and the last column which is untroubled does.

+ +

TODO (pitr-ch 20-Dec-2018): example with virtual throttled executor, +throttling only part of promises chain.

+ +

Other abstraction

+ +

The proxy executor created with throttle can be used with other abstractions as well +and combined.

+ +
concurrency_level = Concurrent::AtomicFixnum.new 
+futures = Array.new(5) do |i|
+  # create throttled future
+  throttle.future(i) do |arg|
+    monitor_concurrency_level(concurrency_level) { do_stuff arg }  
+    # fulfill with the observed concurrency level
+  end
+end 
+agents = Array.new(5) do |i|
+  agent = Concurrent::Agent.new 0
+  # execute agent update on throttled executor
+  agent.send_via(throttle.on(:io)) { monitor_concurrency_level(concurrency_level_throttled) { do_stuff } }
+  agent 
+end 
+futures.map(&:value!)                    # => [3, 3, 3, 2, 1]
+agents.each { |a| a.await }.map(&:value) 
+# => [3, 2, 3, 3, 1]
+
+ +

There is no observed concurrency level above 3.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(capacity) ⇒ Throttle + + + + + +

+
+

Create throttle.

+ + +
+
+
+

Parameters:

+
    + +
  • + + capacity + + + (Integer) + + + + — +

    How many tasks using this throttle can run at the same time.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+39
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 33
+
+def initialize(capacity)
+  super()
+  @MaxCapacity            = capacity
+  @Queue                  = LockFreeQueue.new
+  @executor_cache         = [nil, nil]
+  self.capacity = capacity
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #acquire(timeout = nil) { ... } ⇒ Object, self, true, false + + + + + +

+
+

Blocks current thread until there is capacity available in the throttle. +The acquired capacity has to be returned to the throttle by calling #release. +If block is passed then the block is called after the capacity is acquired and +it is automatically released after the block is executed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Numeric) + + + (defaults to: nil) + + + — +

    the maximum time in second to wait.

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    [] block to execute after the capacity is acquired

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object, self, true, false) + + + + — +
      +
    • When no timeout and no block it returns self
    • +
    • When no timeout and with block it returns the result of the block
    • +
    • When with timeout and no block it returns true when acquired and false when timed out
    • +
    • When with timeout and with block it returns the result of the block of nil on timing out
    • +
    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 59
+
+def acquire(timeout = nil, &block)
+  event = acquire_or_event
+  if event
+    within_timeout = event.wait(timeout)
+    # release immediately when acquired later after the timeout since it is unused
+    event.on_resolution!(self, &:release) unless within_timeout
+  else
+    within_timeout = true
+  end
+
+  called = false
+  if timeout
+    if block
+      if within_timeout
+        called = true
+        block.call
+      else
+        nil
+      end
+    else
+      within_timeout
+    end
+  else
+    if block
+      called = true
+      block.call
+    else
+      self
+    end
+  end
+ensure
+  release if called
+end
+
+
+ +
+

+ + #available_capacityInteger + + + + + +

+
+

Returns The available capacity.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The available capacity.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+26
+27
+28
+29
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 26
+
+def available_capacity
+  current_capacity = capacity
+  current_capacity >= 0 ? current_capacity : 0
+end
+
+
+ +
+

+ + #default_executorExecutorService + + + + + +

+
+

Uses executor provided by #on therefore +all events and futures created using factory methods on this object will be throttled. +Overrides Promises::FactoryMethods::Configuration#default_executor.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (ExecutorService) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+179
+180
+181
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 179
+
+def default_executor
+  on(super)
+end
+
+
+ +
+

+ + #max_capacityInteger + + + + + +

+
+

Returns The maximum capacity.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    The maximum capacity.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+42
+43
+44
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 42
+
+def max_capacity
+  @MaxCapacity
+end
+
+
+ +
+

+ + #on(executor = Promises::FactoryMethods.default_executor) ⇒ ExecutorService + + + + + +

+
+

Returns An executor which wraps given executor and allows to post tasks only +as available capacity in the throttle allows.

+ + +
+
+
+ +
+

Examples:

+ + +

throttling future

+

+ +
a_future.then_on(a_throttle.on(:io)) { a_throttled_task }
+ +
+

Parameters:

+
    + +
  • + + executor + + + (ExecutorService) + + + (defaults to: Promises::FactoryMethods.default_executor) + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (ExecutorService) + + + + — +

    An executor which wraps given executor and allows to post tasks only +as available capacity in the throttle allows.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 158
+
+def on(executor = Promises::FactoryMethods.default_executor)
+  current_executor, current_cache = @executor_cache
+  return current_cache if current_executor == executor && current_cache
+
+  if current_executor.nil?
+    # cache first proxy
+    proxy_executor  = ProxyExecutor.new(self, Concurrent.executor(executor))
+    @executor_cache = [executor, proxy_executor]
+    return proxy_executor
+  else
+    # do not cache more than 1 executor
+    ProxyExecutor.new(self, Concurrent.executor(executor))
+  end
+end
+
+
+ +
+

+ + #releaseself + + + + + +

+
+

Releases previously acquired capacity back to Throttle. +Has to be called exactly once for each acquired capacity.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (self) + + + +
  • + +
+ +

See Also:

+
    + +
  • #acquire, #try_acquire
  • + +
+ +
+ + + + +
+
+
+
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 114
+
+def release
+  while true
+    current_capacity = capacity
+    if compare_and_set_capacity current_capacity, current_capacity + 1
+      if current_capacity < 0
+        # release called after trigger which pushed a trigger, busy wait is ok
+        Thread.pass until (trigger = @Queue.pop)
+        trigger.resolve
+      end
+      return self
+    end
+  end
+end
+
+
+ +
+

+ + #to_sString + + + + Also known as: + inspect + + + + +

+
+

Returns Short string representation.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    Short string representation.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+129
+130
+131
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 129
+
+def to_s
+  format '%s capacity available %d of %d>', super[0..-2], capacity, @MaxCapacity
+end
+
+
+ +
+

+ + #try_acquiretrue, false + + + + + +

+
+

Tries to acquire capacity from the throttle. +Returns true when there is capacity available. +The acquired capacity has to be returned to the throttle by calling #release.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+
+
# File 'lib/concurrent-ruby-edge/concurrent/edge/throttle.rb', line 98
+
+def try_acquire
+  while true
+    current_capacity = capacity
+    if current_capacity > 0
+      return true if compare_and_set_capacity(
+          current_capacity, current_capacity - 1)
+    else
+      return false
+    end
+  end
+end
+
+
+ +
+

+ + #any_event(*futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #any_event_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + #any_event_on(default_executor, *futures_and_or_events) ⇒ Event + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates new event which becomes resolved after first of the futures_and_or_events resolves. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+
+ +
+

+ + #any_fulfilled_future(*futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #any_fulfilled_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + #any_fulfilled_future_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates new future which is resolved after first of futures_and_or_events is fulfilled. +Its result equals result of the first resolved future or if all futures_and_or_events reject, +it has reason of the last resolved future. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + #any_resolved_future(*futures_and_or_events) ⇒ Future + + + + Also known as: + any + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #any_resolved_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + #any_resolved_future_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates new future which is resolved after first futures_and_or_events is resolved. +Its result equals result of the first resolved future. +If resolved it does not propagate AbstractEventFuture#touch, leaving delayed +futures un-executed if they are not required any more. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + #delay(*args, &task) ⇒ Future, Event + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #delay_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+
+ +
+

+ + + #delay_on(default_executor, *args) {|*args| ... } ⇒ Future + + #delay_on(default_executor) ⇒ Event + + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates new event or future which is resolved only after it is touched, +see AbstractEventFuture#touch.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #delay_on(default_executor, *args) {|*args| ... } ⇒ Future +
    +
    +

    If task is provided it returns a Concurrent::Promises::Future representing the result of the task.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + args + + + (Object) + + + + — +

      arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

      +
      + +
    • + +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Returns:

    + +

    Returns:

    +
      + +
    • + + + (Future) + + + +
    • + +
    + +
    +
  • + + +
  • + #delay_on(default_executor) ⇒ Event +
    +
    +

    If no task is provided, it returns an Event

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ + +
+
+ +
+

+ + #fulfilled_future(value, default_executor = self.default_executor) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates resolved future with will be fulfilled with the given value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + #future(*args, &task) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + #future_on(default_executor, *args) {|*args| ... } ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Constructs new Future which will be resolved after block is evaluated on default executor. +Evaluation begins immediately.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + args + + + (Object) + + + + — +

    arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (*args) + + + + — +

    to the task.

    +
    + +
  • + +
+

Yield Returns:

+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + + #make_future(nil, default_executor = self.default_executor) ⇒ Event + + #make_future(a_future, default_executor = self.default_executor) ⇒ Future + + #make_future(an_event, default_executor = self.default_executor) ⇒ Event + + #make_future(exception, default_executor = self.default_executor) ⇒ Future + + #make_future(value, default_executor = self.default_executor) ⇒ Future + + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

General constructor. Behaves differently based on the argument's type. It's provided for convenience +but it's better to be explicit.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #make_future(nil, default_executor = self.default_executor) ⇒ Event +
    +
    +

    Returns resolved event.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + nil + + + (nil) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + + — +

      resolved event.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(a_future, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a future which will be resolved when a_future is.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + a_future + + + (Future) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a future which will be resolved when a_future is.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(an_event, default_executor = self.default_executor) ⇒ Event +
    +
    +

    Returns an event which will be resolved when an_event is.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + an_event + + + (Event) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + + — +

      an event which will be resolved when an_event is.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(exception, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a rejected future with the exception as its reason.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + exception + + + (Exception) + + + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a rejected future with the exception as its reason.

      +
      + +
    • + +
    + +
    +
  • + + +
  • + #make_future(value, default_executor = self.default_executor) ⇒ Future +
    +
    +

    Returns a fulfilled future with the value.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + value + + + (Object) + + + + — +

      when none of the above overloads fits

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Future) + + + + — +

      a fulfilled future with the value.

      +
      + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +

See Also:

+
    + +
  • resolved_event, fulfilled_future
  • + +
+ +
+
+ +
+

+ + #rejected_future(reason, default_executor = self.default_executor) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates resolved future with will be rejected with the given reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + reason + + + (Object) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + #resolvable_eventResolvableEvent + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #resolvable_event_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+
+ +
+

+ + #resolvable_event_on(default_executor = self.default_executor) ⇒ ResolvableEvent + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Created resolvable event, user is responsible for resolving the event once by +ResolvableEvent#resolve.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +
+
+ +
+

+ + #resolvable_futureResolvableFuture + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #resolvable_future_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+
+ +
+

+ + #resolvable_future_on(default_executor = self.default_executor) ⇒ ResolvableFuture + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates resolvable future, user is responsible for resolving the future once by +ResolvableFuture#resolve, ResolvableFuture#fulfill, +or ResolvableFuture#reject

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+ + +
+
+ +
+

+ + #resolved_event(default_executor = self.default_executor) ⇒ Event + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates resolved event.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+
+ +
+

+ + #resolved_future(fulfilled, value, reason, default_executor = self.default_executor) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates resolved future with will be either fulfilled with the given value or rejection with +the given reason.

+ + +
+
+
+

Parameters:

+
    + +
  • + + fulfilled + + + (true, false) + + + +
  • + +
  • + + value + + + (Object) + + + +
  • + +
  • + + reason + + + (Object) + + + +
  • + +
  • + + default_executor + + + (Executor, :io, :fast) + + + (defaults to: self.default_executor) + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + #schedule(intended_time, *args, &task) ⇒ Future, Event + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #schedule_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+ + +

See Also:

+ + +
+
+ +
+

+ + + #schedule_on(default_executor, intended_time, *args) {|*args| ... } ⇒ Future + + #schedule_on(default_executor, intended_time) ⇒ Event + + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates new event or future which is resolved in intended_time.

+ + +
+
+
+ +

Overloads:

+
    + + +
  • + #schedule_on(default_executor, intended_time, *args) {|*args| ... } ⇒ Future +
    +
    +

    If task is provided it returns a Concurrent::Promises::Future representing the result of the task.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + args + + + (Object) + + + + — +

      arguments which are passed to the task when it's executed. +(It might be prepended with other arguments, see the @yeild section).

      +
      + +
    • + +
    + +

    Yields:

    +
      + +
    • + + + (*args) + + + + — +

      to the task.

      +
      + +
    • + +
    +

    Yield Returns:

    + +

    Returns:

    +
      + +
    • + + + (Future) + + + +
    • + +
    + +
    +
  • + + +
  • + #schedule_on(default_executor, intended_time) ⇒ Event +
    +
    +

    If no task is provided, it returns an Event

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Event) + + + +
    • + +
    + +
    +
  • + +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + intended_time + + + (Numeric, Time) + + + + — +

    Numeric means to run in intended_time seconds. +Time means to run on intended_time.

    +
    + +
  • + +
+ + +
+
+ +
+

+ + #zip_events(*futures_and_or_events) ⇒ Event + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #zip_events_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + #zip_events_on(default_executor, *futures_and_or_events) ⇒ Event + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates new event which is resolved after all futures_and_or_events are resolved. +(Future is resolved when fulfilled or rejected.)

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Event) + + + +
  • + +
+ +
+
+ +
+

+ + #zip_futures(*futures_and_or_events) ⇒ Future + + + + Also known as: + zip + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Shortcut of #zip_futures_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + #zip_futures_on(default_executor, *futures_and_or_events) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+

Creates new future which is resolved after all futures_and_or_events are resolved. +Its value is array of zipped future values. Its reason is array of reasons for rejection. +If there is an error it rejects. +If event is supplied, which does not have value and can be only resolved, it's +represented as :fulfilled with value nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + futures_and_or_events + + + (AbstractEventFuture) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+

+ + #zip_futures_over(enumerable, &future_factory) ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Shortcut of #zip_futures_over_on with default :io executor supplied.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +

See Also:

+ + +
+
+ +
+

+ + #zip_futures_over_on(default_executor, enumerable) {|element| ... } ⇒ Future + + + + + + + Originally defined in module + Promises::FactoryMethods + + +

+
+ +
+ Note: +

Edge Features are under active development and may change frequently.

+ +
    +
  • Deprecations are not added before incompatible changes.
  • +
  • Edge version: major is always 0, minor bump means incompatible change, +patch bump means compatible change.
  • +
  • Edge features may also lack tests and documentation.
  • +
  • Features developed in concurrent-ruby-edge are expected to move +to concurrent-ruby when finalised.
  • +
+
+
+ +

Creates new future which is resolved after all the futures created by future_factory from +enumerable elements are resolved. Simplified it does: +zip(*enumerable.map { |e| future e, &future_factory })

+ + +
+
+
+ +
+

Examples:

+ + +
# `#succ` calls are executed in parallel
+zip_futures_over_on(:io, [1, 2], &:succ).value! # => [2, 3]
+ +
+

Parameters:

+
    + +
  • + + default_executor + + + (Executor, :io, :fast) + + + + — +

    Instance of an executor or a name of the +global executor. Default executor propagates to chained futures unless overridden with +executor parameter or changed with AbstractEventFuture#with_default_executor.

    +
    + +
  • + +
  • + + enumerable + + + (Enumerable) + + + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    a task to be executed in future

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + element + + + (Object) + + + + — +

    from enumerable

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Object) + + + + — +

    a value of the future

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Future) + + + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/TimerSet.html b/docs/1.1.10/Concurrent/TimerSet.html new file mode 100644 index 000000000..d7a11a017 --- /dev/null +++ b/docs/1.1.10/Concurrent/TimerSet.html @@ -0,0 +1,563 @@ + + + + + + + Class: Concurrent::TimerSet + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::TimerSet + + + +

+
+ +
+
Inherits:
+
+ RubyExecutorService + +
    +
  • Object
  • + + + + + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/executor/timer_set.rb
+
+ +
+ +

Overview

+
+ +
+ Note: +

Time calculations on all platforms and languages are sensitive to +changes to the system clock. To alleviate the potential problems +associated with changing the system clock while an application is running, +most modern operating systems provide a monotonic clock that operates +independently of the system clock. A monotonic clock cannot be used to +determine human-friendly clock times. A monotonic clock is used exclusively +for calculating time intervals. Not all Ruby platforms provide access to an +operating system monotonic clock. On these platforms a pure-Ruby monotonic +clock will be used as a fallback. An operating system monotonic clock is both +faster and more reliable than the pure-Ruby implementation. The pure-Ruby +implementation should be fast and reliable enough for most non-realtime +operations. At this time the common Ruby platforms that provide access to an +operating system monotonic clock are MRI 2.1 and above and JRuby (all versions).

+
+
+ +

Executes a collection of tasks, each after a given delay. A master task +monitors the set and schedules each task for execution at the appropriate +time. Tasks are run on the global thread pool or on the supplied executor. +Each task is represented as a ScheduledTask.

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(opts = {}) ⇒ TimerSet + + + + + +

+
+

Create a new set of timed tasks.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options used to specify the executor on which to perform actions

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :executor + (Executor) + + + + + —

    when set use the given Executor instance. +Three special values are also supported: :task returns the global task pool, +:operation returns the global operation pool, and :immediate returns a new +ImmediateExecutor object.

    +
    + +
  • + +
+ + + +
+ + + + +
+
+
+
+30
+31
+32
+
+
# File 'lib/concurrent-ruby/concurrent/executor/timer_set.rb', line 30
+
+def initialize(opts = {})
+  super(opts)
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #killundocumented + + + + + +

+
+

Begin an immediate shutdown. In-progress tasks will be allowed to +complete but enqueued tasks will be dismissed and no new tasks +will be accepted. Has no additional effect if the thread pool is +not running.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+62
+63
+64
+
+
# File 'lib/concurrent-ruby/concurrent/executor/timer_set.rb', line 62
+
+def kill
+  shutdown
+end
+
+
+ +
+

+ + #post(delay, *args) { ... } ⇒ Concurrent::ScheduledTask, false + + + + + +

+
+

Post a task to be execute run after a given delay (in seconds). If the +delay is less than 1/100th of a second the task will be immediately post +to the executor.

+ + +
+
+
+

Parameters:

+
    + +
  • + + delay + + + (Float) + + + + — +

    the number of seconds to wait for before executing the task.

    +
    + +
  • + +
  • + + args + + + (Array<Object>) + + + + — +

    the arguments passed to the task on execution.

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the task to be performed.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Concurrent::ScheduledTask, false) + + + + — +

    IVar representing the task if the post +is successful; false after shutdown.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    if the intended execution time is not in the future.

    +
    + +
  • + +
  • + + + (ArgumentError) + + + + — +

    if no block is given.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/concurrent-ruby/concurrent/executor/timer_set.rb', line 48
+
+def post(delay, *args, &task)
+  raise ArgumentError.new('no block given') unless block_given?
+  return false unless running?
+  opts = { executor:  @task_executor,
+           args:      args,
+           timer_set: self }
+  task = ScheduledTask.execute(delay, opts, &task) # may raise exception
+  task.unscheduled? ? false : task
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/TimerTask.html b/docs/1.1.10/Concurrent/TimerTask.html new file mode 100644 index 000000000..b72752492 --- /dev/null +++ b/docs/1.1.10/Concurrent/TimerTask.html @@ -0,0 +1,1843 @@ + + + + + + + Class: Concurrent::TimerTask + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::TimerTask + + + +

+
+ +
+
Inherits:
+
+ RubyExecutorService + +
    +
  • Object
  • + + + + + + + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Concern::Dereferenceable, Concern::Observable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/timer_task.rb
+
+ +
+ +

Overview

+
+

A very common concurrency pattern is to run a thread that performs a task at +regular intervals. The thread that performs the task sleeps for the given +interval then wakes up and performs the task. Lather, rinse, repeat... This +pattern causes two problems. First, it is difficult to test the business +logic of the task because the task itself is tightly coupled with the +concurrency logic. Second, an exception raised while performing the task can +cause the entire thread to abend. In a long-running application where the +task thread is intended to run for days/weeks/years a crashed task thread +can pose a significant problem. TimerTask alleviates both problems.

+ +

When a TimerTask is launched it starts a thread for monitoring the +execution interval. The TimerTask thread does not perform the task, +however. Instead, the TimerTask launches the task on a separate thread. +Should the task experience an unrecoverable crash only the task thread will +crash. This makes the TimerTask very fault tolerant. Additionally, the +TimerTask thread can respond to the success or failure of the task, +performing logging or ancillary operations.

+ +

One other advantage of TimerTask is that it forces the business logic to +be completely decoupled from the concurrency logic. The business logic can +be tested separately then passed to the TimerTask for scheduling and +running.

+ +

In some cases it may be necessary for a TimerTask to affect its own +execution cycle. To facilitate this, a reference to the TimerTask instance +is passed as an argument to the provided block every time the task is +executed.

+ +

The TimerTask class includes the Dereferenceable mixin module so the +result of the last execution is always available via the #value method. +Dereferencing options can be passed to the TimerTask during construction or +at any later time using the #set_deref_options method.

+ +

TimerTask supports notification through the Ruby standard library +Observable module. On execution the TimerTask will notify the observers +with three arguments: time of execution, the result of the block (or nil on +failure), and any raised exceptions (or nil on success).

+ +

Copy Options

+ +

Object references in Ruby are mutable. This can lead to serious +problems when the Concern::Dereferenceable#value of an object is a mutable reference. Which +is always the case unless the value is a Fixnum, Symbol, or similar +"primitive" data type. Each instance can be configured with a few +options that can help protect the program from potentially dangerous +operations. Each of these options can be optionally set when the object +instance is created:

+ +
    +
  • :dup_on_deref When true the object will call the #dup method on +the value object every time the #value method is called +(default: false)
  • +
  • :freeze_on_deref When true the object will call the #freeze +method on the value object every time the #value method is called +(default: false)
  • +
  • :copy_on_deref When given a Proc object the Proc will be run +every time the #value method is called. The Proc will be given +the current value as its only argument and the result returned by +the block will be the return value of the #value call. When nil +this option will be ignored (default: nil)
  • +
+ +

When multiple deref options are set the order of operations is strictly defined. +The order of deref operations is:

+ +
    +
  • :copy_on_deref
  • +
  • :dup_on_deref
  • +
  • :freeze_on_deref
  • +
+ +

Because of this ordering there is no need to #freeze an object created by a +provided :copy_on_deref block. Simply set :freeze_on_deref to true. +Setting both :dup_on_deref to true and :freeze_on_deref to true is +as close to the behavior of a "pure" functional language (like Erlang, Clojure, +or Haskell) as we are likely to get in Ruby.

+ + +
+
+
+ +
+

Examples:

+ + +

Basic usage

+

+ +
task = Concurrent::TimerTask.new{ puts 'Boom!' }
+task.execute
+
+task.execution_interval #=> 60 (default)
+
+# wait 60 seconds...
+#=> 'Boom!'
+
+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
+
+#=> 'Boom!'
+ + +

Last #value and Dereferenceable mixin

+

+ +
task = Concurrent::TimerTask.new(
+  dup_on_deref: true,
+  execution_interval: 5
+){ Time.now }
+
+task.execute
+Time.now   #=> 2013-11-07 18:06:50 -0500
+sleep(10)
+task.value #=> 2013-11-07 18:06:55 -0500
+ + +

Controlling execution from within the block

+

+ +
timer_task = Concurrent::TimerTask.new(execution_interval: 1) do |task|
+  task.execution_interval.times{ print 'Boom! ' }
+  print "\n"
+  task.execution_interval += 1
+  if task.execution_interval > 5
+    puts 'Stopping...'
+    task.shutdown
+  end
+end
+
+timer_task.execute # blocking call - this task will stop itself
+#=> Boom!
+#=> Boom! Boom!
+#=> Boom! Boom! Boom!
+#=> Boom! Boom! Boom! Boom!
+#=> Boom! Boom! Boom! Boom! Boom!
+#=> Stopping...
+ + +

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.execute
+sleep 4
+
+#=> (2013-10-13 19:08:58 -0400) Execution successfully returned 42
+#=> (2013-10-13 19:08:59 -0400) Execution successfully returned 42
+#=> (2013-10-13 19:09:00 -0400) Execution successfully returned 42
+task.shutdown
+
+task = Concurrent::TimerTask.new(execution_interval: 1){ sleep }
+task.add_observer(TaskObserver.new)
+task.execute
+
+#=> (2013-10-13 19:07:25 -0400) Execution timed out
+#=> (2013-10-13 19:07:27 -0400) Execution timed out
+#=> (2013-10-13 19:07:29 -0400) Execution timed out
+task.shutdown
+
+task = Concurrent::TimerTask.new(execution_interval: 1){ raise StandardError }
+task.add_observer(TaskObserver.new)
+task.execute
+
+#=> (2013-10-13 19:09:37 -0400) Execution failed with error StandardError
+#=> (2013-10-13 19:09:38 -0400) Execution failed with error StandardError
+#=> (2013-10-13 19:09:39 -0400) Execution failed with error StandardError
+task.shutdown
+ +
+ + +

See Also:

+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
EXECUTION_INTERVAL = +
+
+

Default :execution_interval in seconds.

+ + +
+
+
+ + +
+
+
60
+ +
TIMEOUT_INTERVAL = +
+
+

Default :timeout_interval in seconds.

+ + +
+
+
+ + +
+
+
30
+ +
+ + + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(opts = {}) {|task| ... } ⇒ TimerTask + + + + + +

+
+

Create a new TimerTask with the given task and configuration.

+ + +
+
+
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options defining task execution.

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :execution_interval + (Integer) + + + + + —

    number of seconds between +task executions (default: EXECUTION_INTERVAL)

    +
    + +
  • + +
  • + :run_now + (Boolean) + + + + + —

    Whether to run the task immediately +upon instantiation or to wait until the first # execution_interval +has passed (default: false)

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Dereferenceable#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Dereferenceable#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Dereferenceable#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
+ + +

Yields:

+
    + +
  • + + + + + + + +

    to the block after :execution_interval seconds have passed since +the last yield

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + task + + + + + + + — +

    a reference to the TimerTask instance so that the +block can control its own lifecycle. Necessary since self will +refer to the execution context of the block rather than the running +TimerTask.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + + + + + +

    ArgumentError when no block is given.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+180
+181
+182
+183
+184
+
+
# File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 180
+
+def initialize(opts = {}, &task)
+  raise ArgumentError.new('no block given') unless block_given?
+  super
+  set_deref_options opts
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #execution_intervalFixnum + + + + + +

+
+

Returns Number of seconds after the task completes before the +task is performed again.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    Number of seconds after the task completes before the +task is performed again.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+230
+231
+232
+
+
# File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 230
+
+def execution_interval
+  synchronize { @execution_interval }
+end
+
+
+ + + +
+

+ + #timeout_intervalFixnum + + + + + +

+
+

Returns Number of seconds the task can run before it is +considered to have failed.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Fixnum) + + + + — +

    Number of seconds the task can run before it is +considered to have failed.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+248
+249
+250
+
+
# File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 248
+
+def timeout_interval
+  warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly'
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .execute(opts = {}) {|task| ... } ⇒ TimerTask + + + + + +

+
+

Create and execute a new TimerTask.

+ + +
+
+
+ +
+

Examples:

+ + +
task = Concurrent::TimerTask.execute(execution_interval: 10){ print "Hello World\n" }
+task.running? #=> true
+ +
+

Parameters:

+
    + +
  • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +

    the options defining task execution.

    +
    + +
  • + +
+ + + + +

Options Hash (opts):

+
    + +
  • + :execution_interval + (Integer) + + + + + —

    number of seconds between +task executions (default: EXECUTION_INTERVAL)

    +
    + +
  • + +
  • + :run_now + (Boolean) + + + + + —

    Whether to run the task immediately +upon instantiation or to wait until the first # execution_interval +has passed (default: false)

    +
    + +
  • + +
  • + :dup_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #dup before +returning the data from Concern::Dereferenceable#value

    +
    + +
  • + +
  • + :freeze_on_deref + (Boolean) + + + — default: + false + + + + —

    Call #freeze before +returning the data from Concern::Dereferenceable#value

    +
    + +
  • + +
  • + :copy_on_deref + (Proc) + + + — default: + nil + + + + —

    When calling the Concern::Dereferenceable#value +method, call the given proc passing the internal value as the sole +argument then return the new value returned from the proc.

    +
    + +
  • + +
+ + +

Yields:

+
    + +
  • + + + + + + + +

    to the block after :execution_interval seconds have passed since +the last yield

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + task + + + + + + + — +

    a reference to the TimerTask instance so that the +block can control its own lifecycle. Necessary since self will +refer to the execution context of the block rather than the running +TimerTask.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (TimerTask) + + + + — +

    the new TimerTask

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + + + + + +

    ArgumentError when no block is given.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+223
+224
+225
+
+
# File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 223
+
+def self.execute(opts = {}, &task)
+  TimerTask.new(opts, &task).execute
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #executeTimerTask + + + + + +

+
+

Execute a previously created TimerTask.

+ + +
+
+
+ +
+

Examples:

+ + +

Instance and execute in separate steps

+

+ +
task = Concurrent::TimerTask.new(execution_interval: 10){ print "Hello World\n" }
+task.running? #=> false
+task.execute
+task.running? #=> true
+ + +

Instance and execute in one line

+

+ +
task = Concurrent::TimerTask.new(execution_interval: 10){ print "Hello World\n" }.execute
+task.running? #=> true
+ +
+ +

Returns:

+
    + +
  • + + + (TimerTask) + + + + — +

    a reference to self

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+206
+207
+208
+209
+210
+211
+212
+213
+214
+
+
# File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 206
+
+def execute
+  synchronize do
+    if @running.false?
+      @running.make_true
+      schedule_next_task(@run_now ? 0 : @execution_interval)
+    end
+  end
+  self
+end
+
+
+ +
+

+ + #running?Boolean + + + + + +

+
+

Is the executor running?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true when running, false when shutting down or shutdown

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+189
+190
+191
+
+
# File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 189
+
+def running?
+  @running.true?
+end
+
+
+ +
+

+ + #add_observer(observer = nil, func = :update, &block) ⇒ Object + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Adds an observer to this set. If a block is passed, the observer will be +created by this method and no other params should be passed.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification. +Default is :update

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the added observer

    +
    + +
  • + +
+ +
+
+ +
+

+ + #count_observersInteger + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Return the number of observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the observers count

    +
    + +
  • + +
+ +
+
+ +
+

+ + #delete_observer(observer) ⇒ Object + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Remove observer as an observer on this object so that it will no +longer receive notifications.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + + — +

    the observer to remove

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the deleted observer

    +
    + +
  • + +
+ +
+
+ +
+

+ + #delete_observersObservable + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

Remove all observers associated with this object.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+

+ + #valueObject + + + + Also known as: + deref + + + + + + Originally defined in module + Concern::Dereferenceable + + +

+
+

Return the value this object represents after applying the options specified +by the #set_deref_options method.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of the object

    +
    + +
  • + +
+ +
+
+ +
+

+ + #with_observer(observer = nil, func = :update, &block) ⇒ Observable + + + + + + + Originally defined in module + Concern::Observable + + +

+
+

As #add_observer but can be used for chaining.

+ + +
+
+
+

Parameters:

+
    + +
  • + + observer + + + (Object) + + + (defaults to: nil) + + + — +

    the observer to add

    +
    + +
  • + +
  • + + func + + + (Symbol) + + + (defaults to: :update) + + + — +

    the function to call on the observer during notification.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Observable) + + + + — +

    self

    +
    + +
  • + +
+ +
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Transaction.html b/docs/1.1.10/Concurrent/Transaction.html new file mode 100644 index 000000000..97ba7e86f --- /dev/null +++ b/docs/1.1.10/Concurrent/Transaction.html @@ -0,0 +1,727 @@ + + + + + + + Class: Concurrent::Transaction + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Transaction + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/tvar.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: OpenEntry + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
ABORTED = + +
+
::Object.new
+ +
AbortError = + +
+
Class.new(StandardError)
+ +
LeaveError = + +
+
Class.new(StandardError)
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeTransaction + + + + + +

+
+

Returns a new instance of Transaction.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+161
+162
+163
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 161
+
+def initialize
+  @open_tvars = {}
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .currentundocumented + + + + + +

+ + + + +
+
+
+
+211
+212
+213
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 211
+
+def self.current
+  Thread.current[:current_tvar_transaction]
+end
+
+
+ +
+

+ + .current=(transaction) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+215
+216
+217
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 215
+
+def self.current=(transaction)
+  Thread.current[:current_tvar_transaction] = transaction
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #abortundocumented + + + + + +

+ + + + +
+
+
+
+191
+192
+193
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 191
+
+def abort
+  unlock
+end
+
+
+ +
+

+ + #commitundocumented + + + + + +

+ + + + +
+
+
+
+195
+196
+197
+198
+199
+200
+201
+202
+203
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 195
+
+def commit
+  @open_tvars.each do |tvar, entry|
+    if entry.modified
+      tvar.unsafe_value = entry.value
+    end
+  end
+
+  unlock
+end
+
+
+ +
+

+ + #open(tvar) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 176
+
+def open(tvar)
+  entry = @open_tvars[tvar]
+
+  unless entry
+    unless tvar.unsafe_lock.try_lock
+      Concurrent::abort_transaction
+    end
+
+    entry = OpenEntry.new(tvar.unsafe_value, false)
+    @open_tvars[tvar] = entry
+  end
+
+  entry
+end
+
+
+ +
+

+ + #read(tvar) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+165
+166
+167
+168
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 165
+
+def read(tvar)
+  entry = open(tvar)
+  entry.value
+end
+
+
+ +
+

+ + #unlockundocumented + + + + + +

+ + + + +
+
+
+
+205
+206
+207
+208
+209
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 205
+
+def unlock
+  @open_tvars.each_key do |tvar|
+    tvar.unsafe_lock.unlock
+  end
+end
+
+
+ +
+

+ + #write(tvar, value) ⇒ undocumented + + + + + +

+ + + + +
+
+
+
+170
+171
+172
+173
+174
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 170
+
+def write(tvar, value)
+  entry = open(tvar)
+  entry.modified = true
+  entry.value = value
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Transaction/OpenEntry.html b/docs/1.1.10/Concurrent/Transaction/OpenEntry.html new file mode 100644 index 000000000..7a0ba5c9d --- /dev/null +++ b/docs/1.1.10/Concurrent/Transaction/OpenEntry.html @@ -0,0 +1,313 @@ + + + + + + + Class: Concurrent::Transaction::OpenEntry + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Transaction::OpenEntry + + + +

+
+ +
+
Inherits:
+
+ Struct + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/tvar.rb
+
+ +
+ + + + + +

Instance Attribute Summary collapse

+ + + + + + + +
+

Instance Attribute Details

+ + + +
+

+ + #modifiedObject + + + + + +

+
+

Returns the value of attribute modified

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of modified

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+156
+157
+158
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 156
+
+def modified
+  @modified
+end
+
+
+ + + +
+

+ + #valueObject + + + + + +

+
+

Returns the value of attribute value

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the current value of value

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+156
+157
+158
+
+
# File 'lib/concurrent-ruby/concurrent/tvar.rb', line 156
+
+def value
+  @value
+end
+
+
+ +
+ + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Tuple.html b/docs/1.1.10/Concurrent/Tuple.html new file mode 100644 index 000000000..a4ecfc311 --- /dev/null +++ b/docs/1.1.10/Concurrent/Tuple.html @@ -0,0 +1,818 @@ + + + + + + + Class: Concurrent::Tuple + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::Tuple + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Enumerable
+
+ + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/tuple.rb
+
+ +
+ +

Overview

+
+

A fixed size array with volatile (synchronized, thread safe) getters/setters. +Mixes in Ruby's Enumerable module for enhanced search, sort, and traversal.

+ + +
+
+
+ +
+

Examples:

+ + +
tuple = Concurrent::Tuple.new(16)
+
+tuple.set(0, :foo)                   #=> :foo  | volatile write
+tuple.get(0)                         #=> :foo  | volatile read
+tuple.compare_and_set(0, :foo, :bar) #=> true  | strong CAS
+tuple.cas(0, :foo, :baz)             #=> false | strong CAS
+tuple.get(0)                         #=> :bar  | volatile read
+ +
+ + +

See Also:

+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Constructor Details

+ +
+

+ + #initialize(size) ⇒ Tuple + + + + + +

+
+

Create a new tuple of the given size.

+ + +
+
+
+

Parameters:

+
    + +
  • + + size + + + (Integer) + + + + — +

    the number of elements in the tuple

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
+
# File 'lib/concurrent-ruby/concurrent/tuple.rb', line 33
+
+def initialize(size)
+  @size = size
+  @tuple = tuple = Tuple.new(size)
+  i = 0
+  while i < size
+    tuple[i] = Concurrent::AtomicReference.new
+    i += 1
+  end
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #sizeundocumented (readonly) + + + + + +

+
+

The (fixed) size of the tuple.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+24
+25
+26
+
+
# File 'lib/concurrent-ruby/concurrent/tuple.rb', line 24
+
+def size
+  @size
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #compare_and_set(i, old_value, new_value) ⇒ Boolean + + + + Also known as: + cas + + + + +

+
+

Set the value at the given index to the new value if and only if the current +value matches the given old value.

+ + +
+
+
+

Parameters:

+
    + +
  • + + i + + + (Integer) + + + + — +

    the index for the element to set

    +
    + +
  • + +
  • + + old_value + + + (Object) + + + + — +

    the value to compare against the current value

    +
    + +
  • + +
  • + + new_value + + + (Object) + + + + — +

    the value to set at the given index

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    true if the value at the given element was set else false

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+73
+74
+75
+76
+
+
# File 'lib/concurrent-ruby/concurrent/tuple.rb', line 73
+
+def compare_and_set(i, old_value, new_value)
+  return false if i >= @size || i < 0
+  @tuple[i].compare_and_set(old_value, new_value)
+end
+
+
+ +
+

+ + #each {|ref| ... } ⇒ undocumented + + + + + +

+
+

Calls the given block once for each element in self, passing that element as a parameter.

+ + +
+
+
+ +

Yield Parameters:

+
    + +
  • + + ref + + + (Object) + + + + — +

    the Concurrent::AtomicReference object at the current index

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+82
+83
+84
+
+
# File 'lib/concurrent-ruby/concurrent/tuple.rb', line 82
+
+def each
+  @tuple.each {|ref| yield ref.get}
+end
+
+
+ +
+

+ + #get(i) ⇒ Object + + + + Also known as: + volatile_get + + + + +

+
+

Get the value of the element at the given index.

+ + +
+
+
+

Parameters:

+
    + +
  • + + i + + + (Integer) + + + + — +

    the index from which to retrieve the value

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the value at the given index or nil if the index is out of bounds

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+47
+48
+49
+50
+
+
# File 'lib/concurrent-ruby/concurrent/tuple.rb', line 47
+
+def get(i)
+  return nil if i >= @size || i < 0
+  @tuple[i].get
+end
+
+
+ +
+

+ + #set(i, value) ⇒ Object + + + + Also known as: + volatile_set + + + + +

+
+

Set the element at the given index to the given value

+ + +
+
+
+

Parameters:

+
    + +
  • + + i + + + (Integer) + + + + — +

    the index for the element to set

    +
    + +
  • + +
  • + + value + + + (Object) + + + + — +

    the value to set at the given index

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object) + + + + — +

    the new value of the element at the given index or nil if the index is out of bounds

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+59
+60
+61
+62
+
+
# File 'lib/concurrent-ruby/concurrent/tuple.rb', line 59
+
+def set(i, value)
+  return nil if i >= @size || i < 0
+  @tuple[i].set(value)
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/Utility.html b/docs/1.1.10/Concurrent/Utility.html new file mode 100644 index 000000000..69517f7a6 --- /dev/null +++ b/docs/1.1.10/Concurrent/Utility.html @@ -0,0 +1,116 @@ + + + + + + + Module: Concurrent::Utility + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Concurrent::Utility + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby/concurrent/utility/engine.rb,
+ lib/concurrent-ruby/concurrent/utility/native_integer.rb,
lib/concurrent-ruby/concurrent/utility/processor_counter.rb,
lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb
+
+
+ +
+ + + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/Concurrent/WrappingExecutor.html b/docs/1.1.10/Concurrent/WrappingExecutor.html new file mode 100644 index 000000000..c8f3fa16f --- /dev/null +++ b/docs/1.1.10/Concurrent/WrappingExecutor.html @@ -0,0 +1,649 @@ + + + + + + + Class: Concurrent::WrappingExecutor + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Concurrent::WrappingExecutor + + + +

+
+ +
+
Inherits:
+
+ Synchronization::Object + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb
+
+ +
+ +

Overview

+
+

A delegating executor which modifies each task with arguments +before the task is given to the target executor it delegates to.

+ + +
+
+
+ +
+

Examples:

+ + +

Count task executions

+

+ +
counter          = AtomicFixnum.new
+count_executions = WrappingExecutor.new Concurrent.global_io_executor do |*args, &task|
+  [*args, -> *args { counter.increment; task.call *args }]
+end
+10.times { count_executions.post { :do_something } }
+sleep 0.01
+counter.value #=> 10
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + +
+

Constructor Details

+ +
+

+ + #initialize(executor) {|*args, &task| ... } ⇒ WrappingExecutor + + + + + +

+
+

Returns a new instance of WrappingExecutor.

+ + +
+
+
+

Parameters:

+
    + +
  • + + executor + + + (Executor) + + + + — +

    an executor to delegate the tasks to

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + (*args, &task) + + + + — +

    A function which can modify the task with arguments

    +
    + +
  • + +
+

Yield Parameters:

+
    + +
  • + + *args + + + (Array<Object>) + + + + — +

    the arguments submitted with the tasks

    +
    + +
  • + +
  • + + &task + + + (block) + + + + — +

    the task submitted to the executor to be modified

    +
    + +
  • + +
+

Yield Returns:

+
    + +
  • + + + (Array<Object>) + + + + — +

    a new arguments and task [*args, task] which are submitted to the target executor

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+23
+24
+25
+26
+27
+
+
# File 'lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb', line 23
+
+def initialize(executor, &wrapper)
+  super()
+  @Wrapper  = wrapper
+  @Executor = executor
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #can_overflow?Boolean + + + + + +

+
+

Does the task queue have a maximum size?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if the task queue has a maximum size else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+38
+39
+40
+
+
# File 'lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb', line 38
+
+def can_overflow?
+  @Executor.can_overflow?
+end
+
+
+ +
+

+ + #post(*args) { ... } ⇒ Boolean + + + + + +

+
+

Submit a task to the executor for asynchronous processing.

+ + +
+
+
+

Parameters:

+
    + +
  • + + 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

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+32
+33
+34
+35
+
+
# File 'lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb', line 32
+
+def post(*args, &task)
+  *args, task = @Wrapper.call(*args, &task)
+  @Executor.post(*args, &task)
+end
+
+
+ +
+

+ + #serialized?Boolean + + + + + +

+
+

Does this executor guarantee serialization of its operations?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +

    True if the executor guarantees that all operations +will be post in the order they are received and no two operations may +occur simultaneously. Else false.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+43
+44
+45
+
+
# File 'lib/concurrent-ruby-edge/concurrent/executor/wrapping_executor.rb', line 43
+
+def serialized?
+  @Executor.serialized?
+end
+
+
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/_index.html b/docs/1.1.10/_index.html new file mode 100644 index 000000000..ae8fa0249 --- /dev/null +++ b/docs/1.1.10/_index.html @@ -0,0 +1,1431 @@ + + + + + + + Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Concurrent Ruby

+
+

Alphabetic Index

+ +

File Listing

+ + +
+

Namespace Listing A-Z

+ + + + + + + + +
+ + + + + +
    +
  • B
  • +
      + + + +
    • + Balancer + + (Concurrent::Actor::Utils) + +
    • + +
    • + Base + + (Concurrent::Channel::Buffer) + +
    • + +
    • + Behaviour + + (Concurrent::Actor) + +
    • + +
    • + Broadcast + + (Concurrent::Actor::Utils) + +
    • + +
    • + Buffer + + (Concurrent::Actor::Behaviour) + +
    • + +
    • + Buffer + + (Concurrent::Channel) + +
    • + +
    • + Buffered + + (Concurrent::Channel::Buffer) + +
    • + +
    +
+ + + + + + + + + + + + + + +
    +
  • H
  • +
      + + + +
    • + Hash + + (Concurrent) + +
    • + +
    • + Head + + (Concurrent::Edge::LockFreeLinkedSet) + +
    • + +
    +
+ + +
+ + + + + +
    +
  • J
  • +
      + + + +
    • + Job + + (Concurrent::SerializedExecution) + +
    • + +
    +
+ + + + + + + + +
    +
  • N
  • +
      + + + +
    • + NewChannelIntegration + + (Concurrent::Promises::Future) + +
    • + +
    • + NoActor + + (Concurrent::ErlangActor) + +
    • + +
    • + NoReply + + (Concurrent::ErlangActor) + +
    • + +
    • + Node + + (Concurrent::Edge::LockFreeLinkedSet) + +
    • + +
    • + Node + + (Concurrent::LockFreeQueue) + +
    • + +
    • + Node + + (Concurrent::LockFreeStack) + +
    • + +
    +
+ + +
    +
  • O
  • +
      + + + +
    • + Object + + (Concurrent::Synchronization) + +
    • + +
    • + Obligation + + (Concurrent::Concern) + +
    • + +
    • + Observable + + (Concurrent::Concern) + +
    • + +
    • + OpenEntry + + (Concurrent::Transaction) + +
    • + +
    • + Or + + (Concurrent::ErlangActor::EnvironmentConstants) + +
    • + +
    +
+ + +
    +
  • P
  • +
      + + + +
    • + Pausing + + (Concurrent::Actor::Behaviour) + +
    • + +
    • + Pid + + (Concurrent::ErlangActor) + +
    • + +
    • + Pool + + (Concurrent::Actor::Utils) + +
    • + +
    • + ProcessingActor + + (Concurrent) + +
    • + +
    • + Promise + + (Concurrent) + +
    • + +
    • + Promises + + (Concurrent) + +
    • + +
    • + PublicDelegations + + (Concurrent::Actor) + +
    • + +
    • + PutClause + + (Concurrent::Channel::Selector) + +
    • + +
    +
+ + + + + +
+ + + + + +
    +
  • T
  • +
      + + + +
    • + TVar + + (Concurrent) + +
    • + +
    • + Tail + + (Concurrent::Edge::LockFreeLinkedSet) + +
    • + +
    • + TakeClause + + (Concurrent::Channel::Selector) + +
    • + +
    • + Terminated + + (Concurrent::ErlangActor) + +
    • + +
    • + Termination + + (Concurrent::Actor::Behaviour) + +
    • + +
    • + ThreadLocalVar + + (Concurrent) + +
    • + +
    • + ThreadPoolExecutor + + (Concurrent) + +
    • + +
    • + Throttle + + (Concurrent) + +
    • + +
    • + Tick + + (Concurrent::Channel) + +
    • + +
    • + Ticker + + (Concurrent::Channel::Buffer) + +
    • + +
    • + Timer + + (Concurrent::Channel::Buffer) + +
    • + +
    • + TimerSet + + (Concurrent) + +
    • + +
    • + TimerTask + + (Concurrent) + +
    • + +
    • + Transaction + + (Concurrent) + +
    • + +
    • + Tuple + + (Concurrent) + +
    • + +
    • + TypeCheck + + (Concurrent::Actor) + +
    • + +
    +
+ + +
    +
  • U
  • +
      + + + +
    • + Unbuffered + + (Concurrent::Channel::Buffer) + +
    • + +
    • + UnknownMessage + + (Concurrent::Actor) + +
    • + +
    • + Utility + + (Concurrent) + +
    • + +
    • + Utils + + (Concurrent::Actor) + +
    • + +
    +
+ + + + + +
    +
  • W
  • +
      + + + +
    • + Window + + (Concurrent::Edge::LockFreeLinkedSet) + +
    • + +
    • + WrappingExecutor + + (Concurrent) + +
    • + +
    +
+ + +
    +
  • X
  • + +
+ +
+ +
+ +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/1.1.10/class_list.html b/docs/1.1.10/class_list.html new file mode 100644 index 000000000..7df30bb99 --- /dev/null +++ b/docs/1.1.10/class_list.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + Class List + + + +
+
+

Class List

+ + + +
+ + +
+ + diff --git a/docs/1.1.10/css/common.css b/docs/1.1.10/css/common.css new file mode 100644 index 000000000..f7f7f98b8 --- /dev/null +++ b/docs/1.1.10/css/common.css @@ -0,0 +1,135 @@ +/* Override this file with custom rules */ + +body { + line-height: 18px; +} + +.docstring h1:before { + content: '# '; + color: silver; +} + +.docstring h2:before { + content: '## '; + color: silver; +} + +.docstring code, .docstring .object_link a, #filecontents code { + padding: 0px 3px 1px 3px; + border: 1px solid #eef; + background: #f5f5ff; +} + +#filecontents pre code, .docstring pre code { + border: none; + background: none; + padding: 0; +} + +#filecontents pre.code, .docstring pre.code, .tags pre.example, .docstring code, .docstring .object_link a, +#filecontents code { + -moz-border-radius: 2px; + -webkit-border-radius: 2px; +} + +/* syntax highlighting */ +.source_code { + display: none; + padding: 3px 8px; + border-left: 8px solid #ddd; + margin-top: 5px; +} + +#filecontents pre.code, .docstring pre.code, .source_code pre { + font-family: monospace; +} + +#filecontents pre.code, .docstring pre.code { + display: block; +} + +.source_code .lines { + padding-right: 12px; + color: #555; + text-align: right; +} + +#filecontents pre.code, .docstring pre.code, +.tags pre.example { + padding: 5px 12px; + margin-top: 4px; + border: 1px solid #eef; + background: #f5f5ff; +} + +pre.code { + color: #000; +} + +pre.code .info.file { + color: #555; +} + +pre.code .val { + color: #036A07; +} + +pre.code .tstring_content, +pre.code .heredoc_beg, pre.code .heredoc_end, +pre.code .qwords_beg, pre.code .qwords_end, +pre.code .tstring, pre.code .dstring { + color: #036A07; +} + +pre.code .fid, +pre.code .rubyid_new, +pre.code .rubyid_to_s, +pre.code .rubyid_to_sym, +pre.code .rubyid_to_f, +pre.code .rubyid_to_i, +pre.code .rubyid_each { + color: inherit; +} + +pre.code .comment { + color: #777; + font-style: italic; +} + +pre.code .const, pre.code .constant { + color: inherit; + font-weight: bold; + font-style: italic; +} + +pre.code .label, +pre.code .symbol { + color: #C5060B; +} + +pre.code .kw, +pre.code .rubyid_require, +pre.code .rubyid_extend, +pre.code .rubyid_include, +pre.code .int { + color: #0000FF; +} + +pre.code .ivar { + color: #660E7A; +} + +pre.code .gvar, +pre.code .rubyid_backref, +pre.code .rubyid_nth_ref { + color: #6D79DE; +} + +pre.code .regexp, .dregexp { + color: #036A07; +} + +pre.code a { + border-bottom: 1px dotted #bbf; +} + diff --git a/docs/1.1.10/css/full_list.css b/docs/1.1.10/css/full_list.css new file mode 100644 index 000000000..fa3598242 --- /dev/null +++ b/docs/1.1.10/css/full_list.css @@ -0,0 +1,58 @@ +body { + margin: 0; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + height: 101%; + overflow-x: hidden; + background: #fafafa; +} + +h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } +.clear { clear: both; } +.fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } +#search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } +#content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } +#full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } +#full_list ul { padding: 0; } +#full_list li { padding: 0; margin: 0; list-style: none; } +#full_list li .item { padding: 5px 5px 5px 12px; } +#noresults { padding: 7px 12px; background: #fff; } +#content.insearch #noresults { margin-left: 7px; } +li.collapsed ul { display: none; } +li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } +li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } +li { color: #888; cursor: pointer; } +li.deprecated { text-decoration: line-through; font-style: italic; } +li.odd { background: #f0f0f0; } +li.even { background: #fafafa; } +.item:hover { background: #ddd; } +li small:before { content: "("; } +li small:after { content: ")"; } +li small.search_info { display: none; } +a, a:visited { text-decoration: none; color: #05a; } +li.clicked > .item { background: #05a; color: #ccc; } +li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } +li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } +li.collapsed.clicked a.toggle { background-position: top right; } +#search input { border: 1px solid #bbb; border-radius: 3px; } +#full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } +#full_list_nav a, #nav a:visited { color: #358; } +#full_list_nav a:hover { background: transparent; color: #5af; } +#full_list_nav span:after { content: ' | '; } +#full_list_nav span:last-child:after { content: ''; } + +#content h1 { margin-top: 0; } +li { white-space: nowrap; cursor: normal; } +li small { display: block; font-size: 0.8em; } +li small:before { content: ""; } +li small:after { content: ""; } +li small.search_info { display: none; } +#search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } +#content.insearch #search { background-position: center right; } +#search input { width: 110px; } + +#full_list.insearch ul { display: block; } +#full_list.insearch .item { display: none; } +#full_list.insearch .found { display: block; padding-left: 11px !important; } +#full_list.insearch li a.toggle { display: none; } +#full_list.insearch li small.search_info { display: block; } diff --git a/docs/1.1.10/css/style.css b/docs/1.1.10/css/style.css new file mode 100644 index 000000000..eb0dbc86f --- /dev/null +++ b/docs/1.1.10/css/style.css @@ -0,0 +1,497 @@ +html { + width: 100%; + height: 100%; +} +body { + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + width: 100%; + margin: 0; + padding: 0; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; +} + +#nav { + position: relative; + width: 100%; + height: 100%; + border: 0; + border-right: 1px dotted #eee; + overflow: auto; +} +.nav_wrap { + margin: 0; + padding: 0; + width: 20%; + height: 100%; + position: relative; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; + flex-shrink: 0; + -webkit-flex-shrink: 0; + -ms-flex: 1 0; +} +#resizer { + position: absolute; + right: -5px; + top: 0; + width: 10px; + height: 100%; + cursor: col-resize; + z-index: 9999; +} +#main { + flex: 5 1; + -webkit-flex: 5 1; + -ms-flex: 5 1; + outline: none; + position: relative; + background: #fff; + padding: 1.2em; + padding-top: 0.2em; + box-sizing: border-box; +} + +@media (max-width: 920px) { + .nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; } + #resizer { display: none; } + #nav { + z-index: 9999; + background: #fff; + display: none; + position: absolute; + top: 40px; + right: 12px; + width: 500px; + max-width: 80%; + height: 80%; + overflow-y: scroll; + border: 1px solid #999; + border-collapse: collapse; + box-shadow: -7px 5px 25px #aaa; + border-radius: 2px; + } +} + +@media (min-width: 920px) { + body { height: 100%; overflow: hidden; } + #main { height: 100%; overflow: auto; } + #search { display: none; } +} + +#main img { max-width: 100%; } +h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } +h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } +h1.title { margin-bottom: 10px; } +h1.alphaindex { margin-top: 0; font-size: 22px; } +h2 { + padding: 0; + padding-bottom: 3px; + border-bottom: 1px #aaa solid; + font-size: 1.4em; + margin: 1.8em 0 0.5em; + position: relative; +} +h2 small { font-weight: normal; font-size: 0.7em; display: inline; position: absolute; right: 0; } +h2 small a { + display: block; + height: 20px; + border: 1px solid #aaa; + border-bottom: 0; + border-top-left-radius: 5px; + background: #f8f8f8; + position: relative; + padding: 2px 7px; +} +.clear { clear: both; } +.inline { display: inline; } +.inline p:first-child { display: inline; } +.docstring, .tags, #filecontents { font-size: 15px; line-height: 1.5145em; } +.docstring p > code, .docstring p > tt, .tags p > code, .tags p > tt { + color: #c7254e; background: #f9f2f4; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } +.docstring h1 { font-size: 1.2em; } +.docstring h2 { font-size: 1.1em; } +.docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } +.summary_desc .object_link a, .docstring .object_link a { + font-family: monospace; font-size: 1.05em; + color: #05a; background: #EDF4FA; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.rdoc-term { padding-right: 25px; font-weight: bold; } +.rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } +.summary_desc pre.code .object_link a, .docstring pre.code .object_link a { + padding: 0px; background: inherit; color: inherit; border-radius: inherit; +} + +/* style for */ +#filecontents table, .docstring table { border-collapse: collapse; } +#filecontents table th, #filecontents table td, +.docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; } +#filecontents table tr:nth-child(odd), +.docstring table tr:nth-child(odd) { background: #eee; } +#filecontents table tr:nth-child(even), +.docstring table tr:nth-child(even) { background: #fff; } +#filecontents table th, .docstring table th { background: #fff; } + +/* style for
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/docs/1.1.10/method_list.html b/docs/1.1.10/method_list.html new file mode 100644 index 000000000..6be04a203 --- /dev/null +++ b/docs/1.1.10/method_list.html @@ -0,0 +1,7283 @@ + + + + + + + + + + + + + + + + + + Method List + + + +
+
+

Method List

+ + + +
+ +
    + + +
  • +
    + #<< + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + << + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #<< + Concurrent::Edge::LockFreeLinkedSet +
    +
  • + + +
  • +
    + #<< + Concurrent::ImmediateExecutor +
    +
  • + + +
  • +
    + #<< + Concurrent::Agent +
    +
  • + + +
  • +
    + #<< + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #<< + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #<=> + Concurrent::Edge::LockFreeLinkedSet::Node +
    +
  • + + +
  • +
    + #<=> + Concurrent::Channel::Tick +
    +
  • + + +
  • +
    + #<=> + Concurrent::Edge::LockFreeLinkedSet::Head +
    +
  • + + +
  • +
    + #<=> + Concurrent::Maybe +
    +
  • + + +
  • +
    + #<=> + Concurrent::Edge::LockFreeLinkedSet::Tail +
    +
  • + + +
  • +
    + #== + Concurrent::ErlangActor::Down +
    +
  • + + +
  • +
    + #== + Concurrent::ErlangActor::Terminated +
    +
  • + + +
  • +
    + #== + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #== + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #== + Concurrent::ErlangActor::NoActor +
    +
  • + + +
  • +
    + #== + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + #== + Concurrent::Actor::Reference +
    +
  • + + +
  • +
    + #=== + Concurrent::ErlangActor::EnvironmentConstants::And +
    +
  • + + +
  • +
    + #=== + Concurrent::ErlangActor::EnvironmentConstants::Or +
    +
  • + + +
  • +
    + #Child! + Concurrent::Actor::TypeCheck +
    +
  • + + +
  • +
    + #Child? + Concurrent::Actor::TypeCheck +
    +
  • + + +
  • +
    + #Match! + Concurrent::Actor::TypeCheck +
    +
  • + + +
  • +
    + #Match? + Concurrent::Actor::TypeCheck +
    +
  • + + +
  • +
    + #Type! + Concurrent::Actor::TypeCheck +
    +
  • + + +
  • +
    + #Type? + Concurrent::Actor::TypeCheck +
    +
  • + + +
  • +
    + #[] + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #[] + Concurrent::LazyRegister +
    +
  • + + +
  • +
    + #[] + Concurrent::Map +
    +
  • + + +
  • +
    + #[] + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #[] + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + [] + Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher +
    +
  • + + +
  • +
    + #[]= + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #[]= + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #[]= + Concurrent::Map +
    +
  • + + +
  • +
    + #abort + Concurrent::Transaction +
    +
  • + + +
  • +
    + abort_transaction + Concurrent +
    +
  • + + +
  • +
    + #acquire + Concurrent::Semaphore +
    +
  • + + +
  • +
    + #acquire + Concurrent::Throttle +
    +
  • + + +
  • +
    + #acquire_read_lock + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #acquire_read_lock + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + #acquire_write_lock + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #acquire_write_lock + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + act + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + act_listening + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #actor_class + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #add + Concurrent::Edge::LockFreeLinkedSet +
    +
  • + + +
  • +
    + #add_child + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #add_observer + Concurrent::IVar +
    +
  • + + +
  • +
    + #add_observer + Concurrent::Collection::CopyOnNotifyObserverSet +
    +
  • + + +
  • +
    + #add_observer + Concurrent::Concern::Observable +
    +
  • + + +
  • +
    + #add_observer + Concurrent::Collection::CopyOnWriteObserverSet +
    +
  • + + +
  • +
    + #address + Concurrent::Actor::Envelope +
    +
  • + + +
  • +
    + #address_path + Concurrent::Actor::Envelope +
    +
  • + + +
  • +
    + all? + Concurrent::Promise +
    +
  • + + +
  • +
    + #allocate_context + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #any + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #any + Concurrent::Promises::Event +
    +
  • + + +
  • +
    + any? + Concurrent::Promise +
    +
  • + + +
  • +
    + #any_event + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #any_event_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #any_fulfilled_future + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #any_fulfilled_future_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #any_resolved_future + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #any_resolved_future_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #args + Concurrent::SerializedExecution::Job +
    +
  • + + +
  • +
    + #ask + Concurrent::ErlangActor::Pid +
    +
  • + + +
  • +
    + #ask + Concurrent::Actor::Reference +
    +
  • + + +
  • +
    + #ask + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #ask! + Concurrent::Actor::Reference +
    +
  • + + +
  • +
    + #ask_op + Concurrent::ErlangActor::Pid +
    +
  • + + +
  • +
    + #ask_op + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #async + Concurrent::Async +
    +
  • + + +
  • +
    + atomic_attribute? + Concurrent::Synchronization::Object +
    +
  • + + +
  • +
    + atomic_attributes + Concurrent::Synchronization::Object +
    +
  • + + +
  • +
    + atomic_resolution + Concurrent::Promises::Resolvable +
    +
  • + + +
  • +
    + atomically + Concurrent +
    +
  • + + +
  • +
    + attr_atomic + Concurrent::Synchronization::Object +
    +
  • + + +
  • +
    + #attr_volatile + Concurrent::Synchronization::TruffleRubyAttrVolatile::ClassMethods +
    +
  • + + +
  • +
    + #attr_volatile + Concurrent::Synchronization::JRubyAttrVolatile::ClassMethods +
    +
  • + + +
  • +
    + #attr_volatile + Concurrent::Synchronization::RbxAttrVolatile::ClassMethods +
    +
  • + + +
  • +
    + attr_volatile + Concurrent::Synchronization::Object +
    +
  • + + +
  • +
    + #attr_volatile + Concurrent::Synchronization::MriAttrVolatile::ClassMethods +
    +
  • + + +
  • +
    + #auto_terminate= + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #auto_terminate= + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #auto_terminate? + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #auto_terminate? + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #available_capacity + Concurrent::Throttle +
    +
  • + + +
  • +
    + #available_permits + Concurrent::Semaphore +
    +
  • + + +
  • +
    + #await + Concurrent::Agent +
    +
  • + + +
  • +
    + await + Concurrent::Agent +
    +
  • + + +
  • +
    + #await + Concurrent::Async +
    +
  • + + +
  • +
    + await_for + Concurrent::Agent +
    +
  • + + +
  • +
    + #await_for + Concurrent::Agent +
    +
  • + + +
  • +
    + #await_for! + Concurrent::Agent +
    +
  • + + +
  • +
    + await_for! + Concurrent::Agent +
    +
  • + + +
  • +
    + base + Concurrent::Actor::Behaviour +
    +
  • + + +
  • +
    + basic_behaviour_definition + Concurrent::Actor::Behaviour +
    +
  • + + +
  • +
    + #behaviour + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #behaviour + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #behaviour! + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #behaviour! + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #behaviour_definition + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #behaviour_definition + Concurrent::Actor::RestartingContext +
    +
  • + + +
  • +
    + #behaviour_definition + Concurrent::Actor::Root +
    +
  • + + +
  • +
    + #behaviour_definition + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #behaviour_definition + Concurrent::Actor::Context +
    +
  • + + +
  • +
    + #bind + Concurrent::ThreadLocalVar +
    +
  • + + +
  • +
    + #block + Concurrent::SerializedExecution::Job +
    +
  • + + +
  • +
    + #blocking? + Concurrent::Channel::Buffer::Dropping +
    +
  • + + +
  • +
    + #blocking? + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #blocking? + Concurrent::Channel::Buffer::Sliding +
    +
  • + + +
  • +
    + #borrow + Concurrent::MVar +
    +
  • + + +
  • +
    + #broadcast + Concurrent::Synchronization +
    +
  • + + +
  • +
    + #broadcast + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #broadcast + Concurrent::Actor::Behaviour::Abstract +
    +
  • + + +
  • +
    + #broken? + Concurrent::CyclicBarrier +
    +
  • + + +
  • +
    + #build_context + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #call + Concurrent::SerializedExecution::Job +
    +
  • + + +
  • +
    + call_dataflow + Concurrent +
    +
  • + + +
  • +
    + #can_overflow? + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #can_overflow? + Concurrent::WrappingExecutor +
    +
  • + + +
  • +
    + #can_overflow? + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #cancel + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #cancel + Concurrent::Future +
    +
  • + + +
  • +
    + #canceled? + Concurrent::Cancellation +
    +
  • + + +
  • +
    + #cancelled? + Concurrent::Future +
    +
  • + + +
  • +
    + #cancelled? + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #capacity + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #capacity + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #chain + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #chain_on + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #chain_resolvable + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #check! + Concurrent::Cancellation +
    +
  • + + +
  • +
    + #children + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #children + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #clear + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #clear_each + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #clear_if + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #close + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #closed? + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #commit + Concurrent::Transaction +
    +
  • + + +
  • +
    + #compare_and_clear + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #compare_and_pop + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #compare_and_push + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #compare_and_set + Concurrent::Atom +
    +
  • + + +
  • +
    + #compare_and_set + Concurrent::Tuple +
    +
  • + + +
  • +
    + #compare_and_set + Concurrent::AtomicFixnum +
    +
  • + + +
  • +
    + #compare_and_set + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + #compare_and_set + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #compare_and_set_successor + Concurrent::LockFreeQueue::Node +
    +
  • + + +
  • +
    + #complete? + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #completed_task_count + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #compute + Concurrent::Map +
    +
  • + + +
  • +
    + #compute_if_absent + Concurrent::Map +
    +
  • + + +
  • +
    + #compute_if_present + Concurrent::Map +
    +
  • + + +
  • +
    + #contains? + Concurrent::Edge::LockFreeLinkedSet +
    +
  • + + +
  • +
    + #context + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #context + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #context_class + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #context_class + Concurrent::Actor::PublicDelegations +
    +
  • + + +
  • +
    + #core + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #core + Concurrent::Actor::Behaviour::Abstract +
    +
  • + + +
  • +
    + #count + Concurrent::CountDownLatch +
    +
  • + + +
  • +
    + #count_down + Concurrent::CountDownLatch +
    +
  • + + +
  • +
    + #count_observers + Concurrent::Collection::CopyOnNotifyObserverSet +
    +
  • + + +
  • +
    + #count_observers + Concurrent::Concern::Observable +
    +
  • + + +
  • +
    + #count_observers + Concurrent::Collection::CopyOnWriteObserverSet +
    +
  • + + +
  • +
    + create_simple_logger + Concurrent +
    +
  • + + +
  • +
    + create_stdlib_logger + Concurrent +
    +
  • + + +
  • +
    + #curr + Concurrent::Edge::LockFreeLinkedSet::Window +
    +
  • + + +
  • +
    + current + Concurrent::Transaction +
    +
  • + + +
  • +
    + current + Concurrent::Actor +
    +
  • + + +
  • +
    + current= + Concurrent::Transaction +
    +
  • + + +
  • +
    + #data + Concurrent::Edge::LockFreeLinkedSet::Node +
    +
  • + + +
  • +
    + dataflow + Concurrent +
    +
  • + + +
  • +
    + dataflow! + Concurrent +
    +
  • + + +
  • +
    + dataflow_with + Concurrent +
    +
  • + + +
  • +
    + dataflow_with! + Concurrent +
    +
  • + + +
  • +
    + #dead_letter_routing + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #dead_letter_routing + Concurrent::Actor::Reference +
    +
  • + + +
  • +
    + #dead_letter_routing + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #dead_letter_routing + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #dead_letter_routing + Concurrent::Actor::Root +
    +
  • + + +
  • +
    + #decrement + Concurrent::AtomicFixnum +
    +
  • + + +
  • +
    + #default_actor_executor + Concurrent::ErlangActor::Functions +
    +
  • + + +
  • +
    + #default_executor + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #default_executor + Concurrent::Promises::FactoryMethods::Configuration +
    +
  • + + +
  • +
    + #default_executor + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #default_executor + Concurrent::ErlangActor::Functions +
    +
  • + + +
  • +
    + #default_executor + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #default_executor + Concurrent::Throttle +
    +
  • + + +
  • +
    + #default_reference_class + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #delay + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #delay + Concurrent::Promises::Event +
    +
  • + + +
  • +
    + #delay + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #delay_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #delete + Concurrent::Map +
    +
  • + + +
  • +
    + #delete_observer + Concurrent::Collection::CopyOnNotifyObserverSet +
    +
  • + + +
  • +
    + #delete_observer + Concurrent::Concern::Observable +
    +
  • + + +
  • +
    + #delete_observer + Concurrent::Collection::CopyOnWriteObserverSet +
    +
  • + + +
  • +
    + #delete_observers + Concurrent::Collection::CopyOnWriteObserverSet +
    +
  • + + +
  • +
    + #delete_observers + Concurrent::Concern::Observable +
    +
  • + + +
  • +
    + #delete_observers + Concurrent::Collection::CopyOnNotifyObserverSet +
    +
  • + + +
  • +
    + #delete_pair + Concurrent::Map +
    +
  • + + +
  • +
    + #demonitor + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + disable_at_exit_handlers! + Concurrent +
    +
  • + + +
  • +
    + #distribute + Concurrent::Actor::Utils::Balancer +
    +
  • + + +
  • +
    + #drain_permits + Concurrent::Semaphore +
    +
  • + + +
  • +
    + #each + Concurrent::Channel +
    +
  • + + +
  • +
    + #each + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #each + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + #each + Concurrent::Edge::LockFreeLinkedSet +
    +
  • + + +
  • +
    + #each + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #each + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #each + Concurrent::Tuple +
    +
  • + + +
  • +
    + #each_key + Concurrent::Map +
    +
  • + + +
  • +
    + #each_pair + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #each_pair + Concurrent::Map +
    +
  • + + +
  • +
    + #each_pair + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #each_pair + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + #each_value + Concurrent::Map +
    +
  • + + +
  • +
    + #empty? + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #empty? + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #empty? + Concurrent::Map +
    +
  • + + +
  • +
    + #empty? + Concurrent::MVar +
    +
  • + + +
  • +
    + #empty? + Concurrent::Channel::Buffer::Unbuffered +
    +
  • + + +
  • +
    + ensure_safe_initialization_when_final_fields_are_present + Concurrent::Synchronization::Object +
    +
  • + + +
  • +
    + #envelope + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #envelope + Concurrent::Actor::UnknownMessage +
    +
  • + + +
  • +
    + #epoch + Concurrent::Channel::Tick +
    +
  • + + +
  • +
    + #error + Concurrent::Agent +
    +
  • + + +
  • +
    + #error_mode + Concurrent::Agent +
    +
  • + + +
  • +
    + #error_strategy + Concurrent::Actor::Behaviour::SetResults +
    +
  • + + +
  • +
    + #errors + Concurrent::MultipleErrors +
    +
  • + + +
  • +
    + #evaluate_to + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #evaluate_to! + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #exception + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #exception + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #exchange + Concurrent +
    +
  • + + +
  • +
    + #exchange! + Concurrent +
    +
  • + + +
  • +
    + execute + Concurrent::Promise +
    +
  • + + +
  • +
    + execute + Concurrent::Future +
    +
  • + + +
  • +
    + #execute + Concurrent::Future +
    +
  • + + +
  • +
    + #execute + Concurrent::Promise +
    +
  • + + +
  • +
    + #execute + Concurrent::Channel::Selector::AfterClause +
    +
  • + + +
  • +
    + execute + Concurrent::TimerTask +
    +
  • + + +
  • +
    + #execute + Concurrent::TimerTask +
    +
  • + + +
  • +
    + #execute + Concurrent::Channel::Selector::DefaultClause +
    +
  • + + +
  • +
    + #execute + Concurrent::Channel::Selector::ErrorClause +
    +
  • + + +
  • +
    + #execute + Concurrent::SafeTaskExecutor +
    +
  • + + +
  • +
    + execute + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #execute + Concurrent::Channel::Selector::PutClause +
    +
  • + + +
  • +
    + #execute + Concurrent::Channel::Selector::TakeClause +
    +
  • + + +
  • +
    + #execute + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #execution_interval + Concurrent::TimerTask +
    +
  • + + +
  • +
    + #executor + Concurrent::Actor::PublicDelegations +
    +
  • + + +
  • +
    + executor + Concurrent +
    +
  • + + +
  • +
    + #executor + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #executor + Concurrent::SerializedExecution::Job +
    +
  • + + +
  • +
    + #fail + Concurrent::IVar +
    +
  • + + +
  • +
    + #fail + Concurrent::Promise +
    +
  • + + +
  • +
    + #failed? + Concurrent::Agent +
    +
  • + + +
  • +
    + #fallback_policy + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #fallback_policy + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #false? + Concurrent::AtomicBoolean +
    +
  • + + +
  • +
    + #fetch + Concurrent::Map +
    +
  • + + +
  • +
    + #fetch_or_store + Concurrent::Map +
    +
  • + + +
  • +
    + #filtered_receivers + Concurrent::Actor::Utils::Broadcast +
    +
  • + + +
  • +
    + find + Concurrent::Edge::LockFreeLinkedSet::Window +
    +
  • + + +
  • +
    + #flat_event + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #flat_future + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #flat_map + Concurrent::Promise +
    +
  • + + +
  • +
    + #from + Concurrent::ErlangActor::Down +
    +
  • + + +
  • +
    + #from + Concurrent::ErlangActor::Terminated +
    +
  • + + +
  • +
    + from + Concurrent::Maybe +
    +
  • + + +
  • +
    + #fulfill + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + fulfill + Concurrent::Promise +
    +
  • + + +
  • +
    + #fulfilled? + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #fulfilled? + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #fulfilled_future + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #full? + Concurrent::Channel::Buffer::Sliding +
    +
  • + + +
  • +
    + #full? + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #full? + Concurrent::MVar +
    +
  • + + +
  • +
    + #full? + Concurrent::Channel::Buffer::Dropping +
    +
  • + + +
  • +
    + #full? + Concurrent::Channel::Buffer::Unbuffered +
    +
  • + + +
  • +
    + #future + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #future + Concurrent::Actor::Envelope +
    +
  • + + +
  • +
    + #future_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #get + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + #get + Concurrent::ThreadSafe::Util::XorShiftRandom +
    +
  • + + +
  • +
    + #get + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #get + Concurrent::Tuple +
    +
  • + + +
  • +
    + #get_and_set + Concurrent::Map +
    +
  • + + +
  • +
    + #get_and_set + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + global_fast_executor + Concurrent +
    +
  • + + +
  • +
    + global_immediate_executor + Concurrent +
    +
  • + + +
  • +
    + global_io_executor + Concurrent +
    +
  • + + +
  • +
    + global_logger + Concurrent +
    +
  • + + +
  • +
    + global_logger= + Concurrent +
    +
  • + + +
  • +
    + global_timer_set + Concurrent +
    +
  • + + +
  • +
    + go + Concurrent::Channel +
    +
  • + + +
  • +
    + go_loop + Concurrent::Channel +
    +
  • + + +
  • +
    + go_loop_via + Concurrent::Channel +
    +
  • + + +
  • +
    + go_via + Concurrent::Channel +
    +
  • + + +
  • +
    + #guard! + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #has_waiters? + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + #hash + Concurrent::ErlangActor::Down +
    +
  • + + +
  • +
    + #hash + Concurrent::ErlangActor::Terminated +
    +
  • + + +
  • +
    + #hash + Concurrent::ErlangActor::NoActor +
    +
  • + + +
  • +
    + #idletime + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #incomplete? + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #increment + Concurrent::AtomicFixnum +
    +
  • + + +
  • +
    + #info + Concurrent::ErlangActor::Down +
    +
  • + + +
  • +
    + #initial_delay + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #initialize + Concurrent::ThreadLocalVar +
    +
  • + + +
  • +
    + #initialize + Concurrent::WrappingExecutor +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Behaviour::Supervising +
    +
  • + + +
  • +
    + #initialize + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #initialize + Concurrent::Edge::LockFreeLinkedSet +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Behaviour::Termination +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel::Selector::PutClause +
    +
  • + + +
  • +
    + #initialize + Concurrent::TimerSet +
    +
  • + + +
  • +
    + #initialize + Concurrent::AtomicFixnum +
    +
  • + + +
  • +
    + #initialize + Concurrent::AtomicBoolean +
    +
  • + + +
  • +
    + #initialize + Concurrent::CyclicBarrier +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Behaviour::Abstract +
    +
  • + + +
  • +
    + #initialize + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + #initialize + Concurrent::Synchronization::Object +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Behaviour::SetResults +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel::Selector::TakeClause +
    +
  • + + +
  • +
    + #initialize + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + #initialize + Concurrent::CountDownLatch +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel::Selector::AfterClause +
    +
  • + + +
  • +
    + #initialize + Concurrent::Semaphore +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Behaviour::Pausing +
    +
  • + + +
  • +
    + #initialize + Concurrent::Event +
    +
  • + + +
  • +
    + #initialize + Concurrent::LockFreeStack::Node +
    +
  • + + +
  • +
    + #initialize + Concurrent::FixedThreadPool +
    +
  • + + +
  • +
    + #initialize + Concurrent::CachedThreadPool +
    +
  • + + +
  • +
    + #initialize + Concurrent::ImmediateExecutor +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Behaviour::Linking +
    +
  • + + +
  • +
    + #initialize + Concurrent::SafeTaskExecutor +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel::Selector::ErrorClause +
    +
  • + + +
  • +
    + #initialize + Concurrent::SerializedExecution +
    +
  • + + +
  • +
    + #initialize + Concurrent::TimerTask +
    +
  • + + +
  • +
    + #initialize + Concurrent +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Behaviour::Buffer +
    +
  • + + +
  • +
    + #initialize + Concurrent::Edge::LockFreeLinkedSet::Node +
    +
  • + + +
  • +
    + #initialize + Concurrent::Edge::LockFreeLinkedSet::Tail +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Utils::Broadcast +
    +
  • + + +
  • +
    + #initialize + Concurrent::LockFreeQueue::Node +
    +
  • + + +
  • +
    + #initialize + Concurrent::Synchronization +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel::Selector::DefaultClause +
    +
  • + + +
  • +
    + #initialize + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Utils::Balancer +
    +
  • + + +
  • +
    + #initialize + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #initialize + Concurrent::Edge::LockFreeLinkedSet::Window +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Utils::AsAdHoc +
    +
  • + + +
  • +
    + #initialize + Concurrent::IndirectImmediateExecutor +
    +
  • + + +
  • +
    + #initialize + Concurrent::Collection::CopyOnWriteObserverSet +
    +
  • + + +
  • +
    + #initialize + Concurrent::Promise +
    +
  • + + +
  • +
    + #initialize + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #initialize + Concurrent::Collection::CopyOnNotifyObserverSet +
    +
  • + + +
  • +
    + #initialize + Concurrent::Future +
    +
  • + + +
  • +
    + #initialize + Concurrent::MultipleErrors +
    +
  • + + +
  • +
    + #initialize + Concurrent::SerializedExecutionDelegator +
    +
  • + + +
  • +
    + #initialize + Concurrent::MultipleAssignmentError +
    +
  • + + +
  • +
    + #initialize + Concurrent::ErlangActor::NoActor +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel::ValidationError +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel +
    +
  • + + +
  • +
    + #initialize + Concurrent::Tuple +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #initialize + Concurrent::Delay +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Root +
    +
  • + + +
  • +
    + #initialize + Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::ActorTerminated +
    +
  • + + +
  • +
    + #initialize + Concurrent::Agent +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::UnknownMessage +
    +
  • + + +
  • +
    + #initialize + Concurrent::Channel::Tick +
    +
  • + + +
  • +
    + #initialize + Concurrent::Agent::ValidationError +
    +
  • + + +
  • +
    + #initialize + Concurrent::Agent::Error +
    +
  • + + +
  • +
    + #initialize + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #initialize + Concurrent::Transaction +
    +
  • + + +
  • +
    + #initialize + Concurrent::TVar +
    +
  • + + +
  • +
    + #initialize + Concurrent::Cancellation +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Utils::Pool +
    +
  • + + +
  • +
    + #initialize + Concurrent::MVar +
    +
  • + + +
  • +
    + #initialize + Concurrent::IVar +
    +
  • + + +
  • +
    + #initialize + Concurrent::Atom +
    +
  • + + +
  • +
    + #initialize + Concurrent::Throttle +
    +
  • + + +
  • +
    + #initialize + Concurrent::Map +
    +
  • + + +
  • +
    + #initialize + Concurrent::LazyRegister +
    +
  • + + +
  • +
    + #initialize + Concurrent::Actor::Envelope +
    +
  • + + +
  • +
    + #inspect + Concurrent::MultipleAssignmentError +
    +
  • + + +
  • +
    + #inspect + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + #inspect + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #inspect + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #inspection_data + Concurrent::MultipleAssignmentError +
    +
  • + + +
  • +
    + #internal_state + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #item + Concurrent::LockFreeQueue::Node +
    +
  • + + +
  • +
    + #join + Concurrent::Cancellation +
    +
  • + + +
  • +
    + #just + Concurrent::Maybe +
    +
  • + + +
  • +
    + just + Concurrent::Maybe +
    +
  • + + +
  • +
    + #just? + Concurrent::Maybe +
    +
  • + + +
  • +
    + #key + Concurrent::Edge::LockFreeLinkedSet::Node +
    +
  • + + +
  • +
    + #key + Concurrent::Map +
    +
  • + + +
  • +
    + #key_for + Concurrent::Edge::LockFreeLinkedSet::Node +
    +
  • + + +
  • +
    + #keys + Concurrent::Map +
    +
  • + + +
  • +
    + #kill + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #kill + Concurrent::TimerSet +
    +
  • + + +
  • +
    + #kill + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #kill + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #largest_length + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #last? + Concurrent::Edge::LockFreeLinkedSet::Node +
    +
  • + + +
  • +
    + leave_transaction + Concurrent +
    +
  • + + +
  • +
    + #length + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #link + Concurrent::Actor::Behaviour::Linking +
    +
  • + + +
  • +
    + #link + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + linking + Concurrent::Actor::Behaviour +
    +
  • + + +
  • +
    + locking_order_by + Concurrent::Promises::Resolvable +
    +
  • + + +
  • +
    + #log + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #log + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #mailbox + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #make_false + Concurrent::AtomicBoolean +
    +
  • + + +
  • +
    + #make_future + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #make_true + Concurrent::AtomicBoolean +
    +
  • + + +
  • +
    + #map + Concurrent::Actor::Reference +
    +
  • + + +
  • +
    + #mark + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #max_capacity + Concurrent::Throttle +
    +
  • + + +
  • +
    + #max_length + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #max_queue + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #merge + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #merge + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + #merge + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #merge_pair + Concurrent::Map +
    +
  • + + +
  • +
    + #message + Concurrent::Actor::Envelope +
    +
  • + + +
  • +
    + #message + Concurrent::Actor::Reference +
    +
  • + + +
  • +
    + #min_length + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #modified + Concurrent::Transaction::OpenEntry +
    +
  • + + +
  • +
    + #modify + Concurrent::MVar +
    +
  • + + +
  • +
    + #modify! + Concurrent::MVar +
    +
  • + + +
  • +
    + #monitor + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #monotonic + Concurrent::Channel::Tick +
    +
  • + + +
  • +
    + monotonic_time + Concurrent +
    +
  • + + +
  • +
    + #name + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #name + Concurrent::ErlangActor::Pid +
    +
  • + + +
  • +
    + #name + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #name + Concurrent::Actor::PublicDelegations +
    +
  • + + +
  • +
    + new + Concurrent::Async +
    +
  • + + +
  • +
    + new_fast_executor + Concurrent +
    +
  • + + +
  • +
    + new_io_executor + Concurrent +
    +
  • + + +
  • +
    + #next + Concurrent::Channel +
    +
  • + + +
  • +
    + #next + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #next + Concurrent::Channel::Buffer::Timer +
    +
  • + + +
  • +
    + #next + Concurrent::Channel::Buffer::Unbuffered +
    +
  • + + +
  • +
    + #next + Concurrent::Channel::Buffer::Buffered +
    +
  • + + +
  • +
    + #next? + Concurrent::Channel +
    +
  • + + +
  • +
    + next_node + Node[nil, nil] +
    +
  • + + +
  • +
    + #next_node + Concurrent::Edge::LockFreeLinkedSet::Node +
    +
  • + + +
  • +
    + #next_node + Concurrent::LockFreeStack::Node +
    +
  • + + +
  • +
    + nothing + Concurrent::Maybe +
    +
  • + + +
  • +
    + #nothing + Concurrent::Maybe +
    +
  • + + +
  • +
    + #nothing? + Concurrent::Maybe +
    +
  • + + +
  • +
    + #notify_and_delete_observers + Concurrent::Collection::CopyOnWriteObserverSet +
    +
  • + + +
  • +
    + #notify_and_delete_observers + Concurrent::Collection::CopyOnNotifyObserverSet +
    +
  • + + +
  • +
    + #notify_observers + Concurrent::Collection::CopyOnWriteObserverSet +
    +
  • + + +
  • +
    + #notify_observers + Concurrent::Collection::CopyOnNotifyObserverSet +
    +
  • + + +
  • +
    + #number_waiting + Concurrent::CyclicBarrier +
    +
  • + + +
  • +
    + #offer + Concurrent::Channel::Buffer::Buffered +
    +
  • + + +
  • +
    + #offer + Concurrent::Channel::Buffer::Timer +
    +
  • + + +
  • +
    + #offer + Concurrent::Channel::Buffer::Dropping +
    +
  • + + +
  • +
    + #offer + Concurrent::Channel::Buffer::Unbuffered +
    +
  • + + +
  • +
    + #offer + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #offer + Concurrent::Channel +
    +
  • + + +
  • +
    + #offer + Concurrent::Channel::Buffer::Sliding +
    +
  • + + +
  • +
    + #offer! + Concurrent::Channel +
    +
  • + + +
  • +
    + #offer? + Concurrent::Channel +
    +
  • + + +
  • +
    + #on + Concurrent::Throttle +
    +
  • + + +
  • +
    + #on + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::ExecutesContext +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::Pausing +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::SetResults +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::ErrorsOnUnknownMessage +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::Supervising +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::Abstract +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::Termination +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::Buffer +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::Awaits +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::Linking +
    +
  • + + +
  • +
    + #on_envelope + Concurrent::Actor::Behaviour::RemovesChild +
    +
  • + + +
  • +
    + #on_event + Concurrent::Actor::Behaviour::Abstract +
    +
  • + + +
  • +
    + #on_event + Concurrent::Actor::Behaviour::Pausing +
    +
  • + + +
  • +
    + #on_event + Concurrent::Actor::Behaviour::ExecutesContext +
    +
  • + + +
  • +
    + #on_event + Concurrent::Actor::Behaviour::Buffer +
    +
  • + + +
  • +
    + #on_event + Concurrent::Actor::Behaviour::Linking +
    +
  • + + +
  • +
    + #on_event + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #on_fulfillment + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #on_fulfillment! + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #on_fulfillment_using + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #on_message + Concurrent::Actor::Root +
    +
  • + + +
  • +
    + #on_message + Concurrent::Actor::Utils::Pool +
    +
  • + + +
  • +
    + #on_message + Concurrent::Actor::DefaultDeadLetterHandler +
    +
  • + + +
  • +
    + #on_message + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #on_message + Concurrent::Actor::Utils::AsAdHoc +
    +
  • + + +
  • +
    + #on_message + Concurrent::Actor::Utils::Balancer +
    +
  • + + +
  • +
    + #on_message + Concurrent::Actor::Utils::Broadcast +
    +
  • + + +
  • +
    + #on_rejection + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #on_rejection! + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #on_rejection_using + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #on_resolution + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #on_resolution! + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #on_resolution_using + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #on_success + Concurrent::Promise +
    +
  • + + +
  • +
    + #open + Concurrent::Transaction +
    +
  • + + +
  • +
    + #or + Concurrent::Maybe +
    +
  • + + +
  • +
    + #origin + Concurrent::Cancellation +
    +
  • + + +
  • +
    + #parent + Concurrent::Actor::PublicDelegations +
    +
  • + + +
  • +
    + #parent + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #parties + Concurrent::CyclicBarrier +
    +
  • + + +
  • +
    + #pass + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #pass + Concurrent::Actor::Behaviour::Abstract +
    +
  • + + +
  • +
    + #path + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #path + Concurrent::Actor::PublicDelegations +
    +
  • + + +
  • +
    + #pause! + Concurrent::Actor::Behaviour::Pausing +
    +
  • + + +
  • +
    + #paused? + Concurrent::Actor::Behaviour::Pausing +
    +
  • + + +
  • +
    + #peek + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #peek + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #peek_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #pending? + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #pending? + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + physical_processor_count + Concurrent +
    +
  • + + +
  • +
    + #pid + Concurrent::ErlangActor::NoActor +
    +
  • + + +
  • +
    + #pid + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #poll + Concurrent::Channel::Buffer::Timer +
    +
  • + + +
  • +
    + #poll + Concurrent::Channel +
    +
  • + + +
  • +
    + #poll + Concurrent::Channel::Buffer::Buffered +
    +
  • + + +
  • +
    + #poll + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #poll + Concurrent::Channel::Buffer::Unbuffered +
    +
  • + + +
  • +
    + #poll! + Concurrent::Channel +
    +
  • + + +
  • +
    + #poll? + Concurrent::Channel +
    +
  • + + +
  • +
    + #pop + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #pop + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #pop_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #pop_op + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #pop_op_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #post + Concurrent::WrappingExecutor +
    +
  • + + +
  • +
    + #post + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #post + Concurrent::SerializedExecutionDelegator +
    +
  • + + +
  • +
    + #post + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #post + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #post + Concurrent::SerializedExecution +
    +
  • + + +
  • +
    + post + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #post + Concurrent::IndirectImmediateExecutor +
    +
  • + + +
  • +
    + #post + Concurrent::TimerSet +
    +
  • + + +
  • +
    + #post + Concurrent::ImmediateExecutor +
    +
  • + + +
  • +
    + #posts + Concurrent::SerializedExecution +
    +
  • + + +
  • +
    + #pred + Concurrent::Edge::LockFreeLinkedSet::Window +
    +
  • + + +
  • +
    + #process_envelope + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #process_envelope + Concurrent::Actor::Behaviour::Buffer +
    +
  • + + +
  • +
    + #process_envelopes? + Concurrent::Actor::Behaviour::Buffer +
    +
  • + + +
  • +
    + #processing? + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + processor_count + Concurrent +
    +
  • + + +
  • +
    + #prune_pool + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #push + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #push + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #push_op + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #put + Concurrent::Channel::Buffer::Timer +
    +
  • + + +
  • +
    + #put + Concurrent::Channel::Buffer::Buffered +
    +
  • + + +
  • +
    + #put + Concurrent::Channel::Buffer::Sliding +
    +
  • + + +
  • +
    + #put + Concurrent::Channel +
    +
  • + + +
  • +
    + #put + Concurrent::Channel::Buffer::Unbuffered +
    +
  • + + +
  • +
    + #put + Concurrent::MVar +
    +
  • + + +
  • +
    + #put + Concurrent::Channel::Buffer::Dropping +
    +
  • + + +
  • +
    + #put + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #put! + Concurrent::Channel +
    +
  • + + +
  • +
    + #put? + Concurrent::Channel +
    +
  • + + +
  • +
    + #put_if_absent + Concurrent::Map +
    +
  • + + +
  • +
    + #queue_length + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #read + Concurrent::Transaction +
    +
  • + + +
  • +
    + #reason + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #reason + Concurrent::ErlangActor::Terminated +
    +
  • + + +
  • +
    + #reason + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #reason + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #receive + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #receive + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #reconfigure + Concurrent::Delay +
    +
  • + + +
  • +
    + #redirect + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #reference + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #reference + Concurrent::ErlangActor::Down +
    +
  • + + +
  • +
    + #reference + Concurrent::Actor::PublicDelegations +
    +
  • + + +
  • +
    + #reference + Concurrent::Actor::ActorTerminated +
    +
  • + + +
  • +
    + #register + Concurrent::LazyRegister +
    +
  • + + +
  • +
    + #registered? + Concurrent::LazyRegister +
    +
  • + + +
  • +
    + reject + Concurrent::Promise +
    +
  • + + +
  • +
    + #reject + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #reject! + Concurrent::Actor::Envelope +
    +
  • + + +
  • +
    + #reject_envelope + Concurrent::Actor::Behaviour::Abstract +
    +
  • + + +
  • +
    + #rejected? + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #rejected? + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #rejected_future + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #release + Concurrent::Throttle +
    +
  • + + +
  • +
    + #release + Concurrent::Semaphore +
    +
  • + + +
  • +
    + #release + Concurrent::Promises::Resolvable +
    +
  • + + +
  • +
    + #release_read_lock + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + #release_read_lock + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #release_write_lock + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #release_write_lock + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + #remaining_capacity + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #remove + Concurrent::Edge::LockFreeLinkedSet +
    +
  • + + +
  • +
    + #remove_child + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #replace_if + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #replace_if_exists + Concurrent::Map +
    +
  • + + +
  • +
    + #replace_pair + Concurrent::Map +
    +
  • + + +
  • +
    + #reply + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #reply_resolution + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #reschedule + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #rescue + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #rescue + Concurrent::Promise +
    +
  • + + +
  • +
    + #rescue_on + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #reserve + Concurrent::Promises::Resolvable +
    +
  • + + +
  • +
    + #reset + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #reset + Concurrent::CyclicBarrier +
    +
  • + + +
  • +
    + #reset + Concurrent::Event +
    +
  • + + +
  • +
    + #reset + Concurrent::Atom +
    +
  • + + +
  • +
    + #reset! + Concurrent::Actor::Behaviour::Pausing +
    +
  • + + +
  • +
    + #resolvable_event + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #resolvable_event_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #resolvable_future + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #resolvable_future_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #resolve + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #resolve + Concurrent::Promises::ResolvableEvent +
    +
  • + + +
  • +
    + #resolved? + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #resolved_event + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #resolved_future + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #restart + Concurrent::Agent +
    +
  • + + +
  • +
    + #restart! + Concurrent::Actor::Behaviour::Pausing +
    +
  • + + +
  • +
    + restarting_behaviour_definition + Concurrent::Actor::Behaviour +
    +
  • + + +
  • +
    + #result + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #result + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #resume! + Concurrent::Actor::Behaviour::Pausing +
    +
  • + + +
  • +
    + root + Concurrent::Actor +
    +
  • + + +
  • +
    + #run + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #running? + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #running? + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #running? + Concurrent::ImmediateExecutor +
    +
  • + + +
  • +
    + #running? + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #running? + Concurrent::TimerTask +
    +
  • + + +
  • +
    + safe_initialization! + Concurrent::Synchronization::Object +
    +
  • + + +
  • +
    + safe_initialization? + Concurrent::Synchronization::Object +
    +
  • + + +
  • +
    + #schedule + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #schedule + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #schedule + Concurrent::Promises::Event +
    +
  • + + +
  • +
    + #schedule_execution + Concurrent::Actor::Core +
    +
  • + + +
  • +
    + #schedule_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #schedule_time + Concurrent::ScheduledTask +
    +
  • + + +
  • +
    + #scheduled_task_count + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #select + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #select + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + select + Concurrent::Channel +
    +
  • + + +
  • +
    + select + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #select + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #select + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #select_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + select_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + select_op + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #select_op + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #select_op_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + select_op_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #send + Concurrent::Agent +
    +
  • + + +
  • +
    + #send! + Concurrent::Agent +
    +
  • + + +
  • +
    + #send_off + Concurrent::Agent +
    +
  • + + +
  • +
    + #send_off! + Concurrent::Agent +
    +
  • + + +
  • +
    + #send_via + Concurrent::Agent +
    +
  • + + +
  • +
    + #send_via! + Concurrent::Agent +
    +
  • + + +
  • +
    + #sender + Concurrent::Actor::Envelope +
    +
  • + + +
  • +
    + #sender_path + Concurrent::Actor::Envelope +
    +
  • + + +
  • +
    + #serialized? + Concurrent::WrappingExecutor +
    +
  • + + +
  • +
    + #serialized? + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #serialized? + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #set + Concurrent::Promise +
    +
  • + + +
  • +
    + #set + Concurrent::IVar +
    +
  • + + +
  • +
    + #set + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #set + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + #set + Concurrent::Tuple +
    +
  • + + +
  • +
    + #set + Concurrent::Future +
    +
  • + + +
  • +
    + #set + Concurrent::Event +
    +
  • + + +
  • +
    + #set! + Concurrent::MVar +
    +
  • + + +
  • +
    + #set? + Concurrent::Event +
    +
  • + + +
  • +
    + #shutdown + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #shutdown + Concurrent::ImmediateExecutor +
    +
  • + + +
  • +
    + #shutdown + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #shutdown + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #shutdown? + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #shutdown? + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #shutdown? + Concurrent::ImmediateExecutor +
    +
  • + + +
  • +
    + #shutdown? + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #shuttingdown? + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #shuttingdown? + Concurrent::ImmediateExecutor +
    +
  • + + +
  • +
    + #shuttingdown? + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #shuttingdown? + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #signal + Concurrent::Synchronization +
    +
  • + + +
  • +
    + #size + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #size + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #size + Concurrent::Map +
    +
  • + + +
  • +
    + #size + Concurrent::Channel::Buffer::Unbuffered +
    +
  • + + +
  • +
    + #size + Concurrent::Tuple +
    +
  • + + +
  • +
    + #spawn + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + spawn + Concurrent::Actor +
    +
  • + + +
  • +
    + #spawn + Concurrent::ErlangActor::FunctionShortcuts +
    +
  • + + +
  • +
    + spawn + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + spawn! + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + spawn! + Concurrent::Actor +
    +
  • + + +
  • +
    + #spawn_actor + Concurrent::ErlangActor::Functions +
    +
  • + + +
  • +
    + #state + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #state + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #subsequent + Concurrent::Actor::Behaviour::Abstract +
    +
  • + + +
  • +
    + #successor + Concurrent::LockFreeQueue::Node +
    +
  • + + +
  • +
    + #successor= + Concurrent::LockFreeQueue::Node +
    +
  • + + +
  • +
    + #successor_reference + Concurrent::Edge::LockFreeLinkedSet::Node +
    +
  • + + +
  • +
    + supervised + Concurrent::Actor::Behaviour +
    +
  • + + +
  • +
    + supervising + Concurrent::Actor::Behaviour +
    +
  • + + +
  • +
    + #swap + Concurrent::Atom +
    +
  • + + +
  • +
    + #swap_successor + Concurrent::LockFreeQueue::Node +
    +
  • + + +
  • +
    + #synchronize + Concurrent::Synchronization +
    +
  • + + +
  • +
    + #take + Concurrent::Channel::Buffer::Timer +
    +
  • + + +
  • +
    + #take + Concurrent::Channel::Buffer::Unbuffered +
    +
  • + + +
  • +
    + #take + Concurrent::Channel::Buffer::Base +
    +
  • + + +
  • +
    + #take + Concurrent::MVar +
    +
  • + + +
  • +
    + #take + Concurrent::Channel::Buffer::Buffered +
    +
  • + + +
  • +
    + #take + Concurrent::Channel +
    +
  • + + +
  • +
    + #take! + Concurrent::Channel +
    +
  • + + +
  • +
    + #take? + Concurrent::Channel +
    +
  • + + +
  • +
    + #tell + Concurrent::Actor::AbstractContext +
    +
  • + + +
  • +
    + #tell + Concurrent::Actor::Reference +
    +
  • + + +
  • +
    + #tell + Concurrent::ErlangActor::Pid +
    +
  • + + +
  • +
    + #tell! + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #tell_op + Concurrent::ErlangActor::Pid +
    +
  • + + +
  • +
    + #tell_op + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #terminate + Concurrent::ErlangActor::FunctionShortcuts +
    +
  • + + +
  • +
    + #terminate + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #terminate! + Concurrent::Actor::Behaviour::Termination +
    +
  • + + +
  • +
    + #terminate! + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #terminate_actor + Concurrent::ErlangActor::Functions +
    +
  • + + +
  • +
    + #terminated + Concurrent::Actor::Behaviour::Termination +
    +
  • + + +
  • +
    + #terminated + Concurrent::ErlangActor::Pid +
    +
  • + + +
  • +
    + #terminated + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #terminated? + Concurrent::Actor::Behaviour::Termination +
    +
  • + + +
  • +
    + #terminated? + Concurrent::Actor::InternalDelegations +
    +
  • + + +
  • +
    + #termination + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #then + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #then + Concurrent::Promise +
    +
  • + + +
  • +
    + #then_ask + Concurrent::Promises::Future::ActorIntegration +
    +
  • + + +
  • +
    + #then_channel_push + Concurrent::Promises::Future::NewChannelIntegration +
    +
  • + + +
  • +
    + #then_flat_event + Concurrent::Promises::Future::FlatShortcuts +
    +
  • + + +
  • +
    + #then_flat_event_on + Concurrent::Promises::Future::FlatShortcuts +
    +
  • + + +
  • +
    + #then_flat_future + Concurrent::Promises::Future::FlatShortcuts +
    +
  • + + +
  • +
    + #then_flat_future_on + Concurrent::Promises::Future::FlatShortcuts +
    +
  • + + +
  • +
    + #then_on + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + ticker + Concurrent::Channel +
    +
  • + + +
  • +
    + timeout + Concurrent::Cancellation +
    +
  • + + +
  • +
    + #timeout_interval + Concurrent::TimerTask +
    +
  • + + +
  • +
    + timer + Concurrent::Channel +
    +
  • + + +
  • +
    + #to_ary + Concurrent::ErlangActor::Down +
    +
  • + + +
  • +
    + #to_ary + Concurrent::Cancellation +
    +
  • + + +
  • +
    + #to_ary + Concurrent::ErlangActor::Terminated +
    +
  • + + +
  • +
    + #to_ary + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #to_event + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #to_event + Concurrent::Promises::Event +
    +
  • + + +
  • +
    + #to_future + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #to_future + Concurrent::Promises::Event +
    +
  • + + +
  • +
    + #to_h + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #to_h + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #to_h + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + #to_s + Concurrent::Actor::Reference +
    +
  • + + +
  • +
    + #to_s + Concurrent::ErlangActor::Pid +
    +
  • + + +
  • +
    + #to_s + Concurrent::ProcessingActor +
    +
  • + + +
  • +
    + #to_s + Concurrent::LockFreeStack +
    +
  • + + +
  • +
    + #to_s + Concurrent::Throttle +
    +
  • + + +
  • +
    + #to_s + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #to_s + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #to_s + Concurrent::AtomicFixnum +
    +
  • + + +
  • +
    + #to_s + Concurrent::Channel::Tick +
    +
  • + + +
  • +
    + #to_s + Concurrent::AtomicBoolean +
    +
  • + + +
  • +
    + #to_s + Concurrent::Cancellation +
    +
  • + + +
  • +
    + #to_s + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #to_s + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + to_spawn_options + Concurrent::Actor +
    +
  • + + +
  • +
    + to_sym + Fulfilled.new(nil) +
    +
  • + + +
  • +
    + #touch + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #trap + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #trapping= + Concurrent::Actor::Behaviour::Termination +
    +
  • + + +
  • +
    + #trapping? + Concurrent::Actor::Behaviour::Termination +
    +
  • + + +
  • +
    + #traps? + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #true? + Concurrent::AtomicBoolean +
    +
  • + + +
  • +
    + #try? + Concurrent::Event +
    +
  • + + +
  • +
    + #try_acquire + Concurrent::Semaphore +
    +
  • + + +
  • +
    + #try_acquire + Concurrent::Throttle +
    +
  • + + +
  • +
    + #try_exchange + Concurrent +
    +
  • + + +
  • +
    + #try_pop + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #try_pop_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #try_push + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #try_put! + Concurrent::MVar +
    +
  • + + +
  • +
    + #try_read_lock + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #try_select + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + try_select + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #try_select_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + try_select_matching + Concurrent::Promises::Channel +
    +
  • + + +
  • +
    + #try_set + Concurrent::IVar +
    +
  • + + +
  • +
    + #try_take! + Concurrent::MVar +
    +
  • + + +
  • +
    + #try_update + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + #try_update + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #try_update! + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #try_update! + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + #try_write_lock + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #unlink + Concurrent::Actor::Behaviour::Linking +
    +
  • + + +
  • +
    + #unlink + Concurrent::ErlangActor::Environment +
    +
  • + + +
  • +
    + #unlock + Concurrent::Transaction +
    +
  • + + +
  • +
    + #unregister + Concurrent::LazyRegister +
    +
  • + + +
  • +
    + #unscheduled? + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #update + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #update + Concurrent::AtomicReference +
    +
  • + + +
  • +
    + #update + Concurrent::AtomicFixnum +
    +
  • + + +
  • +
    + #update_successor + Concurrent::LockFreeQueue::Node +
    +
  • + + +
  • +
    + use_simple_logger + Concurrent +
    +
  • + + +
  • +
    + use_stdlib_logger + Concurrent +
    +
  • + + +
  • +
    + user_messages + Concurrent::Actor::Behaviour +
    +
  • + + +
  • +
    + #utc + Concurrent::Channel::Tick +
    +
  • + + +
  • +
    + #value + Concurrent::LockFreeStack::Node +
    +
  • + + +
  • +
    + #value + Concurrent::AtomicBoolean +
    +
  • + + +
  • +
    + #value + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #value + Concurrent::Delay +
    +
  • + + +
  • +
    + #value + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #value + Concurrent::ThreadLocalVar +
    +
  • + + +
  • +
    + #value + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #value + Concurrent::Agent +
    +
  • + + +
  • +
    + #value + Concurrent::Concern::Dereferenceable +
    +
  • + + +
  • +
    + #value + Concurrent::Transaction::OpenEntry +
    +
  • + + +
  • +
    + #value + Concurrent::Atom +
    +
  • + + +
  • +
    + #value + Concurrent::TVar +
    +
  • + + +
  • +
    + #value + Concurrent::AtomicFixnum +
    +
  • + + +
  • +
    + #value + Concurrent::AtomicMarkableReference +
    +
  • + + +
  • +
    + #value! + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #value! + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #value! + Concurrent::Delay +
    +
  • + + +
  • +
    + #value! + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #value= + Concurrent::AtomicBoolean +
    +
  • + + +
  • +
    + #value= + Concurrent::AtomicFixnum +
    +
  • + + +
  • +
    + #value= + Concurrent::ThreadLocalVar +
    +
  • + + +
  • +
    + #value= + Concurrent::TVar +
    +
  • + + +
  • +
    + #value? + Concurrent::Map +
    +
  • + + +
  • +
    + #values + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + #values + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #values + Concurrent::Map +
    +
  • + + +
  • +
    + #values + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #values_at + Concurrent::SettableStruct +
    +
  • + + +
  • +
    + #values_at + Concurrent::MutableStruct +
    +
  • + + +
  • +
    + #values_at + Concurrent::ImmutableStruct +
    +
  • + + +
  • +
    + #wait + Concurrent::Event +
    +
  • + + +
  • +
    + #wait + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #wait + Concurrent::CyclicBarrier +
    +
  • + + +
  • +
    + #wait + Concurrent::Delay +
    +
  • + + +
  • +
    + #wait + Concurrent::Agent +
    +
  • + + +
  • +
    + #wait + Concurrent::CountDownLatch +
    +
  • + + +
  • +
    + #wait + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #wait + Concurrent::Synchronization +
    +
  • + + +
  • +
    + #wait + Concurrent::Promises::ResolvableEvent +
    +
  • + + +
  • +
    + #wait + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #wait! + Concurrent::Concern::Obligation +
    +
  • + + +
  • +
    + #wait! + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #wait! + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #wait_for_termination + Concurrent::ImmediateExecutor +
    +
  • + + +
  • +
    + #wait_for_termination + Concurrent::SimpleExecutorService +
    +
  • + + +
  • +
    + #wait_for_termination + Concurrent::ThreadPoolExecutor +
    +
  • + + +
  • +
    + #wait_for_termination + Concurrent::SingleThreadExecutor +
    +
  • + + +
  • +
    + #wait_or_cancel + Concurrent::Future +
    +
  • + + +
  • +
    + #wait_until + Concurrent::Synchronization +
    +
  • + + +
  • +
    + #with_default_executor + Concurrent::Promises::AbstractEventFuture +
    +
  • + + +
  • +
    + #with_default_executor + Concurrent::Promises::Event +
    +
  • + + +
  • +
    + #with_default_executor + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #with_hidden_resolvable + Concurrent::Promises::ResolvableFuture +
    +
  • + + +
  • +
    + #with_hidden_resolvable + Concurrent::Promises::ResolvableEvent +
    +
  • + + +
  • +
    + #with_observer + Concurrent::Concern::Observable +
    +
  • + + +
  • +
    + #with_read_lock + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + #with_read_lock + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #with_write_lock + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + #with_write_lock + Concurrent::ReentrantReadWriteLock +
    +
  • + + +
  • +
    + #write + Concurrent::Transaction +
    +
  • + + +
  • +
    + #write_locked? + Concurrent::ReadWriteLock +
    +
  • + + +
  • +
    + #xorshift + Concurrent::ThreadSafe::Util::XorShiftRandom +
    +
  • + + +
  • +
    + #zip + Concurrent::Promises::Event +
    +
  • + + +
  • +
    + zip + Concurrent::Promise +
    +
  • + + +
  • +
    + #zip + Concurrent::Promise +
    +
  • + + +
  • +
    + #zip + Concurrent::Promises::Future +
    +
  • + + +
  • +
    + #zip_events + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #zip_events_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #zip_futures + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #zip_futures_on + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #zip_futures_over + Concurrent::Promises::FactoryMethods +
    +
  • + + +
  • +
    + #zip_futures_over_on + Concurrent::Promises::FactoryMethods +
    +
  • + + + +
+
+ + diff --git a/docs/1.1.10/top-level-namespace.html b/docs/1.1.10/top-level-namespace.html new file mode 100644 index 000000000..dd8666ef1 --- /dev/null +++ b/docs/1.1.10/top-level-namespace.html @@ -0,0 +1,119 @@ + + + + + + + Top Level Namespace + + — Concurrent Ruby + + + + + + + + + + + + + + + + + + + +
+ + +

Top Level Namespace + + + +

+
+ + + + + + + + + + + +
+ +

Defined Under Namespace

+

+ + + Modules: Concurrent + + + + +

+ + + + + + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/docs/file.signpost.html b/docs/file.signpost.html index df9f2d200..ad484b009 100644 --- a/docs/file.signpost.html +++ b/docs/file.signpost.html @@ -63,6 +63,7 @@
@@ -364,7 +364,7 @@

@@ -390,7 +390,7 @@

@@ -416,7 +416,7 @@

@@ -442,7 +442,7 @@

@@ -468,7 +468,7 @@

diff --git a/docs/master/Concurrent/TimerTask.html b/docs/master/Concurrent/TimerTask.html index 319ccd7b8..b72752492 100644 --- a/docs/master/Concurrent/TimerTask.html +++ b/docs/master/Concurrent/TimerTask.html @@ -344,6 +344,21 @@

60
+
TIMEOUT_INTERVAL = +
+
+

Default :timeout_interval in seconds.

+ + +
+
+
+ + +
+
+
30
+ @@ -376,6 +391,32 @@

Instance Attribute Summary collaps

Number of seconds after the task completes before the task is performed again.

+ + + +
  • + + + #timeout_interval ⇒ Fixnum + + + + + + + + + + + + + + + + +

    Number of seconds the task can run before it is considered to have failed.

    +
    +
  • @@ -876,14 +917,14 @@

     
     
    -177
    -178
    -179
     180
    -181
    +181 +182 +183 +184

    -
    # File 'lib/concurrent-ruby/concurrent/utility/processor_counter.rb', line 160
    +      
    # File 'lib/concurrent-ruby/concurrent/utility/processor_counter.rb', line 127
     
     def self.physical_processor_count
       processor_counter.physical_processor_count
    @@ -2604,12 +2604,12 @@ 

     
     
    -156
    -157
    -158
    +123 +124 +125

    -
    # File 'lib/concurrent-ruby/concurrent/utility/processor_counter.rb', line 156
    +      
    # File 'lib/concurrent-ruby/concurrent/utility/processor_counter.rb', line 123
     
     def self.processor_count
       processor_counter.processor_count
    diff --git a/docs/master/Concurrent/Async.html b/docs/master/Concurrent/Async.html
    index e27cade90..f1200de17 100644
    --- a/docs/master/Concurrent/Async.html
    +++ b/docs/master/Concurrent/Async.html
    @@ -608,12 +608,12 @@ 

     
     
    -419
    -420
    -421
    +412 +413 +414

    -
    # File 'lib/concurrent-ruby/concurrent/async.rb', line 419
    +      
    # File 'lib/concurrent-ruby/concurrent/async.rb', line 412
     
     def async
       @__async_delegator__
    @@ -716,12 +716,12 @@ 

     
     
    -437
    -438
    -439
    +430 +431 +432

    -
    # File 'lib/concurrent-ruby/concurrent/async.rb', line 437
    +      
    # File 'lib/concurrent-ruby/concurrent/async.rb', line 430
     
     def await
       @__await_delegator__
    diff --git a/docs/master/Concurrent/ErlangActor/Down.html b/docs/master/Concurrent/ErlangActor/Down.html
    index 333362e9c..b20523ad2 100644
    --- a/docs/master/Concurrent/ErlangActor/Down.html
    +++ b/docs/master/Concurrent/ErlangActor/Down.html
    @@ -324,12 +324,12 @@ 

     
     
    -1465
    -1466
    -1467
    +1461 +1462 +1463

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1465
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1461
     
     def from
       @from
    @@ -378,12 +378,12 @@ 

     
     
    -1469
    -1470
    -1471
    +1465 +1466 +1467

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1469
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1465
     
     def info
       @info
    @@ -432,12 +432,12 @@ 

     
     
    -1467
    -1468
    -1469
    +1463 +1464 +1465

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1467
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1463
     
     def reference
       @reference
    @@ -495,12 +495,12 @@ 

     
     
    -1484
    -1485
    -1486
    +1480 +1481 +1482

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1484
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1480
     
     def ==(o)
       o.class == self.class && o.from == @from && o.reference == @reference && o.info == @info
    @@ -547,12 +547,12 @@ 

     
     
    -1491
    -1492
    -1493
    +1487 +1488 +1489

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1491
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1487
     
     def hash
       to_ary.hash
    @@ -599,12 +599,12 @@ 

     
     
    -1479
    -1480
    -1481
    +1475 +1476 +1477

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1479
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1475
     
     def to_ary
       [@from, @reference, @info]
    diff --git a/docs/master/Concurrent/ErlangActor/Environment.html b/docs/master/Concurrent/ErlangActor/Environment.html
    index 1c51479f1..2c82fb6b0 100644
    --- a/docs/master/Concurrent/ErlangActor/Environment.html
    +++ b/docs/master/Concurrent/ErlangActor/Environment.html
    @@ -547,12 +547,12 @@ 

     
     
    -461
    -462
    -463
    +457 +458 +459

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 461
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 457
     
     def default_executor
       @DefaultExecutor
    @@ -668,12 +668,12 @@ 

     
     
    -328
    -329
    -330
    +324 +325 +326

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 328
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 324
     
     def demonitor(reference, *options)
       @Actor.demonitor(reference, *options)
    @@ -753,12 +753,12 @@ 
    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 232
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 228
     
     def link(pid)
       @Actor.link(pid)
    @@ -816,12 +816,12 @@ 

     
     
    -281
    -282
    -283
    +277 +278 +279

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 281
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 277
     
     def monitor(pid)
       @Actor.monitor(pid)
    @@ -873,12 +873,12 @@ 

     
     
    -150
    -151
    -152
    +146 +147 +148

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 150
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 146
     
     def name
       pid.name
    @@ -929,12 +929,12 @@ 

     
     
    -181
    -182
    -183
    +177 +178 +179

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 181
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 177
     
     def on(matcher, value = nil, &block)
       @Actor.on matcher, value, &block
    @@ -986,12 +986,12 @@ 

     
     
    -145
    -146
    -147
    +141 +142 +143

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 145
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 141
     
     def pid
       @Actor.pid
    @@ -1195,12 +1195,12 @@ 

     
     
    -214
    -215
    -216
    +210 +211 +212

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 214
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 210
     
     def receive(*rules, timeout: nil, timeout_value: nil, **options, &block)
       @Actor.receive(*rules, timeout: timeout, timeout_value: timeout_value, **options, &block)
    @@ -1276,13 +1276,13 @@ 

     
     
    -401
    -402
    -403
    -404
    +397 +398 +399 +400

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 401
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 397
     
     def reply(value)
       # TODO (pitr-ch 08-Feb-2019): consider adding reply? which returns true,false if success, reply method will always return value
    @@ -1392,12 +1392,12 @@ 

     
     
    -422
    -423
    -424
    +418 +419 +420

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 422
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 418
     
     def reply_resolution(fulfilled = true, value = nil, reason = nil)
       @Actor.reply_resolution(fulfilled, value, reason)
    @@ -1631,6 +1631,10 @@ 

     
     
    +370
    +371
    +372
    +373
     374
     375
     376
    @@ -1646,14 +1650,10 @@ 

    386 387 388 -389 -390 -391 -392 -393

    +389

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 374
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 370
     
     def spawn(*args,
               type: @Actor.class,
    @@ -1790,12 +1790,12 @@ 

     
     
    -456
    -457
    -458
    +452 +453 +454

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 456
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 452
     
     def terminate(pid = nil, reason, value: nil)
       @Actor.terminate pid, reason, value: value
    @@ -1851,12 +1851,12 @@ 

     
     
    -140
    -141
    -142
    +136 +137 +138

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 140
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 136
     
     def terminated
       @Actor.terminated
    @@ -1939,12 +1939,12 @@ 

     
     
    -172
    -173
    -174
    +168 +169 +170

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 172
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 168
     
     def trap(value = true)
       @Actor.trap(value)
    @@ -2003,12 +2003,12 @@ 

     
     
    -156
    -157
    -158
    +152 +153 +154

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 156
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 152
     
     def traps?
       @Actor.traps?
    @@ -2075,12 +2075,12 @@ 
    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 258
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 254
     
     def unlink(pid)
       @Actor.unlink(pid)
    diff --git a/docs/master/Concurrent/ErlangActor/EnvironmentConstants/AbstractLogicOperationMatcher.html b/docs/master/Concurrent/ErlangActor/EnvironmentConstants/AbstractLogicOperationMatcher.html
    index 263fc5451..c9732eec4 100644
    --- a/docs/master/Concurrent/ErlangActor/EnvironmentConstants/AbstractLogicOperationMatcher.html
    +++ b/docs/master/Concurrent/ErlangActor/EnvironmentConstants/AbstractLogicOperationMatcher.html
    @@ -214,12 +214,12 @@ 

     
     
    -595
    -596
    -597
    +591 +592 +593

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 595
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 591
     
     def initialize(*matchers)
       @matchers = matchers
    @@ -260,12 +260,12 @@ 

     
     
    -591
    -592
    -593
    +587 +588 +589

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 591
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 587
     
     def self.[](*matchers)
       new(*matchers)
    diff --git a/docs/master/Concurrent/ErlangActor/EnvironmentConstants/And.html b/docs/master/Concurrent/ErlangActor/EnvironmentConstants/And.html
    index cb68a0897..9e2f6260c 100644
    --- a/docs/master/Concurrent/ErlangActor/EnvironmentConstants/And.html
    +++ b/docs/master/Concurrent/ErlangActor/EnvironmentConstants/And.html
    @@ -211,12 +211,12 @@ 

     
     
    -606
    -607
    -608
    +602 +603 +604

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 606
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 602
     
     def ===(v)
       @matchers.all? { |m| m === v }
    diff --git a/docs/master/Concurrent/ErlangActor/EnvironmentConstants/Or.html b/docs/master/Concurrent/ErlangActor/EnvironmentConstants/Or.html
    index b19b5de64..4a797852d 100644
    --- a/docs/master/Concurrent/ErlangActor/EnvironmentConstants/Or.html
    +++ b/docs/master/Concurrent/ErlangActor/EnvironmentConstants/Or.html
    @@ -212,12 +212,12 @@ 

     
     
    -618
    -619
    -620
    +614 +615 +616

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 618
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 614
     
     def ===(v)
       @matchers.any? { |m| m === v }
    diff --git a/docs/master/Concurrent/ErlangActor/FunctionShortcuts.html b/docs/master/Concurrent/ErlangActor/FunctionShortcuts.html
    index aa9ca6443..fd446dcfd 100644
    --- a/docs/master/Concurrent/ErlangActor/FunctionShortcuts.html
    +++ b/docs/master/Concurrent/ErlangActor/FunctionShortcuts.html
    @@ -206,12 +206,12 @@ 

     
     
    -534
    -535
    -536
    +530 +531 +532

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 534
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 530
     
     def spawn(*args, **kwargs, &body)
       spawn_actor(*args, **kwargs, &body)
    @@ -259,12 +259,12 @@ 

     
     
    -540
    -541
    -542
    +536 +537 +538

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 540
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 536
     
     def terminate(pid, reason)
       terminate_actor(pid, reason)
    diff --git a/docs/master/Concurrent/ErlangActor/Functions.html b/docs/master/Concurrent/ErlangActor/Functions.html
    index c2802e2ee..2b62bbc1f 100644
    --- a/docs/master/Concurrent/ErlangActor/Functions.html
    +++ b/docs/master/Concurrent/ErlangActor/Functions.html
    @@ -275,12 +275,12 @@ 

     
     
    -519
    -520
    -521
    +515 +516 +517

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 519
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 515
     
     def default_actor_executor
       default_executor
    @@ -334,12 +334,12 @@ 

     
     
    -525
    -526
    -527
    +521 +522 +523

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 525
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 521
     
     def default_executor
       :io
    @@ -480,6 +480,10 @@ 

     
     
    +488
    +489
    +490
    +491
     492
     493
     494
    @@ -487,14 +491,10 @@ 

    496 497 498 -499 -500 -501 -502 -503

    +499

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 492
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 488
     
     def spawn_actor(*args,
                     type:,
    @@ -577,17 +577,17 @@ 

     
     
    +505
    +506
    +507
    +508
     509
     510
     511
    -512
    -513
    -514
    -515
    -516
    +512

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 509
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 505
     
     def terminate_actor(pid, reason)
       if reason == :kill
    diff --git a/docs/master/Concurrent/ErlangActor/NoActor.html b/docs/master/Concurrent/ErlangActor/NoActor.html
    index d2ac23c55..959772eb3 100644
    --- a/docs/master/Concurrent/ErlangActor/NoActor.html
    +++ b/docs/master/Concurrent/ErlangActor/NoActor.html
    @@ -277,13 +277,13 @@ 

     
     
    -1507
    -1508
    -1509
    -1510
    +1503 +1504 +1505 +1506

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1507
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1503
     
     def initialize(pid = nil)
       super(pid.to_s)
    @@ -338,12 +338,12 @@ 

     
     
    -1503
    -1504
    -1505
    +1499 +1500 +1501

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1503
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1499
     
     def pid
       @pid
    @@ -401,12 +401,12 @@ 

     
     
    -1513
    -1514
    -1515
    +1509 +1510 +1511

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1513
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1509
     
     def ==(o)
       o.class == self.class && o.pid == self.pid
    @@ -453,12 +453,12 @@ 

     
     
    -1520
    -1521
    -1522
    +1516 +1517 +1518

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1520
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1516
     
     def hash
       pid.hash
    diff --git a/docs/master/Concurrent/ErlangActor/Pid.html b/docs/master/Concurrent/ErlangActor/Pid.html
    index 9c7bf4278..2e898b0be 100644
    --- a/docs/master/Concurrent/ErlangActor/Pid.html
    +++ b/docs/master/Concurrent/ErlangActor/Pid.html
    @@ -413,12 +413,12 @@ 

     
     
    -77
    -78
    -79
    +73 +74 +75

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 77
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 73
     
     def ask(message, timeout = nil, timeout_value = nil)
       @Actor.ask message, timeout, timeout_value
    @@ -502,12 +502,12 @@ 

     
     
    -86
    -87
    -88
    +82 +83 +84

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 86
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 82
     
     def ask_op(message, probe = Promises.resolvable_future)
       @Actor.ask_op message, probe
    @@ -559,12 +559,12 @@ 

     
     
    -99
    -100
    -101
    +95 +96 +97

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 99
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 95
     
     def name
       @Name
    @@ -652,12 +652,12 @@ 

     
     
    -52
    -53
    -54
    +48 +49 +50

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 52
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 48
     
     def tell(message, timeout = nil)
       @Actor.tell message, timeout
    @@ -720,12 +720,12 @@ 

     
     
    -59
    -60
    -61
    +55 +56 +57

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 59
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 55
     
     def tell_op(message)
       @Actor.tell_op(message)
    @@ -781,12 +781,12 @@ 

     
     
    -94
    -95
    -96
    +90 +91 +92

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 94
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 90
     
     def terminated
       @Actor.terminated
    @@ -842,6 +842,10 @@ 

     
     
    +100
    +101
    +102
    +103
     104
     105
     106
    @@ -851,14 +855,10 @@ 

    110 111 112 -113 -114 -115 -116 -117

    +113

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 104
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 100
     
     def to_s
       original = super
    diff --git a/docs/master/Concurrent/ErlangActor/Terminated.html b/docs/master/Concurrent/ErlangActor/Terminated.html
    index 9a2f1f6dd..a34fa28b3 100644
    --- a/docs/master/Concurrent/ErlangActor/Terminated.html
    +++ b/docs/master/Concurrent/ErlangActor/Terminated.html
    @@ -297,12 +297,12 @@ 

     
     
    -1403
    -1404
    -1405
    +1399 +1400 +1401

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1403
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1399
     
     def from
       @from
    @@ -351,12 +351,12 @@ 

     
     
    -1405
    -1406
    -1407
    +1401 +1402 +1403

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1405
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1401
     
     def reason
       @reason
    @@ -414,12 +414,12 @@ 

     
     
    -1420
    -1421
    -1422
    +1416 +1417 +1418

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1420
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1416
     
     def ==(o)
       o.class == self.class && o.from == @from && o.reason == self.reason
    @@ -466,12 +466,12 @@ 

     
     
    -1427
    -1428
    -1429
    +1423 +1424 +1425

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1427
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1423
     
     def hash
       [@from, @reason].hash
    @@ -518,12 +518,12 @@ 

     
     
    -1415
    -1416
    -1417
    +1411 +1412 +1413

    -
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1415
    +      
    # File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 1411
     
     def to_ary
       [@from, @reason]
    diff --git a/docs/master/Concurrent/Map.html b/docs/master/Concurrent/Map.html
    index 6fd149895..e8b6e42a7 100644
    --- a/docs/master/Concurrent/Map.html
    +++ b/docs/master/Concurrent/Map.html
    @@ -489,8 +489,6 @@ 

    - (also: #index) - @@ -1794,13 +1792,13 @@

     
     
    +287
     288
     289
    -290
    -291
    +290

    -
    # File 'lib/concurrent-ruby/concurrent/map.rb', line 288
    +      
    # File 'lib/concurrent-ruby/concurrent/map.rb', line 287
     
     def empty?
       each_pair { |k, v| return false }
    @@ -2230,10 +2228,6 @@ 

    - Also known as: - index - -

    @@ -2811,14 +2805,14 @@

     
     
    +294
     295
     296
     297
    -298
    -299
    +298

    -
    # File 'lib/concurrent-ruby/concurrent/map.rb', line 295
    +      
    # File 'lib/concurrent-ruby/concurrent/map.rb', line 294
     
     def size
       count = 0
    diff --git a/docs/master/Concurrent/Synchronization.html b/docs/master/Concurrent/Synchronization.html
    index 8acc18de6..fa2e0e01a 100644
    --- a/docs/master/Concurrent/Synchronization.html
    +++ b/docs/master/Concurrent/Synchronization.html
    @@ -338,7 +338,7 @@ 

    -
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 69
    +      
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 67
     
     
    -
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 54
    +      
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 52
     
     
    -
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 66
    +      
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 64
     
     
    -
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 57
    +      
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 55
     
     
    -
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 63
    +      
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 61
     
     
    -
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 60
    +      
    # File 'lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb', line 58
     
     
    -
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 177
    +      
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 180
     
     def initialize(opts = {}, &task)
       raise ArgumentError.new('no block given') unless block_given?
    @@ -946,12 +987,12 @@ 

     
     
    -227
    -228
    -229
    +230 +231 +232

    -
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 227
    +      
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 230
     
     def execution_interval
       synchronize { @execution_interval }
    @@ -961,6 +1002,67 @@ 

    + + +
    +

    + + #timeout_intervalFixnum + + + + + +

    +
    +

    Returns Number of seconds the task can run before it is +considered to have failed.

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Fixnum) + + + + — +

      Number of seconds the task can run before it is +considered to have failed.

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +248
    +249
    +250
    +
    +
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 248
    +
    +def timeout_interval
    +  warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly'
    +end
    +
    +
    + @@ -1182,12 +1284,12 @@

     
     
    -220
    -221
    -222
    +223 +224 +225 -
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 220
    +      
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 223
     
     def self.execute(opts = {}, &task)
       TimerTask.new(opts, &task).execute
    @@ -1266,18 +1368,18 @@ 

     
     
    -203
    -204
    -205
     206
     207
     208
     209
     210
    -211
    +211 +212 +213 +214

    -
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 203
    +      
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 206
     
     def execute
       synchronize do
    @@ -1335,12 +1437,12 @@ 

     
     
    -186
    -187
    -188
    +189 +190 +191

    -
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 186
    +      
    # File 'lib/concurrent-ruby/concurrent/timer_task.rb', line 189
     
     def running?
       @running.true?
    diff --git a/docs/master/file.CHANGELOG.html b/docs/master/file.CHANGELOG.html
    index be48ab422..cd4412a28 100644
    --- a/docs/master/file.CHANGELOG.html
    +++ b/docs/master/file.CHANGELOG.html
    @@ -59,6 +59,22 @@
     
           

    Current

    +

    Release v1.1.10

    + +

    concurrent-ruby:

    + +
      +
    • (#951) Set the Ruby compatibility version at 2.2
    • +
    • (#939, #933) The caller_runs fallback policy no longer blocks reads from the job queue by worker threads
    • +
    • (#938, #761, #652) You can now explicitly prune_pool a thread pool (Sylvain Joyeux)
    • +
    • (#937, #757, #670) We switched the Yahoo stock API for demos to Alpha Vantage (Gustavo Caso)
    • +
    • (#932, #931) We changed how SafeTaskExecutor handles local jump errors (Aaron Jensen)
    • +
    • (#927) You can use keyword arguments in your initialize when using Async (Matt Larraz)
    • +
    • (#926, #639) We removed timeout from TimerTask because it wasn't sound, and now it's a no-op with a warning (Jacob Atzen)
    • +
    • (#919) If you double-lock a re-entrant read-write lock, we promote to locked for writing (zp yuan)
    • +
    • (#915) monotonic_time now accepts an optional unit parameter, as Ruby's clock_gettime (Jean Boussier)
    • +
    +

    Release v1.1.9 (5 Jun 2021)

    concurrent-ruby:

    diff --git a/docs/master/file.README.html b/docs/master/file.README.html index 95a8c8b20..c91b17a55 100644 --- a/docs/master/file.README.html +++ b/docs/master/file.README.html @@ -351,16 +351,12 @@

    Edge Features

    Supported Ruby versions

      -
    • MRI 2.0 and above
    • -
    • JRuby 9000
    • -
    • TruffleRuby are supported.
    • -
    • Any Ruby interpreter that is compliant with Ruby 2.0 or newer.
    • +
    • MRI 2.2 and above
    • +
    • Latest JRuby 9000
    • +
    • Latest TruffleRuby
    -

    Actually we still support mri 1.9.3 and jruby 1.7.27 but we are looking at ways how to drop the support. -Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs is supported.

    - -

    The legacy support for Rubinius is kept but it is no longer maintained, if you would like to help +

    The legacy support for Rubinius is kept for the moment but it is no longer maintained and is liable to be removed. If you would like to help please respond to #739.

    Usage

    @@ -450,7 +446,7 @@

    Requirements

    Publishing the Gem

      -
    • Updateversion.rb
    • +
    • Update version.rb
    • Update the CHANGELOG
    • Update the Yard documentation diff --git a/docs/master/index.html b/docs/master/index.html index d41347665..76c737095 100644 --- a/docs/master/index.html +++ b/docs/master/index.html @@ -351,16 +351,12 @@

      Edge Features

      Supported Ruby versions

        -
      • MRI 2.0 and above
      • -
      • JRuby 9000
      • -
      • TruffleRuby are supported.
      • -
      • Any Ruby interpreter that is compliant with Ruby 2.0 or newer.
      • +
      • MRI 2.2 and above
      • +
      • Latest JRuby 9000
      • +
      • Latest TruffleRuby
      -

      Actually we still support mri 1.9.3 and jruby 1.7.27 but we are looking at ways how to drop the support. -Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs is supported.

      - -

      The legacy support for Rubinius is kept but it is no longer maintained, if you would like to help +

      The legacy support for Rubinius is kept for the moment but it is no longer maintained and is liable to be removed. If you would like to help please respond to #739.

      Usage

      @@ -450,7 +446,7 @@

      Requirements

      Publishing the Gem

        -
      • Updateversion.rb
      • +
      • Update version.rb
      • Update the CHANGELOG
      • Update the Yard documentation diff --git a/docs/master/method_list.html b/docs/master/method_list.html index eab65c898..6be04a203 100644 --- a/docs/master/method_list.html +++ b/docs/master/method_list.html @@ -54,56 +54,56 @@

        Method List

      • - #<< - Concurrent::ImmediateExecutor + << + Concurrent::SimpleExecutorService
      • - #<< - Concurrent::Agent + #<< + Concurrent::Edge::LockFreeLinkedSet
      • - << - Concurrent::SimpleExecutorService + #<< + Concurrent::ImmediateExecutor
      • - #<< - Concurrent::SimpleExecutorService + #<< + Concurrent::Agent
      • - #<< - Concurrent::Edge::LockFreeLinkedSet + #<< + Concurrent::ThreadPoolExecutor
      • - #<< - Concurrent::ThreadPoolExecutor + #<< + Concurrent::SimpleExecutorService
      • - #<=> - Concurrent::Maybe + #<=> + Concurrent::Edge::LockFreeLinkedSet::Node
      • @@ -118,24 +118,24 @@

        Method List

      • - #<=> - Concurrent::Edge::LockFreeLinkedSet::Tail + #<=> + Concurrent::Edge::LockFreeLinkedSet::Head
      • - #<=> - Concurrent::Edge::LockFreeLinkedSet::Node + #<=> + Concurrent::Maybe
      • - #<=> - Concurrent::Edge::LockFreeLinkedSet::Head + #<=> + Concurrent::Edge::LockFreeLinkedSet::Tail
      • @@ -150,48 +150,48 @@

        Method List

      • - #== - Concurrent::SettableStruct + #== + Concurrent::ErlangActor::Terminated
      • - #== - Concurrent::ErlangActor::Terminated + #== + Concurrent::MutableStruct
      • - #== - Concurrent::ImmutableStruct + #== + Concurrent::SettableStruct
      • - #== - Concurrent::Actor::Reference + #== + Concurrent::ErlangActor::NoActor
      • - #== - Concurrent::MutableStruct + #== + Concurrent::ImmutableStruct
      • - #== - Concurrent::ErlangActor::NoActor + #== + Concurrent::Actor::Reference
      • @@ -270,8 +270,8 @@

        Method List

      • - [] - Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher + #[] + Concurrent::LazyRegister
      • @@ -286,40 +286,40 @@

        Method List

      • - #[] - Concurrent::LazyRegister + #[] + Concurrent::SettableStruct
      • - #[] - Concurrent::SettableStruct + #[] + Concurrent::ImmutableStruct
      • - #[] - Concurrent::ImmutableStruct + [] + Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher
      • - #[]= - Concurrent::SettableStruct + #[]= + Concurrent::MutableStruct
      • - #[]= - Concurrent::MutableStruct + #[]= + Concurrent::SettableStruct
      • @@ -350,16 +350,16 @@

        Method List

      • - #acquire - Concurrent::Throttle + #acquire + Concurrent::Semaphore
      • - #acquire - Concurrent::Semaphore + #acquire + Concurrent::Throttle
      • @@ -438,8 +438,8 @@

        Method List

      • - #add_observer - Concurrent::Concern::Observable + #add_observer + Concurrent::IVar
      • @@ -454,8 +454,8 @@

        Method List

      • - #add_observer - Concurrent::IVar + #add_observer + Concurrent::Concern::Observable
      • @@ -502,16 +502,16 @@

        Method List

      • - #any - Concurrent::Promises::Event + #any + Concurrent::Promises::Future
      • - #any - Concurrent::Promises::Future + #any + Concurrent::Promises::Event
      • @@ -582,8 +582,8 @@

        Method List

      • - #ask - Concurrent::Actor::AbstractContext + #ask + Concurrent::ErlangActor::Pid
      • @@ -598,8 +598,8 @@

        Method List

      • - #ask - Concurrent::ErlangActor::Pid + #ask + Concurrent::Actor::AbstractContext
      • @@ -678,56 +678,56 @@

        Method List

      • - attr_volatile - Concurrent::Synchronization::Object + #attr_volatile + Concurrent::Synchronization::TruffleRubyAttrVolatile::ClassMethods
      • - #attr_volatile - Concurrent::Synchronization::MriAttrVolatile::ClassMethods + #attr_volatile + Concurrent::Synchronization::JRubyAttrVolatile::ClassMethods
      • - #attr_volatile - Concurrent::Synchronization::TruffleRubyAttrVolatile::ClassMethods + #attr_volatile + Concurrent::Synchronization::RbxAttrVolatile::ClassMethods
      • - #attr_volatile - Concurrent::Synchronization::JRubyAttrVolatile::ClassMethods + attr_volatile + Concurrent::Synchronization::Object
      • - #attr_volatile - Concurrent::Synchronization::RbxAttrVolatile::ClassMethods + #attr_volatile + Concurrent::Synchronization::MriAttrVolatile::ClassMethods
      • - #auto_terminate= - Concurrent::SingleThreadExecutor + #auto_terminate= + Concurrent::ThreadPoolExecutor
      • - #auto_terminate= - Concurrent::ThreadPoolExecutor + #auto_terminate= + Concurrent::SingleThreadExecutor
      • @@ -766,8 +766,8 @@

        Method List

      • - #await - Concurrent::Async + #await + Concurrent::Agent
      • @@ -782,15 +782,15 @@

        Method List

      • - #await - Concurrent::Agent + #await + Concurrent::Async
      • - #await_for + await_for Concurrent::Agent
      • @@ -798,7 +798,7 @@

        Method List

      • - await_for + #await_for Concurrent::Agent
      • @@ -878,32 +878,32 @@

        Method List

      • - #behaviour_definition - Concurrent::Actor::Root + #behaviour_definition + Concurrent::Actor::RestartingContext
      • - #behaviour_definition - Concurrent::Actor::AbstractContext + #behaviour_definition + Concurrent::Actor::Root
      • - #behaviour_definition - Concurrent::Actor::Context + #behaviour_definition + Concurrent::Actor::AbstractContext
      • - #behaviour_definition - Concurrent::Actor::RestartingContext + #behaviour_definition + Concurrent::Actor::Context
      • @@ -926,8 +926,8 @@

        Method List

      • - #blocking? - Concurrent::Channel::Buffer::Sliding + #blocking? + Concurrent::Channel::Buffer::Dropping
      • @@ -942,8 +942,8 @@

        Method List

      • - #blocking? - Concurrent::Channel::Buffer::Dropping + #blocking? + Concurrent::Channel::Buffer::Sliding
      • @@ -958,24 +958,24 @@

        Method List

      • - #broadcast - Concurrent::Actor::Core + #broadcast + Concurrent::Synchronization
      • - #broadcast - Concurrent::Actor::Behaviour::Abstract + #broadcast + Concurrent::Actor::Core
      • - #broadcast - Concurrent::Synchronization + #broadcast + Concurrent::Actor::Behaviour::Abstract
      • @@ -1014,16 +1014,16 @@

        Method List

      • - #can_overflow? - Concurrent::WrappingExecutor + #can_overflow? + Concurrent::ThreadPoolExecutor
      • - #can_overflow? - Concurrent::ThreadPoolExecutor + #can_overflow? + Concurrent::WrappingExecutor
      • @@ -1062,16 +1062,16 @@

        Method List

      • - #cancelled? - Concurrent::ScheduledTask + #cancelled? + Concurrent::Future
      • - #cancelled? - Concurrent::Future + #cancelled? + Concurrent::ScheduledTask
      • @@ -1126,16 +1126,16 @@

        Method List

      • - #children - Concurrent::Actor::InternalDelegations + #children + Concurrent::Actor::Core
      • - #children - Concurrent::Actor::Core + #children + Concurrent::Actor::InternalDelegations
      • @@ -1230,24 +1230,24 @@

        Method List

      • - #compare_and_set - Concurrent::AtomicReference + #compare_and_set + Concurrent::AtomicFixnum
      • - #compare_and_set - Concurrent::AtomicMarkableReference + #compare_and_set + Concurrent::AtomicReference
      • - #compare_and_set - Concurrent::AtomicFixnum + #compare_and_set + Concurrent::AtomicMarkableReference
      • @@ -1310,16 +1310,16 @@

        Method List

      • - #context - Concurrent::Actor::InternalDelegations + #context + Concurrent::Actor::Core
      • - #context - Concurrent::Actor::Core + #context + Concurrent::Actor::InternalDelegations
      • @@ -1342,16 +1342,16 @@

        Method List

      • - #core - Concurrent::Actor::Behaviour::Abstract + #core + Concurrent::Actor::AbstractContext
      • - #core - Concurrent::Actor::AbstractContext + #core + Concurrent::Actor::Behaviour::Abstract
      • @@ -1374,24 +1374,24 @@

        Method List

      • - #count_observers - Concurrent::Collection::CopyOnWriteObserverSet + #count_observers + Concurrent::Collection::CopyOnNotifyObserverSet
      • - #count_observers - Concurrent::Collection::CopyOnNotifyObserverSet + #count_observers + Concurrent::Concern::Observable
      • - #count_observers - Concurrent::Concern::Observable + #count_observers + Concurrent::Collection::CopyOnWriteObserverSet
      • @@ -1486,24 +1486,24 @@

        Method List

      • - #dead_letter_routing - Concurrent::Actor::Root + #dead_letter_routing + Concurrent::Actor::Core
      • - #dead_letter_routing - Concurrent::Actor::Core + #dead_letter_routing + Concurrent::Actor::Reference
      • - #dead_letter_routing - Concurrent::Actor::Reference + #dead_letter_routing + Concurrent::Actor::InternalDelegations
      • @@ -1518,8 +1518,8 @@

        Method List

      • - #dead_letter_routing - Concurrent::Actor::InternalDelegations + #dead_letter_routing + Concurrent::Actor::Root
      • @@ -1542,48 +1542,48 @@

        Method List

      • - #default_executor - Concurrent::Throttle + #default_executor + Concurrent::Actor::AbstractContext
      • - #default_executor - Concurrent::ErlangActor::Environment + #default_executor + Concurrent::Promises::FactoryMethods::Configuration
      • - #default_executor - Concurrent::ErlangActor::Functions + #default_executor + Concurrent::Promises::AbstractEventFuture
      • - #default_executor - Concurrent::Actor::AbstractContext + #default_executor + Concurrent::ErlangActor::Functions
      • - #default_executor - Concurrent::Promises::AbstractEventFuture + #default_executor + Concurrent::ErlangActor::Environment
      • - #default_executor - Concurrent::Promises::FactoryMethods::Configuration + #default_executor + Concurrent::Throttle
      • @@ -1598,8 +1598,8 @@

        Method List

      • - #delay - Concurrent::Promises::Future + #delay + Concurrent::Promises::FactoryMethods
      • @@ -1614,8 +1614,8 @@

        Method List

      • - #delay - Concurrent::Promises::FactoryMethods + #delay + Concurrent::Promises::Future
      • @@ -1638,24 +1638,24 @@

        Method List

      • - #delete_observer - Concurrent::Collection::CopyOnWriteObserverSet + #delete_observer + Concurrent::Collection::CopyOnNotifyObserverSet
      • - #delete_observer - Concurrent::Collection::CopyOnNotifyObserverSet + #delete_observer + Concurrent::Concern::Observable
      • - #delete_observer - Concurrent::Concern::Observable + #delete_observer + Concurrent::Collection::CopyOnWriteObserverSet
      • @@ -1726,48 +1726,48 @@

        Method List

      • - #each - Concurrent::SettableStruct + #each + Concurrent::Channel
      • - #each - Concurrent::Edge::LockFreeLinkedSet + #each + Concurrent::MutableStruct
      • - #each - Concurrent::Channel + #each + Concurrent::ImmutableStruct
      • - #each - Concurrent::ImmutableStruct + #each + Concurrent::Edge::LockFreeLinkedSet
      • - #each - Concurrent::LockFreeStack + #each + Concurrent::SettableStruct
      • - #each - Concurrent::MutableStruct + #each + Concurrent::LockFreeStack
      • @@ -1798,24 +1798,24 @@

        Method List

      • - #each_pair - Concurrent::ImmutableStruct + #each_pair + Concurrent::Map
      • - #each_pair - Concurrent::Map + #each_pair + Concurrent::MutableStruct
      • - #each_pair - Concurrent::MutableStruct + #each_pair + Concurrent::ImmutableStruct
      • @@ -1982,16 +1982,16 @@

        Method List

      • - #execute - Concurrent::Channel::Selector::TakeClause + execute + Concurrent::Promise
      • - #execute - Concurrent::Channel::Selector::PutClause + execute + Concurrent::Future
      • @@ -2006,24 +2006,24 @@

        Method List

      • - #execute - Concurrent::Channel::Selector::DefaultClause + #execute + Concurrent::Promise
      • - #execute - Concurrent::Promise + #execute + Concurrent::Channel::Selector::AfterClause
      • - #execute - Concurrent::SafeTaskExecutor + execute + Concurrent::TimerTask
      • @@ -2038,56 +2038,56 @@

        Method List

      • - execute - Concurrent::Promise + #execute + Concurrent::Channel::Selector::DefaultClause
      • - execute - Concurrent::ScheduledTask + #execute + Concurrent::Channel::Selector::ErrorClause
      • - #execute - Concurrent::ScheduledTask + #execute + Concurrent::SafeTaskExecutor
      • - execute - Concurrent::Future + execute + Concurrent::ScheduledTask
      • - #execute - Concurrent::Channel::Selector::ErrorClause + #execute + Concurrent::Channel::Selector::PutClause
      • - #execute - Concurrent::Channel::Selector::AfterClause + #execute + Concurrent::Channel::Selector::TakeClause
      • - execute - Concurrent::TimerTask + #execute + Concurrent::ScheduledTask
      • @@ -2110,24 +2110,24 @@

        Method List

      • - #executor - Concurrent::SerializedExecution::Job + executor + Concurrent
      • - executor - Concurrent + #executor + Concurrent::Actor::Core
      • - #executor - Concurrent::Actor::Core + #executor + Concurrent::SerializedExecution::Job
      • @@ -2158,16 +2158,16 @@

        Method List

      • - #fallback_policy - Concurrent::SingleThreadExecutor + #fallback_policy + Concurrent::ThreadPoolExecutor
      • - #fallback_policy - Concurrent::ThreadPoolExecutor + #fallback_policy + Concurrent::SingleThreadExecutor
      • @@ -2238,8 +2238,8 @@

        Method List

      • - from - Concurrent::Maybe + #from + Concurrent::ErlangActor::Down
      • @@ -2254,8 +2254,8 @@

        Method List

      • - #from - Concurrent::ErlangActor::Down + from + Concurrent::Maybe
      • @@ -2310,8 +2310,8 @@

        Method List

      • - #full? - Concurrent::Channel::Buffer::Dropping + #full? + Concurrent::Channel::Buffer::Base
      • @@ -2326,8 +2326,8 @@

        Method List

      • - #full? - Concurrent::Channel::Buffer::Base + #full? + Concurrent::Channel::Buffer::Dropping
      • @@ -2366,32 +2366,32 @@

        Method List

      • - #get - Concurrent::Tuple + #get + Concurrent::AtomicReference
      • - #get - Concurrent::AtomicMarkableReference + #get + Concurrent::ThreadSafe::Util::XorShiftRandom
      • - #get - Concurrent::ThreadSafe::Util::XorShiftRandom + #get + Concurrent::AtomicMarkableReference
      • - #get - Concurrent::AtomicReference + #get + Concurrent::Tuple
      • @@ -2510,16 +2510,16 @@

        Method List

      • - #hash - Concurrent::ErlangActor::Terminated + #hash + Concurrent::ErlangActor::Down
      • - #hash - Concurrent::ErlangActor::Down + #hash + Concurrent::ErlangActor::Terminated
      • @@ -2574,672 +2574,672 @@

        Method List

      • - #initialize - Concurrent::Channel::Selector::PutClause + #initialize + Concurrent::ThreadLocalVar
      • - #initialize - Concurrent::Map + #initialize + Concurrent::WrappingExecutor
      • - #initialize - Concurrent::Atom + #initialize + Concurrent::Actor::Behaviour::Supervising
      • - #initialize - Concurrent::IVar + #initialize + Concurrent::ScheduledTask
      • - #initialize - Concurrent::MVar + #initialize + Concurrent::Edge::LockFreeLinkedSet
      • - #initialize - Concurrent::TVar + #initialize + Concurrent::Actor::Behaviour::Termination
      • - #initialize - Concurrent::Transaction + #initialize + Concurrent::Channel::Selector::PutClause
      • - #initialize - Concurrent::Agent::Error + #initialize + Concurrent::TimerSet
      • - #initialize - Concurrent::Agent::ValidationError + #initialize + Concurrent::AtomicFixnum
      • - #initialize - Concurrent::Agent + #initialize + Concurrent::AtomicBoolean
      • - #initialize - Concurrent::Delay + #initialize + Concurrent::CyclicBarrier
      • - #initialize - Concurrent::Tuple + #initialize + Concurrent::Actor::Behaviour::Abstract
      • - #initialize - Concurrent::MultipleAssignmentError + #initialize + Concurrent::ReadWriteLock
      • - #initialize - Concurrent::MultipleErrors + #initialize + Concurrent::Synchronization::Object
      • - #initialize - Concurrent::Future + #initialize + Concurrent::Actor::Behaviour::SetResults
      • - #initialize - Concurrent::Promise + #initialize + Concurrent::Channel::Selector::TakeClause
      • - #initialize - Concurrent + #initialize + Concurrent::AtomicReference
      • - #initialize - Concurrent::TimerTask + #initialize + Concurrent::CountDownLatch
      • - #initialize - Concurrent::Event + #initialize + Concurrent::Channel::Selector::AfterClause
      • - #initialize - Concurrent::ScheduledTask + #initialize + Concurrent::Semaphore
      • - #initialize - Concurrent::Semaphore + #initialize + Concurrent::Actor::Behaviour::Pausing
      • - #initialize - Concurrent::TimerSet + #initialize + Concurrent::Event
      • - #initialize - Concurrent::AtomicFixnum + #initialize + Concurrent::LockFreeStack::Node
      • - #initialize - Concurrent::AtomicBoolean + #initialize + Concurrent::FixedThreadPool
      • - #initialize - Concurrent::CyclicBarrier + #initialize + Concurrent::CachedThreadPool
      • - #initialize - Concurrent::ReadWriteLock + #initialize + Concurrent::ImmediateExecutor
      • - #initialize - Concurrent::Synchronization::Object + #initialize + Concurrent::Actor::Behaviour::Linking
      • - #initialize - Concurrent::AtomicReference + #initialize + Concurrent::SafeTaskExecutor
      • - #initialize - Concurrent::CountDownLatch + #initialize + Concurrent::Channel::Selector::ErrorClause
      • - #initialize - Concurrent::ThreadLocalVar + #initialize + Concurrent::SerializedExecution
      • - #initialize - Concurrent::LockFreeStack::Node + #initialize + Concurrent::TimerTask
      • - #initialize - Concurrent::FixedThreadPool + #initialize + Concurrent
      • - #initialize - Concurrent::CachedThreadPool + #initialize + Concurrent::Actor::Behaviour::Buffer
      • - #initialize - Concurrent::ImmediateExecutor + #initialize + Concurrent::Edge::LockFreeLinkedSet::Node
      • - #initialize - Concurrent::SafeTaskExecutor + #initialize + Concurrent::Edge::LockFreeLinkedSet::Tail
      • - #initialize - Concurrent::SerializedExecution + #initialize + Concurrent::Actor::Utils::Broadcast
      • - #initialize - Concurrent::Synchronization + #initialize + Concurrent::LockFreeQueue::Node
      • - #initialize - Concurrent::AtomicMarkableReference + #initialize + Concurrent::Synchronization
      • - #initialize - Concurrent::ReentrantReadWriteLock + #initialize + Concurrent::Channel::Selector::DefaultClause
      • - #initialize - Concurrent::IndirectImmediateExecutor + #initialize + Concurrent::AtomicMarkableReference
      • - #initialize - Concurrent::Collection::CopyOnWriteObserverSet + #initialize + Concurrent::Actor::Utils::Balancer
      • - #initialize - Concurrent::Collection::CopyOnNotifyObserverSet + #initialize + Concurrent::ReentrantReadWriteLock
      • - #initialize - Concurrent::SerializedExecutionDelegator + #initialize + Concurrent::Edge::LockFreeLinkedSet::Window
      • - #initialize - Concurrent::Channel::ValidationError + #initialize + Concurrent::Channel::Buffer::Base
      • - #initialize - Concurrent::Channel + #initialize + Concurrent::Actor::Utils::AsAdHoc
      • - #initialize - Concurrent::Actor::Core + #initialize + Concurrent::IndirectImmediateExecutor
      • - #initialize - Concurrent::Actor::Root + #initialize + Concurrent::Collection::CopyOnWriteObserverSet
      • - #initialize - Concurrent::Actor::ActorTerminated + #initialize + Concurrent::Promise
      • - #initialize - Concurrent::Actor::UnknownMessage + #initialize + Concurrent::LockFreeStack
      • - #initialize - Concurrent::Channel::Tick + #initialize + Concurrent::Collection::CopyOnNotifyObserverSet
      • - #initialize - Concurrent::Promises::Channel + #initialize + Concurrent::Future
      • - #initialize - Concurrent::Throttle + #initialize + Concurrent::MultipleErrors
      • - #initialize - Concurrent::LazyRegister + #initialize + Concurrent::SerializedExecutionDelegator
      • - #initialize - Concurrent::Actor::Envelope + #initialize + Concurrent::MultipleAssignmentError
      • - #initialize - Concurrent::Actor::Utils::Pool + #initialize + Concurrent::ErlangActor::NoActor
      • - #initialize - Concurrent::Cancellation + #initialize + Concurrent::Channel::ValidationError
      • - #initialize - Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher + #initialize + Concurrent::Channel
      • - #initialize - Concurrent::ErlangActor::NoActor + #initialize + Concurrent::Tuple
      • - #initialize - Concurrent::Actor::Utils::AsAdHoc + #initialize + Concurrent::Actor::Core
      • - #initialize - Concurrent::Channel::Buffer::Base + #initialize + Concurrent::Delay
      • - #initialize - Concurrent::Actor::Utils::Balancer + #initialize + Concurrent::Actor::Root
      • - #initialize - Concurrent::LockFreeQueue::Node + #initialize + Concurrent::ErlangActor::EnvironmentConstants::AbstractLogicOperationMatcher
      • - #initialize - Concurrent::Actor::Utils::Broadcast + #initialize + Concurrent::Actor::ActorTerminated
      • - #initialize - Concurrent::Actor::Behaviour::Buffer + #initialize + Concurrent::Agent
      • - #initialize - Concurrent::Actor::Behaviour::Linking + #initialize + Concurrent::Actor::UnknownMessage
      • - #initialize - Concurrent::Actor::Behaviour::Pausing + #initialize + Concurrent::Channel::Tick
      • - #initialize - Concurrent::Actor::Behaviour::Abstract + #initialize + Concurrent::Agent::ValidationError
      • - #initialize - Concurrent::Edge::LockFreeLinkedSet + #initialize + Concurrent::Agent::Error
      • - #initialize - Concurrent::WrappingExecutor + #initialize + Concurrent::Promises::Channel
      • - #initialize - Concurrent::Actor::Behaviour::Supervising + #initialize + Concurrent::Transaction
      • - #initialize - Concurrent::Actor::Behaviour::Termination + #initialize + Concurrent::TVar
      • - #initialize - Concurrent::Actor::Behaviour::SetResults + #initialize + Concurrent::Cancellation
      • - #initialize - Concurrent::Channel::Selector::TakeClause + #initialize + Concurrent::Actor::Utils::Pool
      • - #initialize - Concurrent::Channel::Selector::AfterClause + #initialize + Concurrent::MVar
      • - #initialize - Concurrent::Channel::Selector::ErrorClause + #initialize + Concurrent::IVar
      • - #initialize - Concurrent::Edge::LockFreeLinkedSet::Node + #initialize + Concurrent::Atom
      • - #initialize - Concurrent::Edge::LockFreeLinkedSet::Tail + #initialize + Concurrent::Throttle
      • - #initialize - Concurrent::Channel::Selector::DefaultClause + #initialize + Concurrent::Map
      • - #initialize - Concurrent::Edge::LockFreeLinkedSet::Window + #initialize + Concurrent::LazyRegister
      • - #initialize - Concurrent::LockFreeStack + #initialize + Concurrent::Actor::Envelope
      • - #inspect - Concurrent::MutableStruct + #inspect + Concurrent::MultipleAssignmentError
      • - #inspect - Concurrent::MultipleAssignmentError + #inspect + Concurrent::ImmutableStruct
      • - #inspect - Concurrent::SettableStruct + #inspect + Concurrent::MutableStruct
      • - #inspect - Concurrent::ImmutableStruct + #inspect + Concurrent::SettableStruct
      • @@ -3302,16 +3302,16 @@

        Method List

      • - #key - Concurrent::Map + #key + Concurrent::Edge::LockFreeLinkedSet::Node
      • - #key - Concurrent::Edge::LockFreeLinkedSet::Node + #key + Concurrent::Map
      • @@ -3334,32 +3334,32 @@

        Method List

      • - #kill - Concurrent::TimerSet + #kill + Concurrent::SimpleExecutorService
      • - #kill - Concurrent::SingleThreadExecutor + #kill + Concurrent::TimerSet
      • - #kill - Concurrent::SimpleExecutorService + #kill + Concurrent::ThreadPoolExecutor
      • - #kill - Concurrent::ThreadPoolExecutor + #kill + Concurrent::SingleThreadExecutor
      • @@ -3526,16 +3526,16 @@

        Method List

      • - #merge - Concurrent::MutableStruct + #merge + Concurrent::ImmutableStruct
      • - #merge - Concurrent::ImmutableStruct + #merge + Concurrent::MutableStruct
      • @@ -3550,16 +3550,16 @@

        Method List

      • - #message - Concurrent::Actor::Reference + #message + Concurrent::Actor::Envelope
      • - #message - Concurrent::Actor::Envelope + #message + Concurrent::Actor::Reference
      • @@ -3630,24 +3630,24 @@

        Method List

      • - #name - Concurrent::Actor::PublicDelegations + #name + Concurrent::ErlangActor::Pid
      • - #name - Concurrent::ErlangActor::Pid + #name + Concurrent::ErlangActor::Environment
      • - #name - Concurrent::ErlangActor::Environment + #name + Concurrent::Actor::PublicDelegations
      • @@ -3678,8 +3678,8 @@

        Method List

      • - #next - Concurrent::Channel::Buffer::Unbuffered + #next + Concurrent::Channel
      • @@ -3702,8 +3702,8 @@

        Method List

      • - #next - Concurrent::Channel + #next + Concurrent::Channel::Buffer::Unbuffered
      • @@ -3726,8 +3726,8 @@

        Method List

      • - #next_node - Concurrent::LockFreeStack::Node + next_node + Node[nil, nil]
      • @@ -3742,15 +3742,15 @@

        Method List

      • - next_node - Node[nil, nil] + #next_node + Concurrent::LockFreeStack::Node
      • - #nothing + nothing Concurrent::Maybe
      • @@ -3758,7 +3758,7 @@

        Method List

      • - nothing + #nothing Concurrent::Maybe
      • @@ -3774,32 +3774,32 @@

        Method List

      • - #notify_and_delete_observers - Concurrent::Collection::CopyOnNotifyObserverSet + #notify_and_delete_observers + Concurrent::Collection::CopyOnWriteObserverSet
      • - #notify_and_delete_observers - Concurrent::Collection::CopyOnWriteObserverSet + #notify_and_delete_observers + Concurrent::Collection::CopyOnNotifyObserverSet
      • - #notify_observers - Concurrent::Collection::CopyOnNotifyObserverSet + #notify_observers + Concurrent::Collection::CopyOnWriteObserverSet
      • - #notify_observers - Concurrent::Collection::CopyOnWriteObserverSet + #notify_observers + Concurrent::Collection::CopyOnNotifyObserverSet
      • @@ -3814,16 +3814,16 @@

        Method List

      • - #offer - Concurrent::Channel::Buffer::Sliding + #offer + Concurrent::Channel::Buffer::Buffered
      • - #offer - Concurrent::Channel::Buffer::Buffered + #offer + Concurrent::Channel::Buffer::Timer
      • @@ -3846,24 +3846,24 @@

        Method List

      • - #offer - Concurrent::Channel + #offer + Concurrent::Channel::Buffer::Base
      • - #offer - Concurrent::Channel::Buffer::Timer + #offer + Concurrent::Channel
      • - #offer - Concurrent::Channel::Buffer::Base + #offer + Concurrent::Channel::Buffer::Sliding
      • @@ -3886,16 +3886,16 @@

        Method List

      • - #on - Concurrent::ErlangActor::Environment + #on + Concurrent::Throttle
      • - #on - Concurrent::Throttle + #on + Concurrent::ErlangActor::Environment
      • @@ -3918,48 +3918,48 @@

        Method List

      • - #on_envelope - Concurrent::Actor::Behaviour::Abstract + #on_envelope + Concurrent::Actor::Behaviour::Pausing
      • - #on_envelope - Concurrent::Actor::Behaviour::ErrorsOnUnknownMessage + #on_envelope + Concurrent::Actor::Behaviour::SetResults
      • - #on_envelope - Concurrent::Actor::Behaviour::Awaits + #on_envelope + Concurrent::Actor::Behaviour::ErrorsOnUnknownMessage
      • - #on_envelope - Concurrent::Actor::Behaviour::RemovesChild + #on_envelope + Concurrent::Actor::Behaviour::Supervising
      • - #on_envelope - Concurrent::Actor::Behaviour::SetResults + #on_envelope + Concurrent::Actor::Behaviour::Abstract
      • - #on_envelope - Concurrent::Actor::Behaviour::Buffer + #on_envelope + Concurrent::Actor::Core
      • @@ -3974,16 +3974,16 @@

        Method List

      • - #on_envelope - Concurrent::Actor::Core + #on_envelope + Concurrent::Actor::Behaviour::Buffer
      • - #on_envelope - Concurrent::Actor::Behaviour::Supervising + #on_envelope + Concurrent::Actor::Behaviour::Awaits
      • @@ -3998,56 +3998,56 @@

        Method List

      • - #on_envelope - Concurrent::Actor::Behaviour::Pausing + #on_envelope + Concurrent::Actor::Behaviour::RemovesChild
      • - #on_event - Concurrent::Actor::AbstractContext + #on_event + Concurrent::Actor::Behaviour::Abstract
      • - #on_event - Concurrent::Actor::Behaviour::ExecutesContext + #on_event + Concurrent::Actor::Behaviour::Pausing
      • - #on_event - Concurrent::Actor::Behaviour::Buffer + #on_event + Concurrent::Actor::Behaviour::ExecutesContext
      • - #on_event - Concurrent::Actor::Behaviour::Linking + #on_event + Concurrent::Actor::Behaviour::Buffer
      • - #on_event - Concurrent::Actor::Behaviour::Pausing + #on_event + Concurrent::Actor::Behaviour::Linking
      • - #on_event - Concurrent::Actor::Behaviour::Abstract + #on_event + Concurrent::Actor::AbstractContext
      • @@ -4078,8 +4078,8 @@

        Method List

      • - #on_message - Concurrent::Actor::Utils::AsAdHoc + #on_message + Concurrent::Actor::Root
      • @@ -4094,8 +4094,8 @@

        Method List

      • - #on_message - Concurrent::Actor::Root + #on_message + Concurrent::Actor::DefaultDeadLetterHandler
      • @@ -4110,16 +4110,16 @@

        Method List

      • - #on_message - Concurrent::Actor::Utils::Balancer + #on_message + Concurrent::Actor::Utils::AsAdHoc
      • - #on_message - Concurrent::Actor::DefaultDeadLetterHandler + #on_message + Concurrent::Actor::Utils::Balancer
      • @@ -4214,16 +4214,16 @@

        Method List

      • - #parent - Concurrent::Actor::Core + #parent + Concurrent::Actor::PublicDelegations
      • - #parent - Concurrent::Actor::PublicDelegations + #parent + Concurrent::Actor::Core
      • @@ -4238,32 +4238,32 @@

        Method List

      • - #pass - Concurrent::Actor::Behaviour::Abstract + #pass + Concurrent::Actor::AbstractContext
      • - #pass - Concurrent::Actor::AbstractContext + #pass + Concurrent::Actor::Behaviour::Abstract
      • - #path - Concurrent::Actor::PublicDelegations + #path + Concurrent::Actor::Core
      • - #path - Concurrent::Actor::Core + #path + Concurrent::Actor::PublicDelegations
      • @@ -4286,16 +4286,16 @@

        Method List

      • - #peek - Concurrent::LockFreeStack + #peek + Concurrent::Promises::Channel
      • - #peek - Concurrent::Promises::Channel + #peek + Concurrent::LockFreeStack
      • @@ -4334,32 +4334,32 @@

        Method List

      • - #pid - Concurrent::ErlangActor::Environment + #pid + Concurrent::ErlangActor::NoActor
      • - #pid - Concurrent::ErlangActor::NoActor + #pid + Concurrent::ErlangActor::Environment
      • - #poll - Concurrent::Channel::Buffer::Unbuffered + #poll + Concurrent::Channel::Buffer::Timer
      • - #poll - Concurrent::Channel::Buffer::Base + #poll + Concurrent::Channel
      • @@ -4374,16 +4374,16 @@

        Method List

      • - #poll - Concurrent::Channel + #poll + Concurrent::Channel::Buffer::Base
      • - #poll - Concurrent::Channel::Buffer::Timer + #poll + Concurrent::Channel::Buffer::Unbuffered
      • @@ -4406,16 +4406,16 @@

        Method List

      • - #pop - Concurrent::LockFreeStack + #pop + Concurrent::Promises::Channel
      • - #pop - Concurrent::Promises::Channel + #pop + Concurrent::LockFreeStack
      • @@ -4446,80 +4446,80 @@

        Method List

      • - post - Concurrent::SimpleExecutorService + #post + Concurrent::WrappingExecutor
      • - #post - Concurrent::TimerSet + #post + Concurrent::SimpleExecutorService
      • - #post - Concurrent::WrappingExecutor + #post + Concurrent::SerializedExecutionDelegator
      • - #post - Concurrent::SimpleExecutorService + #post + Concurrent::SingleThreadExecutor
      • - #post - Concurrent::SerializedExecution + #post + Concurrent::ThreadPoolExecutor
      • - #post - Concurrent::ImmediateExecutor + #post + Concurrent::SerializedExecution
      • - #post - Concurrent::SerializedExecutionDelegator + post + Concurrent::SimpleExecutorService
      • - #post - Concurrent::ThreadPoolExecutor + #post + Concurrent::IndirectImmediateExecutor
      • - #post - Concurrent::IndirectImmediateExecutor + #post + Concurrent::TimerSet
      • - #post - Concurrent::SingleThreadExecutor + #post + Concurrent::ImmediateExecutor
      • @@ -4542,16 +4542,16 @@

        Method List

      • - #process_envelope - Concurrent::Actor::Behaviour::Buffer + #process_envelope + Concurrent::Actor::Core
      • - #process_envelope - Concurrent::Actor::Core + #process_envelope + Concurrent::Actor::Behaviour::Buffer
      • @@ -4590,16 +4590,16 @@

        Method List

      • - #push - Concurrent::LockFreeStack + #push + Concurrent::Promises::Channel
      • - #push - Concurrent::Promises::Channel + #push + Concurrent::LockFreeStack
      • @@ -4614,56 +4614,56 @@

        Method List

      • - #put - Concurrent::MVar + #put + Concurrent::Channel::Buffer::Timer
      • - #put - Concurrent::Channel::Buffer::Sliding + #put + Concurrent::Channel::Buffer::Buffered
      • - #put - Concurrent::Channel::Buffer::Buffered + #put + Concurrent::Channel::Buffer::Sliding
      • - #put - Concurrent::Channel::Buffer::Unbuffered + #put + Concurrent::Channel
      • - #put - Concurrent::Channel::Buffer::Dropping + #put + Concurrent::Channel::Buffer::Unbuffered
      • - #put - Concurrent::Channel::Buffer::Timer + #put + Concurrent::MVar
      • - #put - Concurrent::Channel + #put + Concurrent::Channel::Buffer::Dropping
      • @@ -4726,8 +4726,8 @@

        Method List

      • - #reason - Concurrent::Concern::Obligation + #reason + Concurrent::ErlangActor::Terminated
      • @@ -4742,24 +4742,24 @@

        Method List

      • - #reason - Concurrent::ErlangActor::Terminated + #reason + Concurrent::Concern::Obligation
      • - #receive - Concurrent::ProcessingActor + #receive + Concurrent::ErlangActor::Environment
      • - #receive - Concurrent::ErlangActor::Environment + #receive + Concurrent::ProcessingActor
      • @@ -4790,24 +4790,24 @@

        Method List

      • - #reference - Concurrent::Actor::PublicDelegations + #reference + Concurrent::ErlangActor::Down
      • - #reference - Concurrent::Actor::ActorTerminated + #reference + Concurrent::Actor::PublicDelegations
      • - #reference - Concurrent::ErlangActor::Down + #reference + Concurrent::Actor::ActorTerminated
      • @@ -4886,24 +4886,24 @@

        Method List

      • - #release - Concurrent::Semaphore + #release + Concurrent::Throttle
      • - #release - Concurrent::Promises::Resolvable + #release + Concurrent::Semaphore
      • - #release - Concurrent::Throttle + #release + Concurrent::Promises::Resolvable
      • @@ -4926,16 +4926,16 @@

        Method List

      • - #release_write_lock - Concurrent::ReadWriteLock + #release_write_lock + Concurrent::ReentrantReadWriteLock
      • - #release_write_lock - Concurrent::ReentrantReadWriteLock + #release_write_lock + Concurrent::ReadWriteLock
      • @@ -5046,16 +5046,16 @@

        Method List

      • - #reset - Concurrent::CyclicBarrier + #reset + Concurrent::ScheduledTask
      • - #reset - Concurrent::Atom + #reset + Concurrent::CyclicBarrier
      • @@ -5070,8 +5070,8 @@

        Method List

      • - #reset - Concurrent::ScheduledTask + #reset + Concurrent::Atom
      • @@ -5182,16 +5182,16 @@

        Method List

      • - #result - Concurrent::Promises::ResolvableFuture + #result + Concurrent::Promises::Future
      • - #result - Concurrent::Promises::Future + #result + Concurrent::Promises::ResolvableFuture
      • @@ -5222,8 +5222,8 @@

        Method List

      • - #running? - Concurrent::TimerTask + #running? + Concurrent::SingleThreadExecutor
      • @@ -5238,24 +5238,24 @@

        Method List

      • - #running? - Concurrent::SimpleExecutorService + #running? + Concurrent::ImmediateExecutor
      • - #running? - Concurrent::SingleThreadExecutor + #running? + Concurrent::SimpleExecutorService
      • - #running? - Concurrent::ImmediateExecutor + #running? + Concurrent::TimerTask
      • @@ -5286,16 +5286,16 @@

        Method List

      • - #schedule - Concurrent::Promises::Event + #schedule + Concurrent::Promises::Future
      • - #schedule - Concurrent::Promises::Future + #schedule + Concurrent::Promises::Event
      • @@ -5334,32 +5334,32 @@

        Method List

      • - #select - Concurrent::ImmutableStruct + #select + Concurrent::MutableStruct
      • - select - Concurrent::Promises::Channel + #select + Concurrent::ImmutableStruct
      • - #select - Concurrent::MutableStruct + select + Concurrent::Channel
      • - select - Concurrent::Channel + select + Concurrent::Promises::Channel
      • @@ -5382,7 +5382,7 @@

        Method List

      • - select_matching + #select_matching Concurrent::Promises::Channel
      • @@ -5390,7 +5390,7 @@

        Method List

      • - #select_matching + select_matching Concurrent::Promises::Channel
      • @@ -5414,7 +5414,7 @@

        Method List

      • - select_op_matching + #select_op_matching Concurrent::Promises::Channel
      • @@ -5422,7 +5422,7 @@

        Method List

      • - #select_op_matching + select_op_matching Concurrent::Promises::Channel
      • @@ -5494,80 +5494,80 @@

        Method List

      • - #serialized? - Concurrent::ThreadPoolExecutor + #serialized? + Concurrent::WrappingExecutor
      • - #serialized? - Concurrent::WrappingExecutor + #serialized? + Concurrent::SingleThreadExecutor
      • - #serialized? - Concurrent::SingleThreadExecutor + #serialized? + Concurrent::ThreadPoolExecutor
      • - #set - Concurrent::AtomicMarkableReference + #set + Concurrent::Promise
      • - #set - Concurrent::Future + #set + Concurrent::IVar
      • - #set - Concurrent::Event + #set + Concurrent::AtomicMarkableReference
      • - #set - Concurrent::Promise + #set + Concurrent::AtomicReference
      • - #set - Concurrent::AtomicReference + #set + Concurrent::Tuple
      • - #set - Concurrent::IVar + #set + Concurrent::Future
      • - #set - Concurrent::Tuple + #set + Concurrent::Event
      • @@ -5590,24 +5590,24 @@

        Method List

      • - #shutdown - Concurrent::ThreadPoolExecutor + #shutdown + Concurrent::SingleThreadExecutor
      • - #shutdown - Concurrent::SingleThreadExecutor + #shutdown + Concurrent::ImmediateExecutor
      • - #shutdown - Concurrent::ImmediateExecutor + #shutdown + Concurrent::ThreadPoolExecutor
      • @@ -5622,24 +5622,24 @@

        Method List

      • - #shutdown? - Concurrent::SingleThreadExecutor + #shutdown? + Concurrent::ThreadPoolExecutor
      • - #shutdown? - Concurrent::ImmediateExecutor + #shutdown? + Concurrent::SingleThreadExecutor
      • - #shutdown? - Concurrent::ThreadPoolExecutor + #shutdown? + Concurrent::ImmediateExecutor
      • @@ -5670,16 +5670,16 @@

        Method List

      • - #shuttingdown? - Concurrent::ThreadPoolExecutor + #shuttingdown? + Concurrent::SingleThreadExecutor
      • - #shuttingdown? - Concurrent::SingleThreadExecutor + #shuttingdown? + Concurrent::ThreadPoolExecutor
      • @@ -5694,24 +5694,24 @@

        Method List

      • - #size - Concurrent::Tuple + #size + Concurrent::Channel::Buffer::Base
      • - #size - Concurrent::Channel::Buffer::Base + #size + Concurrent::Promises::Channel
      • - #size - Concurrent::Promises::Channel + #size + Concurrent::Map
      • @@ -5725,33 +5725,33 @@

        Method List

      • -
        - #size - Concurrent::Map +
        + #size + Concurrent::Tuple
      • - #spawn - Concurrent::ErlangActor::FunctionShortcuts + #spawn + Concurrent::ErlangActor::Environment
      • - #spawn - Concurrent::ErlangActor::Environment + spawn + Concurrent::Actor
      • - spawn - Concurrent::Actor + #spawn + Concurrent::ErlangActor::FunctionShortcuts
      • @@ -5766,16 +5766,16 @@

        Method List

      • - spawn! - Concurrent::Actor + spawn! + Concurrent::Actor::AbstractContext
      • - spawn! - Concurrent::Actor::AbstractContext + spawn! + Concurrent::Actor
      • @@ -5790,16 +5790,16 @@

        Method List

      • - #state - Concurrent::Promises::AbstractEventFuture + #state + Concurrent::Concern::Obligation
      • - #state - Concurrent::Concern::Obligation + #state + Concurrent::Promises::AbstractEventFuture
      • @@ -5902,16 +5902,16 @@

        Method List

      • - #take - Concurrent::Channel::Buffer::Buffered + #take + Concurrent::MVar
      • - #take - Concurrent::MVar + #take + Concurrent::Channel::Buffer::Buffered
      • @@ -5950,16 +5950,16 @@

        Method List

      • - #tell - Concurrent::ErlangActor::Pid + #tell + Concurrent::Actor::Reference
      • - #tell - Concurrent::Actor::Reference + #tell + Concurrent::ErlangActor::Pid
      • @@ -5974,48 +5974,48 @@

        Method List

      • - #tell_op - Concurrent::ProcessingActor + #tell_op + Concurrent::ErlangActor::Pid
      • - #tell_op - Concurrent::ErlangActor::Pid + #tell_op + Concurrent::ProcessingActor
      • - #terminate - Concurrent::ErlangActor::Environment + #terminate + Concurrent::ErlangActor::FunctionShortcuts
      • - #terminate - Concurrent::ErlangActor::FunctionShortcuts + #terminate + Concurrent::ErlangActor::Environment
      • - #terminate! - Concurrent::Actor::InternalDelegations + #terminate! + Concurrent::Actor::Behaviour::Termination
      • - #terminate! - Concurrent::Actor::Behaviour::Termination + #terminate! + Concurrent::Actor::InternalDelegations
      • @@ -6030,8 +6030,8 @@

        Method List

      • - #terminated - Concurrent::ErlangActor::Environment + #terminated + Concurrent::Actor::Behaviour::Termination
      • @@ -6046,8 +6046,8 @@

        Method List

      • - #terminated - Concurrent::Actor::Behaviour::Termination + #terminated + Concurrent::ErlangActor::Environment
      • @@ -6078,16 +6078,16 @@

        Method List

      • - #then - Concurrent::Promise + #then + Concurrent::Promises::Future
      • - #then - Concurrent::Promises::Future + #then + Concurrent::Promise
      • @@ -6166,45 +6166,53 @@

        Method List

      • - timer - Concurrent::Channel + #timeout_interval + Concurrent::TimerTask
      • - #to_ary - Concurrent::ErlangActor::Terminated + timer + Concurrent::Channel
      • - #to_ary - Concurrent::ProcessingActor + #to_ary + Concurrent::ErlangActor::Down
      • - #to_ary - Concurrent::ErlangActor::Down + #to_ary + Concurrent::Cancellation
      • - #to_ary - Concurrent::Cancellation + #to_ary + Concurrent::ErlangActor::Terminated
      • +
        + #to_ary + Concurrent::ProcessingActor +
        +
      • + + +
      • #to_event Concurrent::Promises::Future @@ -6212,7 +6220,7 @@

        Method List

      • -
      • +
      • #to_event Concurrent::Promises::Event @@ -6220,7 +6228,7 @@

        Method List

      • -
      • +
      • #to_future Concurrent::Promises::Future @@ -6228,7 +6236,7 @@

        Method List

      • -
      • +
      • #to_future Concurrent::Promises::Event @@ -6236,7 +6244,7 @@

        Method List

      • -
      • +
      • #to_h Concurrent::SettableStruct @@ -6244,7 +6252,7 @@

        Method List

      • -
      • +
      • #to_h Concurrent::MutableStruct @@ -6252,7 +6260,7 @@

        Method List

      • -
      • +
      • #to_h Concurrent::ImmutableStruct @@ -6260,90 +6268,82 @@

        Method List

      • -
      • -
        - #to_s - Concurrent::AtomicReference -
        -
      • - -
      • - #to_s - Concurrent::AtomicFixnum + #to_s + Concurrent::Actor::Reference
      • - #to_s - Concurrent::Promises::Future + #to_s + Concurrent::ErlangActor::Pid
      • - #to_s - Concurrent::LockFreeStack + #to_s + Concurrent::ProcessingActor
      • - #to_s - Concurrent::ProcessingActor + #to_s + Concurrent::LockFreeStack
      • - #to_s - Concurrent::Actor::Reference + #to_s + Concurrent::Throttle
      • - #to_s - Concurrent::Promises::Channel + #to_s + Concurrent::Promises::AbstractEventFuture
      • - #to_s - Concurrent::Throttle + #to_s + Concurrent::Promises::Future
      • - #to_s - Concurrent::ErlangActor::Pid + #to_s + Concurrent::AtomicFixnum
      • - #to_s - Concurrent::AtomicBoolean + #to_s + Concurrent::Channel::Tick
      • - #to_s - Concurrent::Channel::Tick + #to_s + Concurrent::AtomicBoolean
      • @@ -6358,13 +6358,21 @@

        Method List

      • - #to_s - Concurrent::Promises::AbstractEventFuture + #to_s + Concurrent::Promises::Channel
      • +
        + #to_s + Concurrent::AtomicReference +
        +
      • + + +
      • to_spawn_options Concurrent::Actor @@ -6372,7 +6380,7 @@

        Method List

      • -
      • +
      • to_sym Fulfilled.new(nil) @@ -6380,7 +6388,7 @@

        Method List

      • -
      • +
      • #touch Concurrent::Promises::AbstractEventFuture @@ -6388,7 +6396,7 @@

        Method List

      • -
      • +
      • #trap Concurrent::ErlangActor::Environment @@ -6396,7 +6404,7 @@

        Method List

      • -
      • +
      • #trapping= Concurrent::Actor::Behaviour::Termination @@ -6404,7 +6412,7 @@

        Method List

      • -
      • +
      • #trapping? Concurrent::Actor::Behaviour::Termination @@ -6412,7 +6420,7 @@

        Method List

      • -
      • +
      • #traps? Concurrent::ErlangActor::Environment @@ -6420,7 +6428,7 @@

        Method List

      • -
      • +
      • #true? Concurrent::AtomicBoolean @@ -6428,7 +6436,7 @@

        Method List

      • -
      • +
      • #try? Concurrent::Event @@ -6436,7 +6444,7 @@

        Method List

      • -
      • +
      • #try_acquire Concurrent::Semaphore @@ -6444,7 +6452,7 @@

        Method List

      • -
      • +
      • #try_acquire Concurrent::Throttle @@ -6452,7 +6460,7 @@

        Method List

      • -
      • +
      • #try_exchange Concurrent @@ -6460,7 +6468,7 @@

        Method List

      • -
      • +
      • #try_pop Concurrent::Promises::Channel @@ -6468,7 +6476,7 @@

        Method List

      • -
      • +
      • #try_pop_matching Concurrent::Promises::Channel @@ -6476,7 +6484,7 @@

        Method List

      • -
      • +
      • #try_push Concurrent::Promises::Channel @@ -6484,7 +6492,7 @@

        Method List

      • -
      • +
      • #try_put! Concurrent::MVar @@ -6492,7 +6500,7 @@

        Method List

      • -
      • +
      • #try_read_lock Concurrent::ReentrantReadWriteLock @@ -6500,23 +6508,23 @@

        Method List

      • -
      • +
      • - try_select + #try_select Concurrent::Promises::Channel
      • -
      • +
      • - #try_select + try_select Concurrent::Promises::Channel
      • -
      • +
      • #try_select_matching Concurrent::Promises::Channel @@ -6524,7 +6532,7 @@

        Method List

      • -
      • +
      • try_select_matching Concurrent::Promises::Channel @@ -6532,7 +6540,7 @@

        Method List

      • -
      • +
      • #try_set Concurrent::IVar @@ -6540,7 +6548,7 @@

        Method List

      • -
      • +
      • #try_take! Concurrent::MVar @@ -6548,7 +6556,7 @@

        Method List

      • -
      • +
      • #try_update Concurrent::AtomicReference @@ -6556,7 +6564,7 @@

        Method List

      • -
      • +
      • #try_update Concurrent::AtomicMarkableReference @@ -6564,23 +6572,23 @@

        Method List

      • -
      • +
      • - #try_update! - Concurrent::AtomicReference + #try_update! + Concurrent::AtomicMarkableReference
      • -
      • +
      • - #try_update! - Concurrent::AtomicMarkableReference + #try_update! + Concurrent::AtomicReference
      • -
      • +
      • #try_write_lock Concurrent::ReentrantReadWriteLock @@ -6588,7 +6596,7 @@

        Method List

      • -
      • +
      • #unlink Concurrent::Actor::Behaviour::Linking @@ -6596,7 +6604,7 @@

        Method List

      • -
      • +
      • #unlink Concurrent::ErlangActor::Environment @@ -6604,7 +6612,7 @@

        Method List

      • -
      • +
      • #unlock Concurrent::Transaction @@ -6612,7 +6620,7 @@

        Method List

      • -
      • +
      • #unregister Concurrent::LazyRegister @@ -6620,7 +6628,7 @@

        Method List

      • -
      • +
      • #unscheduled? Concurrent::Concern::Obligation @@ -6628,15 +6636,15 @@

        Method List

      • -
      • +
      • - #update - Concurrent::AtomicFixnum + #update + Concurrent::AtomicMarkableReference
      • -
      • +
      • #update Concurrent::AtomicReference @@ -6644,15 +6652,15 @@

        Method List

      • -
      • +
      • - #update - Concurrent::AtomicMarkableReference + #update + Concurrent::AtomicFixnum
      • -
      • +
      • #update_successor Concurrent::LockFreeQueue::Node @@ -6660,7 +6668,7 @@

        Method List

      • -
      • +
      • use_simple_logger Concurrent @@ -6668,7 +6676,7 @@

        Method List

      • -
      • +
      • use_stdlib_logger Concurrent @@ -6676,7 +6684,7 @@

        Method List

      • -
      • +
      • user_messages Concurrent::Actor::Behaviour @@ -6684,7 +6692,7 @@

        Method List

      • -
      • +
      • #utc Concurrent::Channel::Tick @@ -6692,66 +6700,74 @@

        Method List

      • +
      • +
        + #value + Concurrent::LockFreeStack::Node +
        +
      • + +
      • - #value - Concurrent::ThreadLocalVar + #value + Concurrent::AtomicBoolean
      • - #value - Concurrent::Delay + #value + Concurrent::Promises::ResolvableFuture
      • - #value - Concurrent::AtomicBoolean + #value + Concurrent::Delay
      • - #value - Concurrent::LockFreeStack::Node + #value + Concurrent::Concern::Obligation
      • - #value - Concurrent::Promises::Future + #value + Concurrent::ThreadLocalVar
      • - #value - Concurrent::Agent + #value + Concurrent::Promises::Future
      • - #value - Concurrent::Promises::ResolvableFuture + #value + Concurrent::Agent
      • - #value - Concurrent::Concern::Obligation + #value + Concurrent::Concern::Dereferenceable
      • @@ -6766,8 +6782,8 @@

        Method List

      • - #value - Concurrent::Concern::Dereferenceable + #value + Concurrent::Atom
      • @@ -6790,48 +6806,48 @@

        Method List

      • - #value - Concurrent::Atom + #value + Concurrent::AtomicMarkableReference
      • - #value - Concurrent::AtomicMarkableReference + #value! + Concurrent::Promises::Future
      • - #value! - Concurrent::Promises::Future + #value! + Concurrent::Concern::Obligation
      • - #value! - Concurrent::Promises::ResolvableFuture + #value! + Concurrent::Delay
      • - #value! - Concurrent::Concern::Obligation + #value! + Concurrent::Promises::ResolvableFuture
      • - #value! - Concurrent::Delay + #value= + Concurrent::AtomicBoolean
      • @@ -6862,32 +6878,32 @@

        Method List

      • - #value= - Concurrent::AtomicBoolean + #value? + Concurrent::Map
      • - #value? - Concurrent::Map + #values + Concurrent::ImmutableStruct
      • - #values - Concurrent::Map + #values + Concurrent::MutableStruct
      • - #values - Concurrent::ImmutableStruct + #values + Concurrent::Map
      • @@ -6902,48 +6918,48 @@

        Method List

      • - #values - Concurrent::MutableStruct + #values_at + Concurrent::SettableStruct
      • - #values_at - Concurrent::SettableStruct + #values_at + Concurrent::MutableStruct
      • - #values_at - Concurrent::MutableStruct + #values_at + Concurrent::ImmutableStruct
      • - #values_at - Concurrent::ImmutableStruct + #wait + Concurrent::Event
      • - #wait - Concurrent::Synchronization + #wait + Concurrent::Concern::Obligation
      • - #wait - Concurrent::CountDownLatch + #wait + Concurrent::CyclicBarrier
      • @@ -6966,48 +6982,48 @@

        Method List

      • - #wait - Concurrent::Promises::AbstractEventFuture + #wait + Concurrent::CountDownLatch
      • - #wait - Concurrent::CyclicBarrier + #wait + Concurrent::Promises::AbstractEventFuture
      • - #wait - Concurrent::Concern::Obligation + #wait + Concurrent::Synchronization
      • - #wait - Concurrent::Promises::ResolvableFuture + #wait + Concurrent::Promises::ResolvableEvent
      • - #wait - Concurrent::Promises::ResolvableEvent + #wait + Concurrent::Promises::ResolvableFuture
      • - #wait - Concurrent::Event + #wait! + Concurrent::Concern::Obligation
      • @@ -7021,14 +7037,6 @@

        Method List

      • -
        - #wait! - Concurrent::Concern::Obligation -
        -
      • - - -
      • #wait! Concurrent::Promises::ResolvableFuture @@ -7036,7 +7044,7 @@

        Method List

      • -
      • +
      • #wait_for_termination Concurrent::ImmediateExecutor @@ -7044,15 +7052,15 @@

        Method List

      • -
      • +
      • - #wait_for_termination - Concurrent::SingleThreadExecutor + #wait_for_termination + Concurrent::SimpleExecutorService
      • -
      • +
      • #wait_for_termination Concurrent::ThreadPoolExecutor @@ -7060,15 +7068,15 @@

        Method List

      • -
      • +
      • - #wait_for_termination - Concurrent::SimpleExecutorService + #wait_for_termination + Concurrent::SingleThreadExecutor
      • -
      • +
      • #wait_or_cancel Concurrent::Future @@ -7076,7 +7084,7 @@

        Method List

      • -
      • +
      • #wait_until Concurrent::Synchronization @@ -7084,15 +7092,15 @@

        Method List

      • -
      • +
      • - #with_default_executor - Concurrent::Promises::Future + #with_default_executor + Concurrent::Promises::AbstractEventFuture
      • -
      • +
      • #with_default_executor Concurrent::Promises::Event @@ -7100,15 +7108,15 @@

        Method List

      • -
      • +
      • - #with_default_executor - Concurrent::Promises::AbstractEventFuture + #with_default_executor + Concurrent::Promises::Future
      • -
      • +
      • #with_hidden_resolvable Concurrent::Promises::ResolvableFuture @@ -7116,7 +7124,7 @@

        Method List

      • -
      • +
      • #with_hidden_resolvable Concurrent::Promises::ResolvableEvent @@ -7124,7 +7132,7 @@

        Method List

      • -
      • +
      • #with_observer Concurrent::Concern::Observable @@ -7132,6 +7140,14 @@

        Method List

      • +
      • +
        + #with_read_lock + Concurrent::ReadWriteLock +
        +
      • + +
      • #with_read_lock @@ -7142,7 +7158,7 @@

        Method List

      • - #with_read_lock + #with_write_lock Concurrent::ReadWriteLock
      • @@ -7158,32 +7174,32 @@

        Method List

      • - #with_write_lock - Concurrent::ReadWriteLock + #write + Concurrent::Transaction
      • - #write - Concurrent::Transaction + #write_locked? + Concurrent::ReadWriteLock
      • - #write_locked? - Concurrent::ReadWriteLock + #xorshift + Concurrent::ThreadSafe::Util::XorShiftRandom
      • - #xorshift - Concurrent::ThreadSafe::Util::XorShiftRandom + #zip + Concurrent::Promises::Event
      • @@ -7205,14 +7221,6 @@

        Method List

      • -
        - #zip - Concurrent::Promises::Event -
        -
      • - - -
      • #zip Concurrent::Promises::Future @@ -7220,7 +7228,7 @@

        Method List

      • -
      • +
      • #zip_events Concurrent::Promises::FactoryMethods @@ -7228,7 +7236,7 @@

        Method List

      • -
      • +
      • #zip_events_on Concurrent::Promises::FactoryMethods @@ -7236,7 +7244,7 @@

        Method List

      • -
      • +
      • #zip_futures Concurrent::Promises::FactoryMethods @@ -7244,7 +7252,7 @@

        Method List

      • -
      • +
      • #zip_futures_on Concurrent::Promises::FactoryMethods @@ -7252,7 +7260,7 @@

        Method List

      • -
      • +
      • #zip_futures_over Concurrent::Promises::FactoryMethods @@ -7260,7 +7268,7 @@

        Method List

      • -
      • +
      • #zip_futures_over_on Concurrent::Promises::FactoryMethods