farce 0.0.1.alpha2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +26 -0
- data/CONTRIBUTING.md +71 -0
- data/MIT-LICENSE +20 -0
- data/README.md +1524 -0
- data/SECURITY.md +10 -0
- data/docs/benchmarks.md +185 -0
- data/docs/gems/dry-types.md +290 -0
- data/docs/gems/msgpack.md +70 -0
- data/docs/gems/ractor-shim.md +63 -0
- data/docs/modes.md +628 -0
- data/docs/scopes.md +649 -0
- data/docs/variants.md +346 -0
- data/lib/farce/_yard/internal.rb +13 -0
- data/lib/farce/_yard/macros.rb +61 -0
- data/lib/farce/_yard/ractor.rb +46 -0
- data/lib/farce/abstract/atom.rb +186 -0
- data/lib/farce/abstract/bounded_map.rb +232 -0
- data/lib/farce/abstract/collection.rb +151 -0
- data/lib/farce/abstract/concurrent_map.rb +381 -0
- data/lib/farce/abstract/counter.rb +193 -0
- data/lib/farce/abstract/duplicable_map.rb +229 -0
- data/lib/farce/abstract/exchanger.rb +26 -0
- data/lib/farce/abstract/flag.rb +71 -0
- data/lib/farce/abstract/lazy.rb +115 -0
- data/lib/farce/abstract/lease.rb +104 -0
- data/lib/farce/abstract/lease_map.rb +261 -0
- data/lib/farce/abstract/lease_pool.rb +91 -0
- data/lib/farce/abstract/lfu_map.rb +20 -0
- data/lib/farce/abstract/lru_map.rb +25 -0
- data/lib/farce/abstract/map.rb +345 -0
- data/lib/farce/abstract/molecule.rb +245 -0
- data/lib/farce/abstract/port.rb +74 -0
- data/lib/farce/abstract/priority_queue.rb +117 -0
- data/lib/farce/abstract/queue.rb +269 -0
- data/lib/farce/abstract/scheduler.rb +111 -0
- data/lib/farce/abstract/set.rb +910 -0
- data/lib/farce/abstract/sorted_set.rb +172 -0
- data/lib/farce/abstract/timer_queue.rb +136 -0
- data/lib/farce/abstract/tree_map.rb +269 -0
- data/lib/farce/abstract/value.rb +68 -0
- data/lib/farce/abstract/vector.rb +1126 -0
- data/lib/farce/abstract/weak_atom.rb +32 -0
- data/lib/farce/abstract/weak_key_map.rb +12 -0
- data/lib/farce/abstract/weak_map.rb +13 -0
- data/lib/farce/abstract/weak_set.rb +12 -0
- data/lib/farce/abstract/weak_value_map.rb +12 -0
- data/lib/farce/abstract.rb +17 -0
- data/lib/farce/atom.rb +293 -0
- data/lib/farce/class_mirror.rb +87 -0
- data/lib/farce/clock.rb +121 -0
- data/lib/farce/config.rb +229 -0
- data/lib/farce/counter.rb +71 -0
- data/lib/farce/deduper.rb +122 -0
- data/lib/farce/engine/jruby/bounded_map.rb +314 -0
- data/lib/farce/engine/jruby/fiber_scheduler.jar +0 -0
- data/lib/farce/engine/jruby/fiber_scheduler.rb +119 -0
- data/lib/farce/engine/jruby/lease_waiting.rb +19 -0
- data/lib/farce/engine/jruby/map.rb +505 -0
- data/lib/farce/engine/jruby/mutable_numeric_copy.rb +42 -0
- data/lib/farce/engine/jruby/signal.rb +147 -0
- data/lib/farce/engine/jruby.rb +63 -0
- data/lib/farce/engine/jvm/concurrent_weak_registry.rb +55 -0
- data/lib/farce/engine/jvm/counter.rb +102 -0
- data/lib/farce/engine/jvm/extension.rb +32 -0
- data/lib/farce/engine/jvm/farce.jar +0 -0
- data/lib/farce/engine/jvm/flag.rb +79 -0
- data/lib/farce/engine/jvm/priority_queue.rb +217 -0
- data/lib/farce/engine/jvm/tree_map.rb +350 -0
- data/lib/farce/engine/jvm/types.rb +180 -0
- data/lib/farce/engine/jvm.rb +19 -0
- data/lib/farce/engine/ruby/3.4/fiber_scheduler.rb +20 -0
- data/lib/farce/engine/ruby/3.4/port.rb +186 -0
- data/lib/farce/engine/ruby/3.4/ractor_methods.rb +26 -0
- data/lib/farce/engine/ruby/3.4/ractor_selector.rb +92 -0
- data/lib/farce/engine/ruby/3.4/vault.rb +56 -0
- data/lib/farce/engine/ruby/4.0/port.rb +19 -0
- data/lib/farce/engine/ruby/4.0/ractor_methods.rb +20 -0
- data/lib/farce/engine/ruby/4.0/ractor_selector.rb +108 -0
- data/lib/farce/engine/ruby/4.0/vault.rb +74 -0
- data/lib/farce/engine/ruby/4.1/port.rb +21 -0
- data/lib/farce/engine/ruby/4.1/ractor_methods.rb +22 -0
- data/lib/farce/engine/ruby/4.1/ractor_selector.rb +25 -0
- data/lib/farce/engine/ruby/4.1/vault.rb +5 -0
- data/lib/farce/engine/ruby/fiber_scheduler.rb +32 -0
- data/lib/farce/engine/ruby/key_lock_map.rb +28 -0
- data/lib/farce/engine/ruby/shared/lease.rb +26 -0
- data/lib/farce/engine/ruby/shared/lease_pool.rb +24 -0
- data/lib/farce/engine/ruby/shared/main_scheduler.rb +9 -0
- data/lib/farce/engine/ruby/shared/parallel_scheduler.rb +9 -0
- data/lib/farce/engine/ruby/shared/proxy_owner.rb +31 -0
- data/lib/farce/engine/ruby/shared/ractor_methods.rb +34 -0
- data/lib/farce/engine/ruby/shared/ractor_selector.rb +328 -0
- data/lib/farce/engine/ruby/shared/strict_map.rb +13 -0
- data/lib/farce/engine/ruby/shared/unshared_vector.rb +14 -0
- data/lib/farce/engine/ruby/shared/vault.rb +144 -0
- data/lib/farce/engine/ruby/shared/vault_weak_map.rb +336 -0
- data/lib/farce/engine/ruby/shared/weak_atom.rb +54 -0
- data/lib/farce/engine/ruby/shared/weak_map.rb +413 -0
- data/lib/farce/engine/ruby.rb +130 -0
- data/lib/farce/engine/shared/atom.rb +10 -0
- data/lib/farce/engine/shared/exchanger.rb +130 -0
- data/lib/farce/engine/shared/identity_key.rb +22 -0
- data/lib/farce/engine/shared/lease.rb +10 -0
- data/lib/farce/engine/shared/lease_pool.rb +10 -0
- data/lib/farce/engine/shared/main_scheduler.rb +20 -0
- data/lib/farce/engine/shared/map_key_coordination.rb +226 -0
- data/lib/farce/engine/shared/parallel_scheduler.rb +9 -0
- data/lib/farce/engine/shared/port.rb +44 -0
- data/lib/farce/engine/shared/portable_bounded_map.rb +619 -0
- data/lib/farce/engine/shared/proxy_owner.rb +43 -0
- data/lib/farce/engine/shared/queue.rb +233 -0
- data/lib/farce/engine/shared/ractor_methods.rb +73 -0
- data/lib/farce/engine/shared/rebindable.rb +15 -0
- data/lib/farce/engine/shared/strict_atom.rb +73 -0
- data/lib/farce/engine/shared/strict_map.rb +117 -0
- data/lib/farce/engine/shared/strict_queue_values.rb +27 -0
- data/lib/farce/engine/shared/strict_tree_map.rb +56 -0
- data/lib/farce/engine/shared/transaction_map_backend.rb +20 -0
- data/lib/farce/engine/shared/trie.rb +317 -0
- data/lib/farce/engine/shared/trie_builder.rb +199 -0
- data/lib/farce/engine/shared/unshareable.rb +14 -0
- data/lib/farce/engine/shared/unshared_atom.rb +256 -0
- data/lib/farce/engine/shared/unshared_priority_queue.rb +9 -0
- data/lib/farce/engine/shared/unshared_queue.rb +18 -0
- data/lib/farce/engine/shared/unshared_signal.rb +21 -0
- data/lib/farce/engine/shared/unshared_vector.rb +377 -0
- data/lib/farce/engine/shared/unshared_weak_atom.rb +30 -0
- data/lib/farce/engine/shared/unshared_weak_map.rb +445 -0
- data/lib/farce/engine/shared/vault.rb +31 -0
- data/lib/farce/engine/shared/vector.rb +83 -0
- data/lib/farce/engine/shared/weak_atom/base.rb +189 -0
- data/lib/farce/engine/shared/weak_atom.rb +20 -0
- data/lib/farce/engine/shared/weak_map/cell.rb +99 -0
- data/lib/farce/engine/shared/weak_map/index.rb +249 -0
- data/lib/farce/engine/shared/weak_map/lock.rb +80 -0
- data/lib/farce/engine/shared/weak_map/reference.rb +33 -0
- data/lib/farce/engine/shared.rb +63 -0
- data/lib/farce/engine/truffleruby/fiber_scheduler.rb +13 -0
- data/lib/farce/engine/truffleruby/lock.rb +121 -0
- data/lib/farce/engine/truffleruby/map.rb +656 -0
- data/lib/farce/engine/truffleruby/native/counter.rb +105 -0
- data/lib/farce/engine/truffleruby/native/flag.rb +77 -0
- data/lib/farce/engine/truffleruby/native/ordered_array_support.rb +67 -0
- data/lib/farce/engine/truffleruby/native/priority_queue.rb +388 -0
- data/lib/farce/engine/truffleruby/native/tree_map.rb +51 -0
- data/lib/farce/engine/truffleruby/native/unsafe_tree_map.rb +350 -0
- data/lib/farce/engine/truffleruby/signal.rb +77 -0
- data/lib/farce/engine/truffleruby.rb +148 -0
- data/lib/farce/envelope.rb +335 -0
- data/lib/farce/error.rb +35 -0
- data/lib/farce/exchanger.rb +41 -0
- data/lib/farce/flag.rb +27 -0
- data/lib/farce/integrations/active_support/blank.rb +68 -0
- data/lib/farce/integrations/active_support/clock.rb +17 -0
- data/lib/farce/integrations/active_support/duplicable.rb +78 -0
- data/lib/farce/integrations/active_support/map.rb +175 -0
- data/lib/farce/integrations/active_support/set.rb +60 -0
- data/lib/farce/integrations/active_support/value_serialization.rb +17 -0
- data/lib/farce/integrations/active_support/vector.rb +231 -0
- data/lib/farce/integrations/active_support.rb +9 -0
- data/lib/farce/integrations/activesupport.rb +5 -0
- data/lib/farce/integrations/bson.rb +108 -0
- data/lib/farce/integrations/cbor.rb +51 -0
- data/lib/farce/integrations/concurrent.rb +112 -0
- data/lib/farce/integrations/dry-types.rb +5 -0
- data/lib/farce/integrations/dry_types.rb +694 -0
- data/lib/farce/integrations/json.rb +7 -0
- data/lib/farce/integrations/msgpack.rb +112 -0
- data/lib/farce/integrations/oj.rb +69 -0
- data/lib/farce/integrations/psych.rb +191 -0
- data/lib/farce/integrations/ractor-sharing.rb +5 -0
- data/lib/farce/integrations/ractor-tmvar.rb +5 -0
- data/lib/farce/integrations/ractor_sharing.rb +172 -0
- data/lib/farce/integrations/ractor_tmvar.rb +64 -0
- data/lib/farce/integrations/shared/to_json.rb +42 -0
- data/lib/farce/integrations/sorted_set.rb +11 -0
- data/lib/farce/integrations/weakref.rb +38 -0
- data/lib/farce/integrations/yajl.rb +10 -0
- data/lib/farce/integrations.rb +156 -0
- data/lib/farce/internal/_frozen_config.rb +11 -0
- data/lib/farce/internal/autoloads.rb +47 -0
- data/lib/farce/internal/blocking_priority_queue.rb +122 -0
- data/lib/farce/internal/converter.rb +106 -0
- data/lib/farce/internal/copyable.rb +31 -0
- data/lib/farce/internal/delegation.rb +20 -0
- data/lib/farce/internal/external_transaction.rb +59 -0
- data/lib/farce/internal/fake_ractor.rb +179 -0
- data/lib/farce/internal/freeze.rb +118 -0
- data/lib/farce/internal/inspect.rb +157 -0
- data/lib/farce/internal/key_lock_map.rb +29 -0
- data/lib/farce/internal/key_normalizer.rb +289 -0
- data/lib/farce/internal/lease_initialization.rb +115 -0
- data/lib/farce/internal/lease_map.rb +441 -0
- data/lib/farce/internal/lease_pool_state.rb +228 -0
- data/lib/farce/internal/lease_state.rb +342 -0
- data/lib/farce/internal/lease_waiting.rb +13 -0
- data/lib/farce/internal/managed_queue.rb +26 -0
- data/lib/farce/internal/map_value_modes.rb +227 -0
- data/lib/farce/internal/marshal_support.rb +227 -0
- data/lib/farce/internal/mixin.rb +20 -0
- data/lib/farce/internal/mutable_ordered_key_lock_map.rb +63 -0
- data/lib/farce/internal/noncopyable.rb +17 -0
- data/lib/farce/internal/ordered_key_lock_map.rb +69 -0
- data/lib/farce/internal/pool_supervisor.rb +41 -0
- data/lib/farce/internal/pool_worker.rb +61 -0
- data/lib/farce/internal/portable_transaction/reservation_entry.rb +29 -0
- data/lib/farce/internal/portable_transaction/strong_map_entry.rb +137 -0
- data/lib/farce/internal/portable_transaction/strong_map_size_entry.rb +44 -0
- data/lib/farce/internal/portable_transaction/tree_entry.rb +64 -0
- data/lib/farce/internal/portable_transaction.rb +164 -0
- data/lib/farce/internal/proxy_owner_notifications.rb +29 -0
- data/lib/farce/internal/reservation_waiting.rb +24 -0
- data/lib/farce/internal/scheduled_task.rb +48 -0
- data/lib/farce/internal/scheduler_io.rb +171 -0
- data/lib/farce/internal/scheduler_lifecycle.rb +314 -0
- data/lib/farce/internal/select_scheduler.rb +235 -0
- data/lib/farce/internal/storage.rb +162 -0
- data/lib/farce/internal/strict_lease.rb +30 -0
- data/lib/farce/internal/strict_lease_map.rb +20 -0
- data/lib/farce/internal/strict_lease_pool.rb +29 -0
- data/lib/farce/internal/thread_pool.rb +166 -0
- data/lib/farce/internal/transaction_conflict.rb +9 -0
- data/lib/farce/internal/transaction_freeze_guard.rb +30 -0
- data/lib/farce/internal/transaction_map_snapshot.rb +123 -0
- data/lib/farce/internal/undefined.rb +22 -0
- data/lib/farce/internal/unshared_lease.rb +29 -0
- data/lib/farce/internal/unshared_lease_pool.rb +34 -0
- data/lib/farce/internal/unshared_queue_waiting.rb +28 -0
- data/lib/farce/internal/value_serialization.rb +13 -0
- data/lib/farce/internal/weak_map_value_modes.rb +58 -0
- data/lib/farce/internal/weak_mode_manager.rb +26 -0
- data/lib/farce/internal.rb +129 -0
- data/lib/farce/lazy.rb +100 -0
- data/lib/farce/lazy_ref.rb +40 -0
- data/lib/farce/lease.rb +28 -0
- data/lib/farce/lease_map.rb +34 -0
- data/lib/farce/lease_pool.rb +29 -0
- data/lib/farce/lfu_map.rb +53 -0
- data/lib/farce/local/atom.rb +23 -0
- data/lib/farce/local/counter.rb +88 -0
- data/lib/farce/local/flag.rb +65 -0
- data/lib/farce/local/lazy.rb +38 -0
- data/lib/farce/local/lazy_ref.rb +36 -0
- data/lib/farce/local/lease.rb +77 -0
- data/lib/farce/local/lease_map.rb +80 -0
- data/lib/farce/local/lease_pool.rb +38 -0
- data/lib/farce/local/lfu_map.rb +55 -0
- data/lib/farce/local/lru_map.rb +62 -0
- data/lib/farce/local/map.rb +47 -0
- data/lib/farce/local/molecule.rb +45 -0
- data/lib/farce/local/priority_queue.rb +53 -0
- data/lib/farce/local/queue.rb +32 -0
- data/lib/farce/local/scoped.rb +166 -0
- data/lib/farce/local/set.rb +18 -0
- data/lib/farce/local/sorted_set.rb +50 -0
- data/lib/farce/local/timer_queue.rb +41 -0
- data/lib/farce/local/tree_map.rb +47 -0
- data/lib/farce/local/vector.rb +30 -0
- data/lib/farce/local/weak_atom.rb +23 -0
- data/lib/farce/local/weak_key_map.rb +39 -0
- data/lib/farce/local/weak_map.rb +39 -0
- data/lib/farce/local/weak_set.rb +18 -0
- data/lib/farce/local/weak_value_map.rb +39 -0
- data/lib/farce/local.rb +35 -0
- data/lib/farce/lock.rb +54 -0
- data/lib/farce/lru_map.rb +63 -0
- data/lib/farce/map.rb +58 -0
- data/lib/farce/mode_manager.rb +142 -0
- data/lib/farce/molecule.rb +60 -0
- data/lib/farce/mutable.rb +171 -0
- data/lib/farce/pool.rb +332 -0
- data/lib/farce/port.rb +134 -0
- data/lib/farce/priority_queue.rb +70 -0
- data/lib/farce/proxy/register.rb +101 -0
- data/lib/farce/proxy/supervisor.rb +137 -0
- data/lib/farce/proxy/wrapper.rb +49 -0
- data/lib/farce/proxy.rb +291 -0
- data/lib/farce/queue.rb +60 -0
- data/lib/farce/ractor.rb +269 -0
- data/lib/farce/read_write_lock.rb +256 -0
- data/lib/farce/reference.rb +158 -0
- data/lib/farce/resolv/dns.rb +42 -0
- data/lib/farce/resolv.rb +85 -0
- data/lib/farce/scheduler.rb +536 -0
- data/lib/farce/set.rb +39 -0
- data/lib/farce/shareable.rb +150 -0
- data/lib/farce/signal.rb +97 -0
- data/lib/farce/sorted_set.rb +36 -0
- data/lib/farce/strict/atom.rb +34 -0
- data/lib/farce/strict/counter.rb +10 -0
- data/lib/farce/strict/exchanger.rb +25 -0
- data/lib/farce/strict/flag.rb +10 -0
- data/lib/farce/strict/lazy.rb +26 -0
- data/lib/farce/strict/lazy_ref.rb +26 -0
- data/lib/farce/strict/lease.rb +27 -0
- data/lib/farce/strict/lease_map.rb +33 -0
- data/lib/farce/strict/lease_pool.rb +28 -0
- data/lib/farce/strict/lfu_map.rb +27 -0
- data/lib/farce/strict/lru_map.rb +28 -0
- data/lib/farce/strict/map.rb +54 -0
- data/lib/farce/strict/molecule.rb +16 -0
- data/lib/farce/strict/port.rb +40 -0
- data/lib/farce/strict/priority_queue.rb +20 -0
- data/lib/farce/strict/queue.rb +17 -0
- data/lib/farce/strict/set.rb +14 -0
- data/lib/farce/strict/sorted_set.rb +19 -0
- data/lib/farce/strict/timer_queue.rb +13 -0
- data/lib/farce/strict/tree_map.rb +27 -0
- data/lib/farce/strict/vector.rb +24 -0
- data/lib/farce/strict/weak_atom.rb +31 -0
- data/lib/farce/strict/weak_key_map.rb +49 -0
- data/lib/farce/strict/weak_map.rb +49 -0
- data/lib/farce/strict/weak_set.rb +14 -0
- data/lib/farce/strict/weak_value_map.rb +48 -0
- data/lib/farce/strict.rb +28 -0
- data/lib/farce/system.rb +40 -0
- data/lib/farce/thread_scheduler.rb +70 -0
- data/lib/farce/timer_queue.rb +66 -0
- data/lib/farce/transaction/atom.rb +73 -0
- data/lib/farce/transaction/map.rb +25 -0
- data/lib/farce/transaction/map_operations.rb +143 -0
- data/lib/farce/transaction/molecule.rb +90 -0
- data/lib/farce/transaction/mutable.rb +61 -0
- data/lib/farce/transaction/set.rb +17 -0
- data/lib/farce/transaction/set_operations.rb +48 -0
- data/lib/farce/transaction/sorted_set.rb +18 -0
- data/lib/farce/transaction/tree_map.rb +78 -0
- data/lib/farce/transaction/vector.rb +139 -0
- data/lib/farce/transaction/wrapper.rb +202 -0
- data/lib/farce/transaction.rb +343 -0
- data/lib/farce/tree_map.rb +56 -0
- data/lib/farce/unsafe/lfu_map.rb +36 -0
- data/lib/farce/unsafe/lru_map.rb +36 -0
- data/lib/farce/unsafe/tree_map.rb +21 -0
- data/lib/farce/unsafe.rb +29 -0
- data/lib/farce/unshareable.rb +67 -0
- data/lib/farce/unshared/atom.rb +24 -0
- data/lib/farce/unshared/counter.rb +10 -0
- data/lib/farce/unshared/flag.rb +10 -0
- data/lib/farce/unshared/lazy.rb +38 -0
- data/lib/farce/unshared/lazy_ref.rb +26 -0
- data/lib/farce/unshared/lease.rb +27 -0
- data/lib/farce/unshared/lease_map.rb +26 -0
- data/lib/farce/unshared/lease_pool.rb +25 -0
- data/lib/farce/unshared/lfu_map.rb +20 -0
- data/lib/farce/unshared/lru_map.rb +20 -0
- data/lib/farce/unshared/map.rb +49 -0
- data/lib/farce/unshared/molecule.rb +16 -0
- data/lib/farce/unshared/priority_queue.rb +16 -0
- data/lib/farce/unshared/queue.rb +27 -0
- data/lib/farce/unshared/set.rb +14 -0
- data/lib/farce/unshared/sorted_set.rb +28 -0
- data/lib/farce/unshared/timer_queue.rb +16 -0
- data/lib/farce/unshared/tree_map.rb +21 -0
- data/lib/farce/unshared/vector.rb +19 -0
- data/lib/farce/unshared/weak_atom.rb +31 -0
- data/lib/farce/unshared/weak_key_map.rb +44 -0
- data/lib/farce/unshared/weak_map.rb +44 -0
- data/lib/farce/unshared/weak_set.rb +14 -0
- data/lib/farce/unshared/weak_value_map.rb +43 -0
- data/lib/farce/unshared.rb +28 -0
- data/lib/farce/vector.rb +228 -0
- data/lib/farce/version.rb +8 -0
- data/lib/farce/walker/definitions.rb +186 -0
- data/lib/farce/walker/modification.rb +355 -0
- data/lib/farce/walker.rb +319 -0
- data/lib/farce/weak_atom.rb +121 -0
- data/lib/farce/weak_key_map.rb +31 -0
- data/lib/farce/weak_map.rb +33 -0
- data/lib/farce/weak_ref.rb +67 -0
- data/lib/farce/weak_set.rb +82 -0
- data/lib/farce/weak_value.rb +195 -0
- data/lib/farce/weak_value_map.rb +32 -0
- data/lib/farce.rb +519 -0
- metadata +420 -0
data/docs/variants.md
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
# @title Variants
|
|
3
|
+
-->
|
|
4
|
+
|
|
5
|
+
# Variants
|
|
6
|
+
|
|
7
|
+
Most Farce classes implement a set of variants as separate subclasses within module namespaces.
|
|
8
|
+
|
|
9
|
+
These namespaces and variants are:
|
|
10
|
+
|
|
11
|
+
* **Farce**: Data containers that support both shareable and unshareable content. Unshareable content is usually handled by implementing [mode support](modes.md). Keep in mind that this is also the top level namespace for Farce in general, so it contains other classes and modules not implementing variants (including the variant namespaces themselves).
|
|
12
|
+
* **Farce::Strict**: Variants that enforce strict sharing rules. Unshareable content will be rejected.
|
|
13
|
+
* **Farce::Local**: Variants that hold concrete, independent data for each [scope](scopes.md) (i.e., one copy per ractor, thread, etc). As no scope stretches across multiple ractors, these may contain unshareable content without issue.
|
|
14
|
+
* **Farce::Unshared**: Variants that explicitly allow unshareable content. These cannot be shared across multiple ractors.
|
|
15
|
+
* **Farce::Unsafe**: Variants that aren't shareable but moreover aren't guaranteed to be thread-safe either. They only exist if they give a significant performance or usability benefit despite these limitations.
|
|
16
|
+
* **Farce::Transaction**: Variants generated by transactions.
|
|
17
|
+
|
|
18
|
+
You can choose the variant based on your needs:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
global_map = Farce::Map.new
|
|
22
|
+
local_map = Farce::Local::Map.new(scope: :thread)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
None of the namespaces define any instance methods, so they are safe to include:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
class MyClass
|
|
29
|
+
include Farce::Strict
|
|
30
|
+
|
|
31
|
+
@register = Map.new
|
|
32
|
+
@cache = LRUMap.new
|
|
33
|
+
end
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Classes implementing Variants
|
|
37
|
+
|
|
38
|
+
<table>
|
|
39
|
+
<thead>
|
|
40
|
+
<tr>
|
|
41
|
+
<th></th>
|
|
42
|
+
<th width="120" align="center" style="text-align: center">Farce</th>
|
|
43
|
+
<th width="120" align="center" style="text-align: center">Strict</th>
|
|
44
|
+
<th width="120" align="center" style="text-align: center">Local</th>
|
|
45
|
+
<th width="120" align="center" style="text-align: center">Unshared</th>
|
|
46
|
+
<th width="120" align="center" style="text-align: center">Unsafe</th>
|
|
47
|
+
<th width="120" align="center" style="text-align: center">Transaction</th>
|
|
48
|
+
</tr>
|
|
49
|
+
</thead>
|
|
50
|
+
<tbody>
|
|
51
|
+
<tr>
|
|
52
|
+
<td><tt>Atom</tt></td>
|
|
53
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
54
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
55
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
56
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
57
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
58
|
+
<td align="center" style="text-align: center">✅</td> <!-- Transaction -->
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<td><tt>Counter</tt></td>
|
|
62
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
63
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Strict -->
|
|
64
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
65
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unshared -->
|
|
66
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
67
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
68
|
+
</tr>
|
|
69
|
+
<tr>
|
|
70
|
+
<td><tt>Exchanger</tt></td>
|
|
71
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
72
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
73
|
+
<td align="center" style="text-align: center">➖</td> <!-- Local -->
|
|
74
|
+
<td align="center" style="text-align: center">➖</td> <!-- Unshared -->
|
|
75
|
+
<td align="center" style="text-align: center">➖</td> <!-- Unsafe -->
|
|
76
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
77
|
+
</tr>
|
|
78
|
+
<tr>
|
|
79
|
+
<td><tt>Flag</tt></td>
|
|
80
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
81
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Strict -->
|
|
82
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
83
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unshared -->
|
|
84
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
85
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
86
|
+
</tr>
|
|
87
|
+
<tr>
|
|
88
|
+
<td><tt>Lazy</tt></td>
|
|
89
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
90
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
91
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
92
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
93
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
94
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
95
|
+
</tr>
|
|
96
|
+
<tr>
|
|
97
|
+
<td><tt>LazyRef</tt></td>
|
|
98
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
99
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
100
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
101
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
102
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
103
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
104
|
+
</tr>
|
|
105
|
+
<tr>
|
|
106
|
+
<td><tt>Lease</tt></td>
|
|
107
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
108
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
109
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
110
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
111
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
112
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
113
|
+
</tr>
|
|
114
|
+
<tr>
|
|
115
|
+
<td><tt>LeaseMap</tt></td>
|
|
116
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
117
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
118
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
119
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
120
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
121
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
122
|
+
</tr>
|
|
123
|
+
<tr>
|
|
124
|
+
<td><tt>LeasePool</tt></td>
|
|
125
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
126
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
127
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
128
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
129
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
130
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
131
|
+
</tr>
|
|
132
|
+
<tr>
|
|
133
|
+
<td><tt>LFUMap</tt></td>
|
|
134
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
135
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
136
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
137
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
138
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unsafe -->
|
|
139
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
140
|
+
</tr>
|
|
141
|
+
<tr>
|
|
142
|
+
<td><tt>LRUMap</tt></td>
|
|
143
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
144
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
145
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
146
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
147
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unsafe -->
|
|
148
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
149
|
+
</tr>
|
|
150
|
+
<tr>
|
|
151
|
+
<td><tt>Molecule</tt></td>
|
|
152
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
153
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
154
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
155
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
156
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
157
|
+
<td align="center" style="text-align: center">✅</td> <!-- Transaction -->
|
|
158
|
+
</tr>
|
|
159
|
+
<tr>
|
|
160
|
+
<td><tt>Map</tt></td>
|
|
161
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
162
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
163
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
164
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
165
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
166
|
+
<td align="center" style="text-align: center">✅</td> <!-- Transaction -->
|
|
167
|
+
</tr>
|
|
168
|
+
<tr>
|
|
169
|
+
<td><tt>Mutable</tt></td>
|
|
170
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
171
|
+
<td align="center" style="text-align: center">➖</td> <!-- Strict -->
|
|
172
|
+
<td align="center" style="text-align: center">➖</td> <!-- Local -->
|
|
173
|
+
<td align="center" style="text-align: center">➖</td> <!-- Unshared -->
|
|
174
|
+
<td align="center" style="text-align: center">➖</td> <!-- Unsafe -->
|
|
175
|
+
<td align="center" style="text-align: center">✅</td> <!-- Transaction -->
|
|
176
|
+
</tr>
|
|
177
|
+
<tr>
|
|
178
|
+
<td><tt>Port</tt></td>
|
|
179
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
180
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
181
|
+
<td align="center" style="text-align: center">➖</td> <!-- Local -->
|
|
182
|
+
<td align="center" style="text-align: center">➖</td> <!-- Unshared -->
|
|
183
|
+
<td align="center" style="text-align: center">➖</td> <!-- Unsafe -->
|
|
184
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
185
|
+
</tr>
|
|
186
|
+
<tr>
|
|
187
|
+
<td><tt>PriorityQueue</tt></td>
|
|
188
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
189
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
190
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
191
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
192
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
193
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
194
|
+
</tr>
|
|
195
|
+
<tr>
|
|
196
|
+
<td><tt>Queue</tt></td>
|
|
197
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
198
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
199
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
200
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
201
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
202
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
203
|
+
</tr>
|
|
204
|
+
<tr>
|
|
205
|
+
<td><tt>Set</tt></td>
|
|
206
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
207
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
208
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
209
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
210
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
211
|
+
<td align="center" style="text-align: center">✅</td> <!-- Transaction -->
|
|
212
|
+
</tr>
|
|
213
|
+
<tr>
|
|
214
|
+
<td><tt>SortedSet</tt></td>
|
|
215
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
216
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
217
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
218
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
219
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
220
|
+
<td align="center" style="text-align: center">✅</td> <!-- Transaction -->
|
|
221
|
+
</tr>
|
|
222
|
+
<tr>
|
|
223
|
+
<td><tt>TimerQueue</tt></td>
|
|
224
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
225
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
226
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
227
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
228
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
229
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
230
|
+
</tr>
|
|
231
|
+
<tr>
|
|
232
|
+
<td><tt>TreeMap</tt></td>
|
|
233
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
234
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
235
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
236
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
237
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unsafe -->
|
|
238
|
+
<td align="center" style="text-align: center">✅</td> <!-- Transaction -->
|
|
239
|
+
</tr>
|
|
240
|
+
<tr>
|
|
241
|
+
<td><tt>Vector</tt></td>
|
|
242
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
243
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
244
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
245
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
246
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
247
|
+
<td align="center" style="text-align: center">✅</td> <!-- Transaction -->
|
|
248
|
+
</tr>
|
|
249
|
+
<tr>
|
|
250
|
+
<td><tt>WeakAtom</tt></td>
|
|
251
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
252
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
253
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
254
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
255
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
256
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
257
|
+
</tr>
|
|
258
|
+
<tr>
|
|
259
|
+
<td><tt>WeakKeyMap</tt></td>
|
|
260
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
261
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
262
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
263
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
264
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
265
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
266
|
+
</tr>
|
|
267
|
+
<tr>
|
|
268
|
+
<td><tt>WeakMap</tt></td>
|
|
269
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
270
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
271
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
272
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
273
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
274
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
275
|
+
</tr>
|
|
276
|
+
<tr>
|
|
277
|
+
<td><tt>WeakSet</tt></td>
|
|
278
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
279
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
280
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
281
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
282
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
283
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
284
|
+
</tr>
|
|
285
|
+
<tr>
|
|
286
|
+
<td><tt>WeakValueMap</tt></td>
|
|
287
|
+
<td align="center" style="text-align: center">✅</td> <!-- Farce -->
|
|
288
|
+
<td align="center" style="text-align: center">✅</td> <!-- Strict -->
|
|
289
|
+
<td align="center" style="text-align: center">✅</td> <!-- Local -->
|
|
290
|
+
<td align="center" style="text-align: center">✅</td> <!-- Unshared -->
|
|
291
|
+
<td align="center" style="text-align: center">🔗</td> <!-- Unsafe -->
|
|
292
|
+
<td align="center" style="text-align: center">➖</td> <!-- Transaction -->
|
|
293
|
+
</tr>
|
|
294
|
+
</tbody>
|
|
295
|
+
</table>
|
|
296
|
+
|
|
297
|
+
Legend:
|
|
298
|
+
* ✅ Defined
|
|
299
|
+
* ➖ Not defined
|
|
300
|
+
* 🔗 Alias for another variant
|
|
301
|
+
|
|
302
|
+
## Classes without Variants
|
|
303
|
+
|
|
304
|
+
When using the variant namespaces interchangeably, keep in mind that some classes do not come with variants.
|
|
305
|
+
|
|
306
|
+
This is obvious for classes that aren't data containers, like `Signal` or `Lock`, but also include classes like `Envelope` and `Scheduler`, which support modes, and `WeakValue` and `WeakRef`, which will choose (and switch) between the correct `WeakAtom` variants automatically.
|
|
307
|
+
|
|
308
|
+
## Abstract Classes and Modules
|
|
309
|
+
|
|
310
|
+
Classes with variants will typically have at least one abstract class or module that they implement.
|
|
311
|
+
This is helpful for type checking and as a possible extension point, while doing a better job at substitution.
|
|
312
|
+
|
|
313
|
+
For example, `Farce::Map` subclasses should all implement mode support, but the same cannot be said for all `Farce::Abstract::Map` subclasses.
|
|
314
|
+
|
|
315
|
+
This makes type checking easy:
|
|
316
|
+
|
|
317
|
+
```ruby
|
|
318
|
+
def self.increment_counter(counter)
|
|
319
|
+
case counter
|
|
320
|
+
when Farce::Abstract::Counter then counter.increment
|
|
321
|
+
when Ratomic::Counter then counter.increment(1) # required argument
|
|
322
|
+
else raise "Unsupported counter type"
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
counter = Farce::Counter.new
|
|
327
|
+
increment_counter(counter)
|
|
328
|
+
|
|
329
|
+
counter = Farce::Local::Counter.new(scope: :fiber)
|
|
330
|
+
increment_counter(counter)
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Abstract classes may in turn have abstract subclasses to group functionality. For instance, all `PriorityQueue` variants inherit from `Farce::Abstract::PriorityQueue`, which in turn is a subclass of `Farce::Abstract::Queue`.
|
|
334
|
+
|
|
335
|
+
A noticeably more complex abstract hierarchy exists for maps:
|
|
336
|
+
|
|
337
|
+
* `Farce::Abstract::Map`: Superclass for all map variants. Contains the almost complete set of Hash-compatible methods, as well as some additional methods like `store_if_absent`.
|
|
338
|
+
* `Farce::Abstract::ConcurrentMap`: Superclass for maps with an extended concurrency API, including `Farce::Map` and its variants.
|
|
339
|
+
* `Farce::Abstract::WeakMap`: Superclass for all `WeakMap` variants.
|
|
340
|
+
* `Farce::Abstract::WeakKeyMap`: Superclass for all `WeakKeyMap` variants.
|
|
341
|
+
* `Farce::Abstract::WeakValueMap`: Superclass for all `WeakValueMap` variants.
|
|
342
|
+
* `Farce::Abstract::BoundedMap`: Superclass for all map variants with an enforced size limit. All current variants enforce this limit via eviction, but a subclass rejecting writes could be a valid implementation.
|
|
343
|
+
* `Farce::Abstract::LFUMap`: Superclass for all Least Frequently Used (LFU) map variants.
|
|
344
|
+
* `Farce::Abstract::LRUMap`: Superclass for all Least Recently Used (LRU) map variants.
|
|
345
|
+
* `Farce::Abstract::LeaseMap`: Superclass for all `LeaseMap` variants.
|
|
346
|
+
* `Farce::Abstract::TreeMap`: Superclass for all `TreeMap` variants.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# @!macro unsafe
|
|
2
|
+
# @note
|
|
3
|
+
# Instances of this class are **not thread-safe** and should not be shared concurrently.
|
|
4
|
+
# This does not just apply to Ractors, but also Threads and possibly Fibers.
|
|
5
|
+
#
|
|
6
|
+
# Only use them if you are absolutely certain of this and they do not leave a tightly controlled scope.
|
|
7
|
+
# They can provide a memory or performance advantage over their thread-safe counterparts, so they
|
|
8
|
+
# might be useful for hot path optimizations.
|
|
9
|
+
#
|
|
10
|
+
# Concurrent access, especially modifications, may corrupt the internal state of the object.
|
|
11
|
+
|
|
12
|
+
# @!macro modes
|
|
13
|
+
# Valid modes are:
|
|
14
|
+
# * `:copy` - The value will be copied between Ractors. This is the default mode.
|
|
15
|
+
# * `:make_shareable` - The value will be made Ractor-shareable using {Ractor.make_shareable}.
|
|
16
|
+
# * `:move` - The value will be moved between Ractors. This saves memory compared to copying, and supports values
|
|
17
|
+
# that can't be copied but moved (like IO objects). However, the value will no longer be accessible on the Ractor
|
|
18
|
+
# that pushed it.
|
|
19
|
+
# * `:mutable` - A {Farce::Mutable} instance will be created for the value. This isn't done recursively and thus will fail for nested unshareable values.
|
|
20
|
+
# * `:local` - The value will be kept local to the Ractor that pushed it. Another ractor trying to receive it will
|
|
21
|
+
# get an error. Useful for usage contained within a single Ractor.
|
|
22
|
+
# * `:proxy` - The value will be wrapped in a `Farce::Proxy` that executes calls in the original Ractor.
|
|
23
|
+
# * `:raise` - An error will be raised if the value is not Ractor-shareable. Useful for enforcing shareability.
|
|
24
|
+
# * `:dedup` - The value will be deduplicated using {Farce.dedup}, then made Ractor-shareable.
|
|
25
|
+
# This may update and freeze the original. Already-shareable values pass through unchanged.
|
|
26
|
+
# * `:shareable_copy` - The value will be copied and the copy will be made Ractor-shareable.
|
|
27
|
+
|
|
28
|
+
# @!macro scopes
|
|
29
|
+
# Valid scopes are:
|
|
30
|
+
# * `:ractor` - The value is shared by all threads within the same Ractor.
|
|
31
|
+
# * `:thread_group` - The value is shared by all threads within the same thread group.
|
|
32
|
+
# * `:thread` - The value is shared by all fibers within the same thread.
|
|
33
|
+
# * `:fiber_storage` - The value is shared by all fibers using the same storage.
|
|
34
|
+
# Unless explicitly specified, storage is inherited from the parent fiber for blocking fibers,
|
|
35
|
+
# but not for non-blocking fibers (such as those created by {Scheduler#schedule}).
|
|
36
|
+
# * `:fiber` - Each fiber has its own independent value.
|
|
37
|
+
|
|
38
|
+
# @!macro key_normalization
|
|
39
|
+
# @param normalize_keys [Symbol, Proc, Hash, Farce::Abstract::Map, nil]
|
|
40
|
+
# Converts incoming keys to their canonical stored form:
|
|
41
|
+
# * If a `Symbol` is provided, it will be used as a method name to call on each key.
|
|
42
|
+
# * If a `Proc` is provided, it will be called with each key and should return the normalized key.
|
|
43
|
+
# * If a `Hash` or {Farce::Abstract::Map Map} is provided, it will be used to look up the normalized key for each incoming key.
|
|
44
|
+
|
|
45
|
+
# @!macro map_initialization
|
|
46
|
+
# Create a map with optional initial entries.
|
|
47
|
+
# @param initial_mapping [Hash, Farce::Abstract::Map, #each, nil]
|
|
48
|
+
# The entries to store initially. Each iteration must yield a key-value pair.
|
|
49
|
+
# Nil creates an empty map.
|
|
50
|
+
# @!macro key_normalization
|
|
51
|
+
# @param compare_by_identity [Boolean]
|
|
52
|
+
# The default identity-comparison setting for keys and values. Defaults to false.
|
|
53
|
+
# @param compare_keys_by_identity [Boolean]
|
|
54
|
+
# Whether keys use object identity instead of `hash` and `eql?`.
|
|
55
|
+
# Defaults to `compare_by_identity`.
|
|
56
|
+
# @param compare_values_by_identity [Boolean]
|
|
57
|
+
# Whether values use object identity instead of `==`.
|
|
58
|
+
# Defaults to `compare_by_identity`.
|
|
59
|
+
|
|
60
|
+
# @!macro active_support
|
|
61
|
+
# @note This methods is only available if ActiveSupport has been loaded.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
return if true
|
|
2
|
+
|
|
3
|
+
# @!visibility private
|
|
4
|
+
class Ractor
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module Farce
|
|
8
|
+
module Ractor
|
|
9
|
+
# Either `Ractor::Port` or a shim for it. It is recommended to use {Farce::Port Farce::Port} instead,
|
|
10
|
+
# which will always be a subclass of this class, but has added safety and functionality.
|
|
11
|
+
class Port
|
|
12
|
+
# Closes the port. Sending to a closed port is prohibited. Receiving is also prohibited if there are no
|
|
13
|
+
# messages in its message queue. Only the Ractor which created the port is allowed to close it.
|
|
14
|
+
# @return [void]
|
|
15
|
+
def close = super
|
|
16
|
+
|
|
17
|
+
# Checks it the port is closed.
|
|
18
|
+
# @return [Boolean] `true` if the port is closed, `false` otherwise.
|
|
19
|
+
# @see #close
|
|
20
|
+
def closed? = super
|
|
21
|
+
|
|
22
|
+
# @overload receive
|
|
23
|
+
# Receives a message from the port.
|
|
24
|
+
# @return [BasicObject] The received message.
|
|
25
|
+
# @overload receive(timeout: nil)
|
|
26
|
+
# Receives a message from the port. Blocks until a message is available or the timeout is reached.
|
|
27
|
+
# @note
|
|
28
|
+
# Use {Farce::Port Farce::Port} instead to guarantee a timeout argument on all Ruby implementations.
|
|
29
|
+
# @ruby CRuby 4.1+, JRuby, TruffleRuby
|
|
30
|
+
# @param timeout [Numeric, nil] The timeout in seconds, or `nil` for no timeout.
|
|
31
|
+
# @return [BasicObject, nil] The received message, or `nil` if the timeout has been reached.
|
|
32
|
+
#
|
|
33
|
+
# @return [BasicObject]
|
|
34
|
+
# @raise [Farce::Ractor::ClosedError] if the port is closed and there are no messages in the queue.
|
|
35
|
+
def receive = super
|
|
36
|
+
|
|
37
|
+
# Sends a message over the port.
|
|
38
|
+
# @param message [BasicObject] The message to send.
|
|
39
|
+
# @param move [Boolean] Whether to move the message to the Ractor if it isn't sharable.
|
|
40
|
+
# @return [self]
|
|
41
|
+
# @raise [Farce::Ractor::ClosedError] if the port is closed.
|
|
42
|
+
def send(message, move: false) = super
|
|
43
|
+
alias << send
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
module Abstract
|
|
7
|
+
# @abstract Common interface and behavior for atomic references.
|
|
8
|
+
#
|
|
9
|
+
# Concrete implementations decide how values are retained and transferred.
|
|
10
|
+
# A value may become `nil` without an explicit update when an implementation
|
|
11
|
+
# retains it weakly.
|
|
12
|
+
class Atom
|
|
13
|
+
include Internal::MarshalSupport::Atom
|
|
14
|
+
include Internal::Copyable
|
|
15
|
+
include Internal::Inspect
|
|
16
|
+
include Value
|
|
17
|
+
include Internal::ValueSerialization
|
|
18
|
+
|
|
19
|
+
# @api private
|
|
20
|
+
def transaction_wrapper(transaction) = Transaction::Atom.new(transaction, self, internal_atom)
|
|
21
|
+
|
|
22
|
+
# Whether comparisons use object identity instead of equality.
|
|
23
|
+
# @return [Boolean]
|
|
24
|
+
def compare_by_identity? = internal_atom.compare_by_identity?
|
|
25
|
+
|
|
26
|
+
# Return the current value without waiting for an update in progress.
|
|
27
|
+
# @return [BasicObject, nil] the current value
|
|
28
|
+
def value = internal_atom.value
|
|
29
|
+
|
|
30
|
+
# Store a new value.
|
|
31
|
+
# @param new_value [BasicObject, nil] the new value
|
|
32
|
+
# @return [BasicObject, nil] the new value
|
|
33
|
+
def value=(new_value)
|
|
34
|
+
store(new_value)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Return the current value, waiting for any update in progress.
|
|
38
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
39
|
+
# @yield called when the timeout expires
|
|
40
|
+
# @return [BasicObject, nil] the current value or the fallback result
|
|
41
|
+
def get(timeout: nil, &) = internal_atom.get(timeout:, &)
|
|
42
|
+
|
|
43
|
+
# Store a new value, waiting for any update in progress.
|
|
44
|
+
# @param new_value [BasicObject, nil] the new value
|
|
45
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
46
|
+
# @yield called when the timeout expires
|
|
47
|
+
# @return [BasicObject, nil] the stored value or the fallback result
|
|
48
|
+
def store(new_value, timeout: nil, &) = internal_atom.store(new_value, timeout:, &)
|
|
49
|
+
|
|
50
|
+
# Replace the current value and return the previous value.
|
|
51
|
+
# @param new_value [BasicObject, nil] the new value
|
|
52
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
53
|
+
# @yield called when the timeout expires
|
|
54
|
+
# @return [BasicObject, nil] the previous value or the fallback result
|
|
55
|
+
def swap(new_value, timeout: nil, &) = internal_atom.swap(new_value, timeout:, &)
|
|
56
|
+
|
|
57
|
+
# Compute and store a value if the current value is nil.
|
|
58
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
59
|
+
# @yield computes the value to store when the current value is nil
|
|
60
|
+
# @yieldreturn [BasicObject, nil] the value to store
|
|
61
|
+
# @return [BasicObject, nil] the current or newly stored value, or nil when the timeout expires
|
|
62
|
+
def store_if_absent(timeout: nil, &) = internal_atom.store_if_absent(timeout:, &)
|
|
63
|
+
|
|
64
|
+
# Atomically replace the current value if it matches the expected value.
|
|
65
|
+
# @param expected [BasicObject, nil] the value to compare with the current value
|
|
66
|
+
# @param new_value [BasicObject, nil] the replacement value
|
|
67
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
68
|
+
# @return [Boolean] whether the value was replaced
|
|
69
|
+
def compare_and_set(expected, new_value, timeout: nil)
|
|
70
|
+
internal_atom.compare_and_set(expected, new_value, timeout:)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Atomically replace the current value with the result of a block.
|
|
74
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
75
|
+
# @yield receives the current value and computes its replacement
|
|
76
|
+
# @yieldparam current [BasicObject, nil] the current value
|
|
77
|
+
# @yieldreturn [BasicObject, nil] the replacement value
|
|
78
|
+
# @return [BasicObject, nil] the replacement value, or nil when the timeout expires
|
|
79
|
+
def update(timeout: nil, &) = internal_atom.update(timeout:, &)
|
|
80
|
+
|
|
81
|
+
# Store an initial value if the current value is nil, otherwise replace it with the result of a block.
|
|
82
|
+
# @param initial_value [BasicObject, nil] the value to store when the current value is nil
|
|
83
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
84
|
+
# @yield receives a non-nil current value and computes its replacement
|
|
85
|
+
# @yieldparam current [BasicObject] the current value
|
|
86
|
+
# @yieldreturn [BasicObject, nil] the replacement value
|
|
87
|
+
# @return [BasicObject, nil] the replacement or initial value, or nil when the timeout expires
|
|
88
|
+
def upsert(initial_value, timeout: nil, &) = internal_atom.upsert(initial_value, timeout:, &)
|
|
89
|
+
|
|
90
|
+
# Wait until a block condition matches the current value.
|
|
91
|
+
# One timeout budget covers all checks and waits. The block is not interrupted.
|
|
92
|
+
# @yieldparam value [BasicObject, nil] the current value
|
|
93
|
+
# @yieldreturn [Boolean] whether the value matches
|
|
94
|
+
# @param timeout [Numeric, nil] the total seconds available
|
|
95
|
+
# @return [BasicObject, nil] the matching value, or nil on timeout
|
|
96
|
+
# @raise [LocalJumpError] if no block is given
|
|
97
|
+
def wait_until(timeout: nil, &) = Internal.wait_until(self, timeout:, &)
|
|
98
|
+
|
|
99
|
+
# Wait while the block returns a truthy value.
|
|
100
|
+
# @yieldparam value [BasicObject, nil] the current value
|
|
101
|
+
# @yieldreturn [BasicObject] a truthy value to keep waiting, or nil or false to stop
|
|
102
|
+
# @param timeout [Numeric, nil] the total seconds available
|
|
103
|
+
# @return [BasicObject, nil] the value when the condition becomes false, or nil on timeout
|
|
104
|
+
# @raise [LocalJumpError] if no block is given
|
|
105
|
+
def wait_while(timeout: nil)
|
|
106
|
+
raise LocalJumpError, "no block given" unless block_given?
|
|
107
|
+
wait_until(timeout:) { |value| !yield(value) }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Wait while `object === value` is true.
|
|
111
|
+
# @param object [#===] the pattern to stop matching
|
|
112
|
+
# @param timeout [Numeric, nil] the total seconds available
|
|
113
|
+
# @return [BasicObject, nil] the first nonmatching value, or nil on timeout
|
|
114
|
+
def wait_while_match(object, timeout: nil)
|
|
115
|
+
wait_while(timeout:) { |value| object === value } # rubocop:disable Style/CaseEquality
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# (see #wait_until_changed)
|
|
119
|
+
def wait_while_value(...) = wait_until_changed(...)
|
|
120
|
+
|
|
121
|
+
# Wait until the current value equals an object using the configured comparison mode.
|
|
122
|
+
# @param object [BasicObject, nil] the value to compare with the current value
|
|
123
|
+
# @param timeout [Numeric, nil] the total seconds available
|
|
124
|
+
# @return [BasicObject, nil] the matching value, or nil on timeout
|
|
125
|
+
def wait_until_value(object, timeout: nil)
|
|
126
|
+
wait_until(timeout:) { |value| compare_by_identity? ? object.equal?(value) : object == value }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Wait until `object === value` is true.
|
|
130
|
+
# @param object [#===] the pattern to match
|
|
131
|
+
# @param timeout [Numeric, nil] the total seconds available
|
|
132
|
+
# @return [BasicObject, nil] the matching value, or nil on timeout
|
|
133
|
+
def wait_until_match(object, timeout: nil)
|
|
134
|
+
wait_until(timeout:) { |value| object === value } # rubocop:disable Style/CaseEquality
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Wait until the current value no longer matches an expected value.
|
|
138
|
+
# @param expected [BasicObject, nil] the value to compare with the current value
|
|
139
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
140
|
+
# @yield called when the timeout expires
|
|
141
|
+
# @return [BasicObject, nil] the changed value or the fallback result
|
|
142
|
+
def wait_until_changed(expected, timeout: nil, &)
|
|
143
|
+
internal_atom.wait_until_changed(expected, timeout:, &)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Wait until the current value is not nil.
|
|
147
|
+
# @param timeout [Numeric, nil] the maximum number of seconds to wait
|
|
148
|
+
# @yield called when the timeout expires
|
|
149
|
+
# @return [BasicObject, nil] the non-nil value or the fallback result
|
|
150
|
+
def wait_until_non_nil(timeout: nil, &) = internal_atom.wait_until_non_nil(timeout:, &)
|
|
151
|
+
|
|
152
|
+
# @api private
|
|
153
|
+
def inspect_with(inspector)
|
|
154
|
+
super do
|
|
155
|
+
yield if block_given?
|
|
156
|
+
inspect_value(inspector)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
protected
|
|
161
|
+
|
|
162
|
+
def internal_atom = @atom
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
def inspect_value(inspector, prefix = "value=")
|
|
167
|
+
if prefix
|
|
168
|
+
inspector.breakable
|
|
169
|
+
inspector.text(prefix)
|
|
170
|
+
end
|
|
171
|
+
inspector.object(value)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def initialize_copy(other)
|
|
175
|
+
super
|
|
176
|
+
source = other.internal_atom
|
|
177
|
+
copy = source.class.new(source.value, compare_by_identity: source.compare_by_identity?)
|
|
178
|
+
if is_a?(Local::Scoped)
|
|
179
|
+
Internal::Storage.scope(scope)[self] = copy
|
|
180
|
+
else
|
|
181
|
+
@atom = copy
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|