Utilities and Custom Classes
Farce provides helpers for converting object graphs, sharing custom classes, timing work, and coordinating access to values. Use these when adapting an existing library or building your own concurrency tools.
Top Level Methods
Farce.clockreturns the monotonic clock time in seconds as a Float.Farce.configreturns the global configuration object.Farce.configureallows you to configure Farce.Farce.dedupde-duplicates the given object based on a deduplication cache shared by all Ractors.Farce.enfarceturns a vanilla data structure into its Farce equivalent.Farce.freeze_graphrecursively freezes an object graph.Farce.in_parallel,Farce.on_main, andFarce.schedule, see Scheduling CodeFarce.rebindrebinds a proc or lambda while preserving its Ractor-shareability.Farce.transactioncreates and runs a transaction.
Some examples:
a = { a: [+"b"] }
b = { a: [+"b"] }
# Farce.clock
Farce.clock # => 0.017476999908685684
Farce.clock(in: 10) # => 10.017520000003278
# Farce.dedup
a.equal? b # => false
Farce.dedup(a).equal? Farce.dedup(b) # => true
# Farce.enfarce
Farce.enfarce(a) # => #<Farce::Map {a: #<Farce::Vector ["b"]>}>
Farce::Strict.enfarce(a) # => #<Farce::Strict::Map {a: #<Farce::Strict::Vector ["b"]>}>
# Farce.freeze_graph
Farce.freeze_graph(a)
# Farce.rebind
callback = ->(add) { self + add }
rebound = Farce.rebind(callback, self: 42)
rebound.call(18) # => 60
Additional Classes
Other classes Farce provides include:
Config: Configuration class, see Third-Party Fiber Schedulers example.ClassMirror: inheritance-aware registry for classesClock: Timing functions based on a monotonic clock rather than onTime.Deduper: Create your own deduplication cache. Direct usage isn't recommended, useFarce.dedupinstead.Exchanger: A synchronization point for two-way data swapping between Threads, Ractors, and/or Fibers. Drop-in replacement for concurrent-ruby's exchanger.Extension: Defines extensions for existing classes that can either be activated globally or used as refinements.Lazy: Lazily initialized value.LazyRef: A reference for a lazily initialized value.ThreadExecutor: A task executor creating a new thread for each unit of work. Used on TruffleRuby.Walker: A tool for walking a Ruby object tree.WeakValue: A value object version ofWeakRef. Allows handling references more explicitly, without automatic method delegation.Strict::WeakCache: Ractor-shared weak maps are slow on CRuby before 4.1.WeakCacheprovides a faster alternative if entries aren't frequently garbage collected, but it does not allow deleting or replacing entries manually.
In addition, Farce includes a range of error classes not listed here. Check the API documentation or code base for these.
Shareability Mixins
Farce includes mixins to help you make your custom classes shareable:
Shareableautomatically marks objects as shareable (viaRactor.make_shareable) after initialization.Shareable::Delegateddelegatesfreezeandfrozen?to another object holding your object's state.Shareable::Immutableinstances are always immutable, being frozen after initialization.Shareable::Nativeis for objects implemented in a native extension, which allows setting the frozen and shareable state separately.Shareable::Trackedfor objects implementing frozen tracking (via an internal flag).Shareable::Unfreezablefor objects that cannot be frozen (like queues).
And also mixins to prevent them from being shareable:
Unshareable: Instances aren't shareable and cannot be made shareable. By default, they also cannot be copied or moved between Ractors.Unshareable::Copyable: Instances aren't shareable but may be copied to another Ractor.Unshareable::Movable: Instances aren't shareable but may be moved to another Ractor.
Unshareable::Copyable and Unshareable::Movable may be combined.
Memoization
Farce::Memoize offers Ractor-friendly memoization:
class MyClass
include Farce::Memoize
# Memoize #expensive_method, shared across Ractors
memoize def expensive_method = expensive_computation
# Memoize #method_with_unsharable_value for each Ractor separately
def method_with_unsharable_value = unsharable_computation
memoize :method_with_unsharable_value, scope: :ractor
private
# The memoized method will also be private
memoize def private_method = expensive_computation
end
Or as a one-liner:
class MyClass
# Memoize return values of #foo and #bar until they get garbage collected
include Farce::Memoize[:foo, :bar, weak: true]
end
Constants
Farce::MODES: List of supported sharing modes.Farce::NULL_PORT: A specialRactor::Portthat acts as a sink for messages and never closes.Farce::SCOPES: List of provided scopes.Farce::VERSION: The current version.