Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for eviction listener #145

Merged
merged 38 commits into from
Jul 4, 2022
Merged

Add support for eviction listener #145

merged 38 commits into from
Jul 4, 2022

Conversation

tatsuya6502
Copy link
Member

@tatsuya6502 tatsuya6502 commented May 30, 2022

This PR adds a support for the eviction listener to the following caches:

  • sync::Cache
  • sync::SegmentedCache
  • future::Cache

The eviction listener is a closure with the following signature and can be used (for example) to keep other data structures in-sync with the cache.

impl Fn(Arc<K>, V, RemovalCause) + Send + Sync + 'static
where
    V: Clone,

and the enum RemovalCause (moka::notification::RemovalCause) is defined as the followings:

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RemovalCause {
    /// The entry's expiration timestamp has passed.
    Expired,
    /// The entry was manually removed by the user.
    Explicit,
    /// The entry itself was not actually removed, but its value was replaced by
    /// the user.
    Replaced,
    /// The entry was evicted due to size constraints.
    Size,
}

The enum DeliveryMode specifies how and when an eviction notification should be delivered to an eviction listener.

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DeliveryMode {
    /// With this mode, a notification should be delivered to the listener
    /// immediately after an entry was evicted. It also guarantees that eviction
    /// notifications and cache write operations such and `insert`, `get_with` and
    /// `invalidate` for a given cache key are ordered by the time when they
    /// occurred.
    ///
    /// To guarantee the order, cache maintains key-level lock, which will reduce
    /// concurrent write performance.
    ///
    /// Use this mode when the order is more import than the write performance.
    Immediate,
    /// With this mode, a notification will be delivered to the listener some time
    /// after an entry was evicted. Therefore, it does not preserve the order of
    /// eviction notifications and write operations.
    ///
    /// On the other hand, cache does not maintain key-level lock, so there will be
    /// no overhead on write performance.
    ///
    /// Use this mode when write performance is more important than preserving the
    /// order of eviction notifications and write operations.
    Queued,
}

Currently, sync caches support both modes and Immediate mode is the default. But future cache supports only Queued mode.


Fixes #128

(WIP) Add support for notification on eviction to the following caches:
- `sync::Cache`
- `sync::SegmentedCache`
- `future::Cache`

Details:
- Add `eviction_listener` method to the cache builders.
- Add `notification` module with `RemovalCause` enum.
- Add internal `sync_base::removal_notifier` module.
- Implement some of the notifications.
- Add a unit test case to `sync::Cache` for the implemented notifications.
Enable `RemovalCause::Replaced` events.
- Enable `RemovalCause::Expired` events.
- Update existing unit test cases to verify the notifications after
  invalidating, replacing, evicting and expiring entries.
- Update the README.
- Fix the `RemovalCause` for entries removed by `invalidate_all`.
- Add unit tests to `sync::SegmentedCache`.
- Add unit tests to `future::Cache`.
- Docs: Write code examples for eviction listener.
- Update the dev dependencies:
    - Tokio v1.16 -> v1.18.
    - Add anyhow v1.0.
Fix a doc test (compile error).
Fix a bug with timing issues that causes to report wrong `RemovalCause`
`Replaced` or `Explicit` when `Expired` is appropriate.
Implement basic part of blocking notifications.
Implement the rest of the part of blocking notifications but only to
`sync::{Cache, SegmentedCache}`. (Will remove blocking mode from `future::Cache`)

- Add `KeyLockMap` for locking a key during updating/removing its entry and
  processing a blocking notification.
- Update the unit tests in `sync::Cache` to test blocking notifications.
to ensure `triomphe::Arc::count` function exists
Remove the second parameter `mode` from `future::CacheBuilder::eviction_listener`
method as `future::Cache` will not support blocking notification mode in
the coming release.
- Add `notification::Configuration` struct.
- Add `eviction_listener_with_conf` method to `sync::Builder`.
- Rename `notification::EvictionNotificationMode` enum to `notification::DeliveryMode`.
- Update unit tests for `sync` caches to test both two `DeliveryMode` variants.
Rename `DeliveryMode::Direct` to `DeliveryMode::Immediate`.
Try to stabilize flaky tests caused by slow QEMU VMs.
Try to stabilize flaky tests caused by slow QEMU VMs.
Add an unit test to ensure the key-level lock is working.
Avoid the housekeeper and non-blocking notifier threads
from stalling when the notification channel is full.
Tweak the name of an unit test and its code comments.
Add panic handling to the notifiers. When the user-provided listener
panics, the notifier will no longer call the listener for safely.
Add unit tests for testing recovery from panicking eviction listener.
Emit an error log when the user provided eviction listener panics. (Requires
`logging` feature enabled)
- Rename the `eviction_listener` method of `future::CacheBuilder` to
  `eviction_listener_with_queued_delivery_mode`.
- Write the documentation.
Add the `name` method to `sync` and `future` caches.
Write the documentation.
Rename `sync_base::removal_notifier` module to `notification::notifier`.
Write the documentation.
Fix "unused field" warnings in `notification::notifier` module.
@tatsuya6502 tatsuya6502 marked this pull request as ready for review July 4, 2022 13:59
Fix some typos in the documentation.
Remove unused function and struct.
@tatsuya6502 tatsuya6502 linked an issue Jul 4, 2022 that may be closed by this pull request
Copy link
Member Author

@tatsuya6502 tatsuya6502 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merging.

@tatsuya6502 tatsuya6502 merged commit 02fe6c8 into next Jul 4, 2022
@tatsuya6502 tatsuya6502 deleted the eviction-listener branch July 4, 2022 23:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
1 participant