Class: Farce::Molecule

Inherits:
Abstract::Molecule show all
Includes:
Shareable
Defined in:
lib/farce/molecule.rb

Overview

A Ractor-shareable record with independently atomic fields. Values use the selected transfer mode, just like Atom. An explicitly supplied atom keeps its own settings.

This class is an alternative to Ruby's Struct or Data classes.

Examples:

Updating a named field atomically

Job = Farce::Molecule.define(:status, :attempts)
job = Job.new(status: :pending, attempts: 0)
job.attempts_atom.update { |count| count + 1 }
job.status = :running
job.to_h # => { status: :running, attempts: 1 }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Shareable

#ractor_shareable?

Methods inherited from Abstract::Molecule

atoms, #atoms, compare_by_identity?, #compare_by_identity?, #each, #each_atom, #each_member, #each_value, #freeze, members, #members

Constructor Details

#initialize(mode: nil) ⇒ Molecule

Initialize fields and optionally override the record class defaults. 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 Farce::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, nil) (defaults to: nil) —

    the transfer mode, or nil for the class default

  • compare_by_identity (Boolean, nil) —

    the comparison policy, or nil for the class default

See Also:



49
50
51
52
# File 'lib/farce/molecule.rb', line 49

def initialize(*, mode: nil, **)
  @mode = mode&.to_sym || self.class.default_mode
  super(*, **)
end

Instance Attribute Details

#mode ⇒ Symbol (readonly)

The default mode used to transfer values between Ractors.

Returns:

  • (Symbol)


56
57
58
# File 'lib/farce/molecule.rb', line 56

def mode
  @mode
end

Class Method Details

.default_mode ⇒ Symbol

Returns the default transfer mode for new records.

Returns:

  • (Symbol) —

    the default transfer mode for new records



35
# File 'lib/farce/molecule.rb', line 35

def self.default_mode = :copy

.define(*fields, mode: nil) ⇒ Class<Molecule>

Create a record class with defaults for newly created atoms. 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 Farce::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:

  • fields (Array<Symbol, String>) —

    the field names

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

    the default transfer mode, or nil for :copy

  • compare_by_identity (Boolean, nil) —

    the default comparison policy

Returns:



27
28
29
30
31
32
# File 'lib/farce/molecule.rb', line 27

def self.define(*fields, mode: nil, **, &)
  subclass = super(*fields, **)
  subclass.class_eval "def self.default_mode = #{mode.to_sym.inspect}", __FILE__, __LINE__ unless nil.equal?(mode)
  subclass.class_eval(&) if block_given?
  subclass
end