Class: Farce::Queue

Inherits:
Abstract::Queue show all
Includes:
Shareable::Unfreezable, Internal::ManagedQueue
Defined in:
lib/farce/queue.rb

Overview

A shareable FIFO queue with transfer modes for unshareable values.

Instance Attribute Summary

Attributes inherited from Abstract::Queue

#capacity, #mode, #num_waiting, #size

Instance Method Summary collapse

Methods included from Shareable

#ractor_shareable?

Methods inherited from Abstract::Queue

#age_tracking?, #clear, #close, #closed?, #deq, #duplicable?, #empty?, #enq, #full?, #generation, #length, #max, #oldest_age, #oldest_enqueued_at, #seal, #sealed?, #wait_pop, #wait_push

Constructor Details

#initialize(capacity: 1024, mode: :copy, track_age: false) ⇒ BasicObject

This method is abstract.

Subclasses may add additional parameters to this method.

Valid modes are:

  • :copy - The value will be copied between Ractors. This is the default mode.
  • :make_shareable - The value will be made Ractor-shareable using Ractor.make_shareable.
  • :move - The value will be moved between Ractors. This saves memory compared to copying, and supports values that can't be copied but moved (like IO objects). However, the value will no longer be accessible on the Ractor that pushed it.
  • :mutable - A Mutable instance will be created for the value. This isn't done recursively and thus will fail for nested unshareable values.
  • :local - The value will be kept local to the Ractor that pushed it. Another ractor trying to receive it will get an error. Useful for usage contained within a single Ractor.
  • :proxy - The value will be wrapped in a Farce::Proxy that executes calls in the original Ractor.
  • :raise - An error will be raised if the value is not Ractor-shareable. Useful for enforcing shareability.
  • :dedup - The value will be deduplicated using Farce.dedup, then made Ractor-shareable. This may update and freeze the original. Already-shareable values pass through unchanged.
  • :shareable_copy - The value will be copied and the copy will be made Ractor-shareable.

Parameters:

  • capacity (Integer, nil) (defaults to: 1024) —

    The maximum number of items the queue can hold. If nil, the queue is unbounded.

    The default may vary for subclasses. Most notably, priority and timer queues default to nil.

  • track_age (Boolean) (defaults to: false) —

    Whether to track enqueue age and queue generations.

  • mode (Symbol) (defaults to: :copy) —

    the default mode for sending unshareable values



14
15
16
17
18
# File 'lib/farce/queue.rb', line 14

def initialize(capacity: 1024, mode: :copy, track_age: false)
  @manager = ModeManager.new(mode:)
  @queue = Internal::Queue.new(capacity:, track_age:)
  super()
end

Instance Method Details

#pop(non_block = false, timeout: nil) ⇒ BasicObject

rubocop:disable Style/OptionalBooleanParameter



43
44
45
46
47
48
49
50
# File 'lib/farce/queue.rb', line 43

def pop(non_block = false, timeout: nil) # rubocop:disable Style/OptionalBooleanParameter
  return try_pop { raise ThreadError, "queue empty" } if non_block

  empty = false
  result = timeout.nil? ? @queue.pop { empty = true } : @queue.pop(timeout:) { empty = true }
  return @manager.unwrap(result) unless empty
  yield if block_given?
end

#push(value, non_block = false, timeout: nil, mode: nil) ⇒ BasicObject

rubocop:disable Style/OptionalBooleanParameter Valid modes are:

  • :copy - The value will be copied between Ractors. This is the default mode.
  • :make_shareable - The value will be made Ractor-shareable using Ractor.make_shareable.
  • :move - The value will be moved between Ractors. This saves memory compared to copying, and supports values that can't be copied but moved (like IO objects). However, the value will no longer be accessible on the Ractor that pushed it.
  • :mutable - A Mutable instance will be created for the value. This isn't done recursively and thus will fail for nested unshareable values.
  • :local - The value will be kept local to the Ractor that pushed it. Another ractor trying to receive it will get an error. Useful for usage contained within a single Ractor.
  • :proxy - The value will be wrapped in a Farce::Proxy that executes calls in the original Ractor.
  • :raise - An error will be raised if the value is not Ractor-shareable. Useful for enforcing shareability.
  • :dedup - The value will be deduplicated using Farce.dedup, then made Ractor-shareable. This may update and freeze the original. Already-shareable values pass through unchanged.
  • :shareable_copy - The value will be copied and the copy will be made Ractor-shareable.

Parameters:

  • mode (Symbol) (defaults to: nil) —

    the default mode for sending unshareable values



23
24
25
26
27
28
29
30
31
32
# File 'lib/farce/queue.rb', line 23

def push(value, non_block = false, timeout: nil, mode: nil) # rubocop:disable Style/OptionalBooleanParameter
  value = @manager.wrap(value, mode:)

  if non_block
    return true if @queue.try_push(value)
    raise ThreadError, "queue full"
  end

  timeout.nil? ? @queue.push(value) : @queue.push(value, timeout:)
end

#try_pop { ... } ⇒ BasicObject?

This method is abstract.

Subclasses may add additional parameters to this method.

Tries to take an item from the queue without blocking. If no item is available, the method will call the block if given, or return nil if no block is given.

Yields:

  • Block called if no item is available.

Returns:

  • (BasicObject, nil) —

    The item taken from the queue, or the return value of the block or nil if no item was available.



53
54
55
56
57
58
# File 'lib/farce/queue.rb', line 53

def try_pop
  empty = false
  result = @queue.try_pop { empty = true }
  return @manager.unwrap(result) unless empty
  yield if block_given?
end

#try_push(value, mode: nil) { ... } ⇒ Boolean

This method is abstract.

Subclasses may add additional parameters to this method.

Tries to push an item onto the queue without blocking. If the queue is at capacity, the method will call the block if given, or return false if no block is given. Valid modes are:

  • :copy - The value will be copied between Ractors. This is the default mode.
  • :make_shareable - The value will be made Ractor-shareable using Ractor.make_shareable.
  • :move - The value will be moved between Ractors. This saves memory compared to copying, and supports values that can't be copied but moved (like IO objects). However, the value will no longer be accessible on the Ractor that pushed it.
  • :mutable - A Mutable instance will be created for the value. This isn't done recursively and thus will fail for nested unshareable values.
  • :local - The value will be kept local to the Ractor that pushed it. Another ractor trying to receive it will get an error. Useful for usage contained within a single Ractor.
  • :proxy - The value will be wrapped in a Farce::Proxy that executes calls in the original Ractor.
  • :raise - An error will be raised if the value is not Ractor-shareable. Useful for enforcing shareability.
  • :dedup - The value will be deduplicated using Farce.dedup, then made Ractor-shareable. This may update and freeze the original. Already-shareable values pass through unchanged.
  • :shareable_copy - The value will be copied and the copy will be made Ractor-shareable.

Parameters:

  • value (BasicObject) —

    The item to add to the queue.

  • mode (Symbol) (defaults to: nil) —

    the default mode for sending unshareable values

Yields:

  • Block called if the queue is at capacity.

Returns:

  • (Boolean) —

    true if the item was added to the queue, false if the queue was at capacity and no block was given.

Raises:



37
38
39
40
# File 'lib/farce/queue.rb', line 37

def try_push(value, mode: nil)
  return true if @queue.try_push(@manager.wrap(value, mode:))
  block_given? ? yield : false
end