Ractor::Cache
Usage:
# Typical cached method:
class Foo
def long_calc
@long_calc ||= do_long_calculation
end
end
# With Ractor::Cache:
using Ractor::Cache
class Foo
cache def long_calc
do_long_calculation
end
end
Why?
0) It's pretty
1) It makes your class Ractor-compatible
Ractor-compatible?
Ractor is new in Ruby 3.0 and is awesome.
Passing classes between Ractors can be done very efficiently if classes are deeply frozen.
For some classes, being frozen isn't useful or possible (e.g. IO), but for many it is possible.
One challenge of writing classes that can be deeply frozen is methods that cache the results:
f = Foo.new
f.freeze
f.long_calc # => FrozenError, can't set `@long_calc`
Some techniques could include storing the cache in a mutable data structure:
class Foo
def initialize
@cache = {}
end
def long_calc
@cache[:long_calc] ||= # ...
end
end
f = Foo.new
f.freeze
f.long_calc # => ok
But Ractor.make_shareable freezes the instance variables too, so this can't work:
f = Foo.new
Ractor.make_shareable(foo)
foo.long_calc # => `FrozenError`, @cache is frozen
How to resolve this
This gem will: 1) Use a mutable data structure like above, which means no issue for shallow freezing an instance 2) If an instance is deeply frozen, the gem will either insure things will keep working by applying any of the following strategies:
- prebuild the cache,
- not write to the cache,
- (or maybe use a separate Ractor /
SharedHash)
Implementation details pexplained here](hacker_guide.md)
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/marcandre/ractor-cache. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Ractor::Cache project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.