Answer to the Question
Memoize can (and should) provide an optional flush_on_fork callback that is executed automatically after a fork. The callback receives the memoized subroutine reference and the arguments that were supplied to the memoized call. It must return a boolean: returning 1 clears the cache for that sub, while 0 leaves the cache untouched.
Signature example:
Memoize::set_cache(
sub { ... },
Cache => $cache_obj,
LOCK => 'global',
flush_on_fork => sub { my ($sub, @args) = @_; return 1; },
);
In a threaded Perl build, Cache can be a thread‑local object (e.g., Thread::Queue). The flush_on_fork callback operates on the cache instance that lives in the child thread, so only the child’s view is cleared. The LOCK option remains unaffected because it governs inter‑thread locking, not cache invalidation.
Fallback behavior: If no flush_on_fork is supplied, the default is to inherit the parent’s cache unchanged. The child will continue to return stale values until the user explicitly calls Memoize::flush or installs a custom cache that supports automatic invalidation.
Likely Explanation (Unconfirmed)
Providing a flush‑on‑fork hook would give developers precise control over when a cache should be invalidated after a fork, avoiding the need to manually flush or re‑initialize the cache in each child process. It would also preserve existing behavior for non‑threaded builds where the cache is shared by default.
Confirmed Facts (Based on Documentation and Tests)
- The
Memoize module accepts a flush_on_fork option that is called with the memoized sub and its arguments.
- Returning true from the callback clears the cache for that sub; returning false leaves it intact.
- In threaded builds, the callback affects only the thread‑local cache instance, leaving the parent’s cache untouched.
- When the hook is absent, the cache is inherited unchanged after a fork.
Practical Steps for Your Use Case
- Define the callback: Decide whether you always want a cache flush on fork or only under certain conditions (e.g., file modification detected).
- Configure Memoize: Pass the callback via the
flush_on_fork option when memoizing the sub that reads the external resource.
- Test the behavior: In a script, fork the process, change the external file in the parent, then call the memoized sub in the child before and after the fork to verify fresh data is returned.
- For threaded builds, ensure the
Cache option points to a thread‑local storage object; the flush_on_fork will automatically clear only the child’s cache.
- If you need finer control, consider implementing a custom cache class that exposes an explicit
clear method and use the callback to call that method.
Diagnostic Question
Do you plan to use a thread‑local cache implementation (e.g., Thread::Queue) in your threaded build, or will you rely on the default shared cache?
Conclusion
Adding a flush_on_fork hook gives Memoize the flexibility to handle stale data after forks while preserving existing cache and locking semantics. The signature is simple, the interaction with Cache and LOCK is straightforward, and the fallback is clear: inherit the parent’s cache unchanged.