This PR will introduce the notion of Cachex.Provision to cache services, so they can also be provisioned just like hooks and warmers. As the Janitor uses :cache, this removes a table lookup on every call of the Janitor.
Also included is a change to Cachex.Router to allow actions which don't support distribution (i.e. Cachex.stream/3) to be called on the local node if local: true. This means we can go via Cachex.stream/3 rather than Cachex.Action.Stream.execute/3 when re-using it internally.
Lastly the flow of the Janitor purge itself has changed. A Janitor is now flagged as "inactive" during initialization. An inactive Janitor will only do a quick sample to determine if there are any records in the cache with expiration set. If there aren't, it'll just short-circuit and repeat this process until there are. To clarify "with expiration" does not mean "expired", just that the field is not nil in a single record.
Once a record with expiration is detected, it'll flag the Janitor as "active" and going forward the purge cycles will run as previously (including immediately). The previous sample will no longer run, so there's no overhead here compared to behaviour before this PR.
Although this sounds more complicated, it skips out on the call to Cachex.purge/2 which uses Locksmith.transaction/3 under the hood and places a lock on the entire table. If you're not using expirations, this overhead will no longer affect you until you are, which is much better!
This fixes #367.
This PR will introduce the notion of
Cachex.Provision
to cache services, so they can also be provisioned just like hooks and warmers. As the Janitor uses:cache
, this removes a table lookup on every call of the Janitor.Also included is a change to
Cachex.Router
to allow actions which don't support distribution (i.e.Cachex.stream/3
) to be called on the local node iflocal: true
. This means we can go viaCachex.stream/3
rather thanCachex.Action.Stream.execute/3
when re-using it internally.Lastly the flow of the Janitor purge itself has changed. A Janitor is now flagged as "inactive" during initialization. An inactive Janitor will only do a quick sample to determine if there are any records in the cache with expiration set. If there aren't, it'll just short-circuit and repeat this process until there are. To clarify "with expiration" does not mean "expired", just that the field is not
nil
in a single record.Once a record with expiration is detected, it'll flag the Janitor as "active" and going forward the purge cycles will run as previously (including immediately). The previous sample will no longer run, so there's no overhead here compared to behaviour before this PR.
Although this sounds more complicated, it skips out on the call to
Cachex.purge/2
which usesLocksmith.transaction/3
under the hood and places a lock on the entire table. If you're not using expirations, this overhead will no longer affect you until you are, which is much better!