farce 0.0.1.alpha2-x86_64-linux-gnu
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/ext/ext_helper.rb +20 -0
- data/ext/farce/README.md +21 -0
- data/ext/farce/atom.c +1023 -0
- data/ext/farce/bounded_map.c +1683 -0
- data/ext/farce/containers.h +77 -0
- data/ext/farce/counter.c +399 -0
- data/ext/farce/darwin.c +100 -0
- data/ext/farce/depend +12 -0
- data/ext/farce/dict.c +1523 -0
- data/ext/farce/dict.h +152 -0
- data/ext/farce/drivers.c +237 -0
- data/ext/farce/exchanger.c +299 -0
- data/ext/farce/extconf.rb +99 -0
- data/ext/farce/farce.c +359 -0
- data/ext/farce/flag.c +288 -0
- data/ext/farce/io.c +338 -0
- data/ext/farce/lock.c +510 -0
- data/ext/farce/map.c +2240 -0
- data/ext/farce/priority_queue.c +2056 -0
- data/ext/farce/queue.c +1059 -0
- data/ext/farce/reactor.c +820 -0
- data/ext/farce/reactor.h +103 -0
- data/ext/farce/shareable.h +31 -0
- data/ext/farce/signal.c +350 -0
- data/ext/farce/transaction.c +354 -0
- data/ext/farce/transaction.h +40 -0
- data/ext/farce/tree_map.c +1953 -0
- data/ext/farce/trie.c +2020 -0
- data/ext/farce/unshareable.c +155 -0
- data/ext/farce/unshared_io_pool.h +234 -0
- data/ext/farce/unshared_signal.c +263 -0
- data/ext/farce/unshared_wait.h +193 -0
- data/ext/farce/unsupported.c +6 -0
- data/ext/farce/vector.c +1195 -0
- data/ext/farce/weak_map.c +1714 -0
- data/ext/java/org/farce/BoundedMap.java +394 -0
- data/ext/java/org/farce/FiberScheduler.java +141 -0
- data/ext/java/org/farce/PriorityKey.java +45 -0
- data/ext/java/org/farce/PriorityQueue.java +373 -0
- data/ext/java/org/farce/QueueSignal.java +28 -0
- data/ext/rebind/README.md +14 -0
- data/ext/rebind/extconf.rb +10 -0
- data/ext/rebind/rebind.c +186 -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/farce.so +0 -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/rebind.so +0 -0
- data/lib/farce/engine/ruby/3.4/vault.rb +56 -0
- data/lib/farce/engine/ruby/4.0/farce.so +0 -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/rebind.so +0 -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 +468 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# An envelope can be used to wrap an unshareable value in a shareable object.
|
|
7
|
+
#
|
|
8
|
+
# Once created, the envelope can be shared between Ractors without any objects being moved or copied until the
|
|
9
|
+
# envelope is opened.
|
|
10
|
+
#
|
|
11
|
+
# When a Ractor attempts to open an envelope, it attempts "claim" it. Some envelopes may only be claimed by a single
|
|
12
|
+
# Ractor, others can be claimed by any Ractor. Claims cannot be taken back.
|
|
13
|
+
#
|
|
14
|
+
# @!method claim
|
|
15
|
+
# Attempts to claim the envelope for the current Ractor.
|
|
16
|
+
# @return [Envelope, nil]
|
|
17
|
+
# The envelope if the claim was successful, or `nil` if the envelope has already been claimed by another Ractor.
|
|
18
|
+
#
|
|
19
|
+
# @!method claimed?
|
|
20
|
+
# @return [Boolean] `true` if the envelope has been claimed by any Ractor, `false` otherwise.
|
|
21
|
+
#
|
|
22
|
+
# @!method owned?
|
|
23
|
+
# @return [Boolean] `true` if the envelope has been claimed by the current Ractor, `false` otherwise.
|
|
24
|
+
class Envelope
|
|
25
|
+
include Internal::Noncopyable
|
|
26
|
+
include Internal::Inspect
|
|
27
|
+
|
|
28
|
+
VAULT_ATOM = Internal::Atom.new
|
|
29
|
+
private_constant :VAULT_ATOM
|
|
30
|
+
|
|
31
|
+
include Shareable
|
|
32
|
+
include Abstract::Value
|
|
33
|
+
|
|
34
|
+
# Raised when trying to claim an envelope that has already been claimed by another Ractor.
|
|
35
|
+
AlreadyClaimed = Class.new(Ractor::IsolationError)
|
|
36
|
+
|
|
37
|
+
module Copyable
|
|
38
|
+
include Internal::Copyable
|
|
39
|
+
|
|
40
|
+
define_method(:dup, Object.instance_method(:dup))
|
|
41
|
+
define_method(:clone, Object.instance_method(:clone))
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def initialize_copy(other)
|
|
46
|
+
Object.instance_method(:initialize_copy).bind_call(self, other)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
private_constant :Copyable
|
|
50
|
+
|
|
51
|
+
# An envelope that copies its contents. Can be opened by multiple Ractors.
|
|
52
|
+
# The value will be copied once when the envelope is created, and then once per Ractor that opens the envelope.
|
|
53
|
+
#
|
|
54
|
+
# @!method new(value)
|
|
55
|
+
# @!scope class
|
|
56
|
+
# @param (see Farce::Envelope#initialize)
|
|
57
|
+
# @return [Copy, Share] A new envelope wrapping the given value.
|
|
58
|
+
class Copy < Farce::Envelope
|
|
59
|
+
include Copyable
|
|
60
|
+
|
|
61
|
+
# @overload initialize(value)
|
|
62
|
+
# @param [Object] value The value to wrap in the envelope.
|
|
63
|
+
def initialize(value, auto_unwrap = nil)
|
|
64
|
+
@vault = VAULT_ATOM.store_if_absent { Internal::Vault.new }
|
|
65
|
+
super
|
|
66
|
+
@vault.copy_in(self, value)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @api private
|
|
70
|
+
def marshal_dump
|
|
71
|
+
storage = Internal::Storage.ractor
|
|
72
|
+
[1, storage.key?(self) ? storage[self] : retrieve, auto_unwrap]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @api private
|
|
76
|
+
def marshal_load(data)
|
|
77
|
+
value, manager = Internal::MarshalSupport.payload(data, 2)
|
|
78
|
+
initialize(value, manager)
|
|
79
|
+
Internal::Storage.ractor[self] = value
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# (see Envelope#claim)
|
|
83
|
+
def claim = self
|
|
84
|
+
|
|
85
|
+
# (see Envelope#claimed?)
|
|
86
|
+
def claimed? = true
|
|
87
|
+
|
|
88
|
+
# (see Envelope#owned?)
|
|
89
|
+
def owned? = true
|
|
90
|
+
|
|
91
|
+
protected
|
|
92
|
+
|
|
93
|
+
def retrieve = @vault.copy_out(vault_key)
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def initialize_dup(other)
|
|
98
|
+
value = other.retrieve
|
|
99
|
+
@vault_key = Object.new.freeze
|
|
100
|
+
super
|
|
101
|
+
@vault.copy_in(@vault_key, value)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def initialize_clone(other, freeze: nil)
|
|
105
|
+
value = other.retrieve
|
|
106
|
+
@vault_key = Object.new.freeze
|
|
107
|
+
super
|
|
108
|
+
@vault.copy_in(@vault_key, value)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def vault_key = defined?(@vault_key) ? @vault_key : self
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# An envelope that moves its contents. Can only be opened by a single Ractor.
|
|
115
|
+
# The value will be moved once when the envelope is created, and then once when the envelope is opened.
|
|
116
|
+
#
|
|
117
|
+
# @!method new(value)
|
|
118
|
+
# @!scope class
|
|
119
|
+
# @param (see Farce::Envelope#initialize)
|
|
120
|
+
# @return [Move, Share] A new envelope wrapping the given value.
|
|
121
|
+
class Move < Farce::Envelope
|
|
122
|
+
include Internal::MarshalSupport::Reject
|
|
123
|
+
include Shareable::Unfreezable
|
|
124
|
+
|
|
125
|
+
# @overload initialize(value)
|
|
126
|
+
# @param [Object] value The value to wrap in the envelope.
|
|
127
|
+
def initialize(value, auto_unwrap = nil)
|
|
128
|
+
@vault = VAULT_ATOM.store_if_absent { Internal::Vault.new }
|
|
129
|
+
@owner = Internal::Atom.new
|
|
130
|
+
super
|
|
131
|
+
@vault.move_in(self, value)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# (see Envelope#claim)
|
|
135
|
+
def claim
|
|
136
|
+
owner = @owner.store_if_absent { Ractor.current }
|
|
137
|
+
self if owner == Ractor.current
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# (see Envelope#claimed?)
|
|
141
|
+
def claimed? = !@owner.value.nil?
|
|
142
|
+
|
|
143
|
+
# (see Envelope#owned?)
|
|
144
|
+
def owned? = @owner.value == Ractor.current
|
|
145
|
+
|
|
146
|
+
private def retrieve = @vault.move_out(self)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# An envelope that keeps its contents local to the Ractor that created it.
|
|
150
|
+
# Can only be opened by the Ractor that created it.
|
|
151
|
+
#
|
|
152
|
+
# @!method new(value)
|
|
153
|
+
# @!scope class
|
|
154
|
+
# @param (see Farce::Envelope#initialize)
|
|
155
|
+
# @return [Local, Share] A new envelope wrapping the given value.
|
|
156
|
+
class Local < Farce::Envelope
|
|
157
|
+
include Copyable
|
|
158
|
+
|
|
159
|
+
# @overload initialize(value)
|
|
160
|
+
# @param value [Object] The value to wrap in the envelope.
|
|
161
|
+
def initialize(value, auto_unwrap = nil)
|
|
162
|
+
@owner = Ractor.current
|
|
163
|
+
Internal::Storage.ractor[self] = value
|
|
164
|
+
super
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# @api private
|
|
168
|
+
def marshal_dump
|
|
169
|
+
raise TypeError, "local envelope belongs to another Ractor" unless owned?
|
|
170
|
+
[1, Internal::Storage.ractor[self], auto_unwrap]
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# @api private
|
|
174
|
+
def marshal_load(data)
|
|
175
|
+
value, manager = Internal::MarshalSupport.payload(data, 2)
|
|
176
|
+
initialize(value, manager)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# (see Envelope#claim)
|
|
180
|
+
def claim = owned? ? self : nil
|
|
181
|
+
|
|
182
|
+
# (see Envelope#claimed?)
|
|
183
|
+
def claimed? = true
|
|
184
|
+
|
|
185
|
+
# (see Envelope#owned?)
|
|
186
|
+
def owned? = @owner == Ractor.current
|
|
187
|
+
|
|
188
|
+
private
|
|
189
|
+
|
|
190
|
+
def initialize_copy(other)
|
|
191
|
+
super
|
|
192
|
+
other.claim!
|
|
193
|
+
Internal::Storage.ractor[self] = other.value.dup
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# An envelope that wraps a Ractor-shareable value. Can be opened by any Ractor.
|
|
198
|
+
# Defeats the purpose of an envelope, but is provided for code that expects an envelope.
|
|
199
|
+
#
|
|
200
|
+
# @!method new(value)
|
|
201
|
+
# @!scope class
|
|
202
|
+
# @param (see Farce::Envelope#initialize)
|
|
203
|
+
# @return [Share] A new envelope wrapping the given value.
|
|
204
|
+
class Share < Farce::Envelope
|
|
205
|
+
include Copyable
|
|
206
|
+
|
|
207
|
+
attr_reader :value
|
|
208
|
+
|
|
209
|
+
# @overload initialize(value)
|
|
210
|
+
# @param value [Object] The value to wrap in the envelope. Must be shareable.
|
|
211
|
+
def initialize(value, auto_unwrap = nil)
|
|
212
|
+
raise ArgumentError, "value must be shareable" unless Ractor.shareable?(value)
|
|
213
|
+
@value = value
|
|
214
|
+
super
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# @api private
|
|
218
|
+
def marshal_dump = [1, value, auto_unwrap]
|
|
219
|
+
|
|
220
|
+
# @api private
|
|
221
|
+
def marshal_load(data)
|
|
222
|
+
value, manager = Internal::MarshalSupport.payload(data, 2)
|
|
223
|
+
initialize(Ractor.make_shareable(value), manager)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# (see Envelope#claim)
|
|
227
|
+
def claim = self
|
|
228
|
+
|
|
229
|
+
# (see Envelope#claimed?)
|
|
230
|
+
def claimed? = true
|
|
231
|
+
|
|
232
|
+
# (see Envelope#owned?)
|
|
233
|
+
def owned? = true
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# @note
|
|
237
|
+
# The keyword arguments are only accepted by Envelope itself, not by its subclasses.
|
|
238
|
+
# Also, if multiple keyword arguments are provided, `mode` takes precedence over `local`, which takes precedence
|
|
239
|
+
# over `move`.
|
|
240
|
+
#
|
|
241
|
+
# Creates an envelope wrapping the given value. If the value is Ractor-shareable, a {Share} envelope will be
|
|
242
|
+
# created. Otherwise, the type of envelope will be determined by the keyword arguments.
|
|
243
|
+
#
|
|
244
|
+
# @overload new(value, move: false)
|
|
245
|
+
# @param value [BasicObject] The value to wrap in the envelope.
|
|
246
|
+
# @param move [Boolean] Whether to create a {Move} envelope. Ignored if `local` or `mode` is provided.
|
|
247
|
+
# @return [Envelope] A new envelope wrapping the given value.
|
|
248
|
+
#
|
|
249
|
+
# @overload new(value, local: false)
|
|
250
|
+
# @param value [BasicObject] The value to wrap in the envelope.
|
|
251
|
+
# @param local [Boolean] Whether to create a {Local} envelope. Ignored if `mode` is provided.
|
|
252
|
+
# @return [Envelope] A new envelope wrapping the given value.
|
|
253
|
+
#
|
|
254
|
+
# @overload new(value, mode:)
|
|
255
|
+
# @param value [BasicObject] The value to wrap in the envelope.
|
|
256
|
+
# @param mode [Symbol, nil] The type of envelope to create. Can be `:move`, `:copy`, or `:local`.
|
|
257
|
+
# @return [Envelope] A new envelope wrapping the given value.
|
|
258
|
+
#
|
|
259
|
+
# @return [Envelope] A new envelope wrapping the given value.
|
|
260
|
+
def self.new(value, *, **)
|
|
261
|
+
return super if self != Envelope
|
|
262
|
+
return Share.new(value, *) if Ractor.shareable?(value)
|
|
263
|
+
subclass_for(**).new(value, *)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def self.subclass_for(move: false, local: false, mode: nil)
|
|
267
|
+
case mode
|
|
268
|
+
when :move then Move
|
|
269
|
+
when :copy then Copy
|
|
270
|
+
when :local then Local
|
|
271
|
+
when nil then local ? Local : (move ? Move : Copy)
|
|
272
|
+
else raise ArgumentError, "invalid mode: #{mode.inspect}"
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
private_class_method :subclass_for
|
|
276
|
+
|
|
277
|
+
# @api private
|
|
278
|
+
attr_reader :auto_unwrap
|
|
279
|
+
|
|
280
|
+
# @overload initialize(value)
|
|
281
|
+
# @param value [BasicObject] The value to wrap in the envelope.
|
|
282
|
+
def initialize(_, auto_unwrap = nil)
|
|
283
|
+
raise ArgumentError, "auto_unwrap needs to be shareable" unless Ractor.shareable?(auto_unwrap)
|
|
284
|
+
@auto_unwrap = auto_unwrap
|
|
285
|
+
super()
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Attempts to claim the envelope for the current Ractor.
|
|
289
|
+
# Raises an exception if it was unable to claim the envelope.
|
|
290
|
+
# @return [Envelope] The envelope if the claim was successful.
|
|
291
|
+
# @raise [AlreadyClaimed] If the envelope has already been claimed by another Ractor.
|
|
292
|
+
def claim! = claim || raise(AlreadyClaimed, "envelope has already been claimed by another Ractor")
|
|
293
|
+
|
|
294
|
+
# Attempts to claim the envelope and retrieves the value if successful.
|
|
295
|
+
# May be called multiple times.
|
|
296
|
+
# @return [BasicObject] The value wrapped in the envelope.
|
|
297
|
+
# @raise [AlreadyClaimed] If the envelope has already been claimed by another Ractor.
|
|
298
|
+
def value = Internal::Storage.ractor.store_if_absent(self) { claim! && retrieve }
|
|
299
|
+
|
|
300
|
+
# Compares wrapped values. Compatible envelopes can be compared without
|
|
301
|
+
# claiming or opening either envelope.
|
|
302
|
+
# @param other [BasicObject, Envelope] The value or envelope to compare.
|
|
303
|
+
# @param identity [Boolean] Whether to compare the values by identity instead of equality.
|
|
304
|
+
# @return [Boolean] Whether the wrapped values match.
|
|
305
|
+
def same_value?(other, identity: false)
|
|
306
|
+
if comparison_vault
|
|
307
|
+
other_vault = other.comparison_vault if Envelope === other
|
|
308
|
+
if comparison_vault.equal?(other_vault)
|
|
309
|
+
return comparison_vault.same_value?(comparison_key, other.comparison_key, identity:)
|
|
310
|
+
elsif !(Envelope === other) && Ractor.shareable?(other)
|
|
311
|
+
return comparison_vault.same_value?(comparison_key, other, identity:, right_stored: false)
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
left = value
|
|
316
|
+
right = Envelope === other ? other.value : other
|
|
317
|
+
return BasicObject.instance_method(:equal?).bind_call(left, right) if identity
|
|
318
|
+
|
|
319
|
+
left == right
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# @api private
|
|
323
|
+
def inspect_with(inspector)
|
|
324
|
+
super do
|
|
325
|
+
inspector.breakable
|
|
326
|
+
inspector.from_envelope(self, "value=")
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
protected
|
|
331
|
+
|
|
332
|
+
def comparison_vault = defined?(@vault) && @vault
|
|
333
|
+
def comparison_key = defined?(@vault_key) ? @vault_key : self
|
|
334
|
+
end
|
|
335
|
+
end
|
data/lib/farce/error.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require "weakref"
|
|
7
|
+
rescue LoadError => e
|
|
8
|
+
raise e unless e.path == "weakref"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module Farce
|
|
12
|
+
# Raised when an operation cannot proceed because a queue is closed.
|
|
13
|
+
ClosedQueueError = Class.new(::ClosedQueueError)
|
|
14
|
+
|
|
15
|
+
# Raised when a push cannot proceed because a queue is sealed.
|
|
16
|
+
SealedQueueError = Class.new(ClosedQueueError)
|
|
17
|
+
|
|
18
|
+
# Raised when attempting to schedule a task on a closed scheduler.
|
|
19
|
+
SchedulerClosedError = Class.new(StandardError)
|
|
20
|
+
|
|
21
|
+
# Raised when attempting to schedule a task on a closed pool.
|
|
22
|
+
PoolClosedError = Class.new(SchedulerClosedError)
|
|
23
|
+
|
|
24
|
+
# Raised when a timed operation does not complete before its timeout.
|
|
25
|
+
TimeoutError = Class.new(StandardError)
|
|
26
|
+
|
|
27
|
+
# Raised when an operation requires ownership by the current Fiber.
|
|
28
|
+
OwnershipError = Class.new(StandardError)
|
|
29
|
+
|
|
30
|
+
# Raised when attempting to use a permanently retired lease.
|
|
31
|
+
RetiredLeaseError = Class.new(StandardError)
|
|
32
|
+
|
|
33
|
+
# Raised when a weak reference is no longer valid because the referenced object has been garbage collected.
|
|
34
|
+
WeakRefError = Class.new(defined?(::WeakRef::RefError) ? ::WeakRef::RefError : StandardError)
|
|
35
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# A Ractor-shareable rendezvous with transfer modes for unshareable values.
|
|
7
|
+
# Values received from a partner are automatically unwrapped.
|
|
8
|
+
#
|
|
9
|
+
# @example Exchanging mutable values between Ractors
|
|
10
|
+
# exchanger = Farce::Exchanger.new
|
|
11
|
+
# worker = Farce::Ractor.new(exchanger) { |shared| shared.exchange([:worker]) }
|
|
12
|
+
# exchanger.exchange([:main]) # => [:worker]
|
|
13
|
+
class Exchanger < Farce::Abstract::Exchanger
|
|
14
|
+
include Shareable::Unfreezable
|
|
15
|
+
|
|
16
|
+
# @!macro modes
|
|
17
|
+
# @param mode [Symbol] the default mode used to transfer values between Ractors
|
|
18
|
+
def initialize(mode: :copy)
|
|
19
|
+
@manager = ModeManager.new(mode:)
|
|
20
|
+
@exchanger = Internal::Exchanger.new
|
|
21
|
+
super()
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# The default mode used to transfer values between Ractors.
|
|
25
|
+
# @return [Symbol]
|
|
26
|
+
def mode = @manager.mode
|
|
27
|
+
|
|
28
|
+
# (see Abstract::Exchanger#exchange)
|
|
29
|
+
# The offered value is prepared before waiting. A timeout does not undo copying,
|
|
30
|
+
# moving, or freezing it. The fallback result is returned unchanged.
|
|
31
|
+
# @!macro modes
|
|
32
|
+
# @param mode [Symbol, nil] the transfer mode, or nil to use the exchanger's default mode
|
|
33
|
+
def exchange(offered, timeout: nil, mode: nil)
|
|
34
|
+
offered = @manager.wrap(offered, mode:)
|
|
35
|
+
timed_out = false
|
|
36
|
+
result = @exchanger.exchange(offered, timeout:) { timed_out = true }
|
|
37
|
+
return @manager.unwrap(result) unless timed_out
|
|
38
|
+
yield if block_given?
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/farce/flag.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
module Farce
|
|
6
|
+
# A Ractor-shareable atomic boolean for coordinating threads and Ractors.
|
|
7
|
+
# Only true and false are accepted. Read {#value} when testing the flag's state.
|
|
8
|
+
# Use {#compare_and_set} to check and change the state in a single atomic operation.
|
|
9
|
+
#
|
|
10
|
+
# On CRuby, subclasses must not add Ruby instance variables.
|
|
11
|
+
#
|
|
12
|
+
# @example Allowing one caller to claim work
|
|
13
|
+
# claimed = Farce::Flag.new
|
|
14
|
+
# workers = 4.times.map do
|
|
15
|
+
# Thread.new { claimed.compare_and_set(false, true) }
|
|
16
|
+
# end
|
|
17
|
+
# workers.count { |worker| worker.value } # => 1
|
|
18
|
+
# claimed.value # => true
|
|
19
|
+
#
|
|
20
|
+
# @!method initialize(value = false)
|
|
21
|
+
# @param value [Boolean] the initial value
|
|
22
|
+
# @raise [ArgumentError] if the value is not true or false
|
|
23
|
+
class Flag < Internal::Flag
|
|
24
|
+
include Abstract::Flag
|
|
25
|
+
include Shareable::Native
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
# @!group ActiveSupport Integration
|
|
6
|
+
require "farce/integrations/active_support"
|
|
7
|
+
|
|
8
|
+
# ActiveSupport's blank? already checks empty?
|
|
9
|
+
# Therefore Vector/Map/Set implementations do not need additional blank? checks.
|
|
10
|
+
#-
|
|
11
|
+
|
|
12
|
+
module Farce
|
|
13
|
+
# @!visibility private
|
|
14
|
+
module Internal # :nodoc: all
|
|
15
|
+
# @api private
|
|
16
|
+
class Vault
|
|
17
|
+
# rubocop:disable-next Naming/PredicatePrefix
|
|
18
|
+
if defined?(Manager)
|
|
19
|
+
class Manager
|
|
20
|
+
def is_blank(key, _, port) = respond(port, [true, @data[key].blank?].freeze)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def is_blank?(key) = execute(:is_blank, key)
|
|
24
|
+
else
|
|
25
|
+
def is_blank?(key) = @data[key].blank?
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module Abstract
|
|
31
|
+
class Atom
|
|
32
|
+
# @!macro active_support
|
|
33
|
+
# @return [Boolean] true if the atom's value is blank, false otherwise.
|
|
34
|
+
def blank? = internal_atom.value.blank?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
module Value
|
|
38
|
+
# @!macro active_support
|
|
39
|
+
# @return [Boolean] true if the value is blank, false otherwise.
|
|
40
|
+
def blank? = value.blank?
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class Atom
|
|
45
|
+
# @!macro active_support
|
|
46
|
+
# @return [Boolean] true if the atom's value is blank, false otherwise.
|
|
47
|
+
def blank?
|
|
48
|
+
current = internal_atom.value
|
|
49
|
+
NIL_VALUE.equal?(current) || current.blank?
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class Envelope
|
|
54
|
+
# @!macro active_support
|
|
55
|
+
# Checks if the envelope's value is blank without claiming it.
|
|
56
|
+
# @return [Boolean] true if the envelope's value is blank or inaccessible, false otherwise.
|
|
57
|
+
def blank?
|
|
58
|
+
if !claimed? && (vault = comparison_vault)
|
|
59
|
+
result = vault.is_blank?(comparison_key)
|
|
60
|
+
# A concurrent claim may have removed the value from the vault.
|
|
61
|
+
return result unless claimed?
|
|
62
|
+
end
|
|
63
|
+
return true unless owned?
|
|
64
|
+
|
|
65
|
+
value.blank?
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
# @!group ActiveSupport Integration
|
|
6
|
+
require "farce/integrations/active_support"
|
|
7
|
+
|
|
8
|
+
module Farce
|
|
9
|
+
module Clock
|
|
10
|
+
# @!macro active_support
|
|
11
|
+
# Treat ActiveSupport durations as relative offsets.
|
|
12
|
+
def self.parse(value)
|
|
13
|
+
return offset(value) if ActiveSupport::Duration === value
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
# warn_indent: true
|
|
4
|
+
|
|
5
|
+
# @!group ActiveSupport Integration
|
|
6
|
+
require "farce/integrations/active_support"
|
|
7
|
+
|
|
8
|
+
module Farce
|
|
9
|
+
class Config
|
|
10
|
+
# @!macro active_support
|
|
11
|
+
# @return [Boolean] true
|
|
12
|
+
def duplicable? = true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class WeakValue
|
|
16
|
+
# @!macro active_support
|
|
17
|
+
# @return [Boolean] true
|
|
18
|
+
def duplicable? = true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class WeakRef
|
|
22
|
+
# @!macro active_support
|
|
23
|
+
# @return [Boolean] true
|
|
24
|
+
def duplicable? = true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class Reference
|
|
28
|
+
# @!macro active_support
|
|
29
|
+
# @return [Boolean] true
|
|
30
|
+
def duplicable? = true
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module Abstract
|
|
34
|
+
class Queue
|
|
35
|
+
# @!macro active_support
|
|
36
|
+
# @return [Boolean] false
|
|
37
|
+
def duplicable? = false
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class Set
|
|
41
|
+
# @!macro active_support
|
|
42
|
+
# @return [Boolean] true
|
|
43
|
+
def duplicable? = true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class LeaseMap
|
|
47
|
+
# @!macro active_support
|
|
48
|
+
# @return [Boolean] false
|
|
49
|
+
def duplicable? = false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
module DuplicableMap
|
|
53
|
+
# @!macro active_support
|
|
54
|
+
# @return [Boolean] true
|
|
55
|
+
def duplicable? = true
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
module Internal
|
|
60
|
+
module Copyable
|
|
61
|
+
# @!macro active_support
|
|
62
|
+
# @return [Boolean] true
|
|
63
|
+
def duplicable? = true
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
module Noncopyable
|
|
67
|
+
# @!macro active_support
|
|
68
|
+
# @return [Boolean] false
|
|
69
|
+
def duplicable? = false
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
module SchedulerLifecycle
|
|
73
|
+
# @!macro active_support
|
|
74
|
+
# @return [Boolean] false
|
|
75
|
+
def duplicable? = false
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|