Skip to content

Commit

Permalink
Merge pull request #45 from moka-rs/merge-maint-0.5
Browse files Browse the repository at this point in the history
Merge recent changes from maint-0.5 branch into master
  • Loading branch information
tatsuya6502 committed Sep 18, 2021
2 parents 19b6925 + 2033a34 commit 19c0528
Show file tree
Hide file tree
Showing 19 changed files with 329 additions and 99 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ jobs:
env:
RUSTFLAGS: '--cfg skeptic'

- name: Run tests (future, without atomic64)
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != '1.45.2' }}
with:
command: test
args: --release --no-default-features --features future
env:
RUSTFLAGS: '--cfg skeptic'

- name: Run UI tests (future, trybuild)
uses: actions-rs/cargo@v1
if: ${{ matrix.rust == 'stable' }}
Expand Down
74 changes: 74 additions & 0 deletions .github/workflows/LinuxCrossCompileTest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Linux cross compile tests

on:
push:
paths-ignore:
- '.devcontainer/**'
- '.gitpod.yml'
- '.vscode/**'
- 'tests/**'
pull_request:
paths-ignore:
- '.devcontainer/**'
- '.gitpod.yml'
- '.vscode/**'
- 'tests/**'
schedule:
# Run against the last commit on the default branch on Friday at 9pm (UTC?)
- cron: '0 21 * * 5'

jobs:
linux-cross:
runs-on: ubuntu-latest
strategy:
matrix:
platform:
- target: aarch64-unknown-linux-musl
- target: i686-unknown-linux-musl
- target: armv7-unknown-linux-musleabihf
# Platforms without AtomicU64 support.
- target: armv5te-unknown-linux-musleabi
cargo-opts: "--no-default-features" # Disable atomic64 feature.
- target: mips-unknown-linux-musl
cargo-opts: "--no-default-features" # Disable atomic64 feature.
- target: mipsel-unknown-linux-musl
cargo-opts: "--no-default-features" # Disable atomic64 feature.

steps:
- name: Checkout Moka
uses: actions/checkout@v2

- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
target: ${{ matrix.platform.target }}
override: true

- name: Remove integration tests
run: |
rm -rf tests
sed -i '/actix-rt\|async-std\|reqwest\|skeptic/d' Cargo.toml
cat Cargo.toml
- uses: Swatinem/rust-cache@v1

- name: cargo clean
uses: actions-rs/cargo@v1
with:
command: clean

- name: Run tests (no features)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: test
args: --release --target ${{ matrix.platform.target }} ${{ matrix.platform.cargo-opts }}

- name: Run tests (future feature)
uses: actions-rs/cargo@v1
with:
use-cross: true
command: test
args: --release --features future --target ${{ matrix.platform.target }} ${{ matrix.platform.cargo-opts }}
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{
"rust-analyzer.cargo.features": ["future"],
"cSpell.words": [
"aarch",
"actix",
"ahash",
"benmanes",
"CLFU",
"clippy",
"compat",
"cpus",
"deqs",
"Deque",
Expand Down
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@
- Change `get_or_try_insert_with` to return a concrete error type rather
than a trait object. ([#23][gh-pull-0023], [#37][gh-pull-0037])

## Version 0.5.4

### Changed

- Restore quanta dependency on some 32-bit platforms such as
`armv5te-unknown-linux-musleabi` or `mips-unknown-linux-musl`.
([#42][gh-pull-0042])


## Version 0.5.3

### Added

- Add support for some 32-bit platforms where `std::sync::atomic::AtomicU64` is not
provided. (e.g. `armv5te-unknown-linux-musleabi` or `mips-unknown-linux-musl`)
([#38][gh-issue-0038])
- On these platforms, you will need to disable the default features of Moka.
See [the relevant section][resolving-error-on-32bit] of the README.


## Version 0.5.2

Expand Down Expand Up @@ -112,6 +131,10 @@

[caffeine-git]: https://github.com/ben-manes/caffeine

[resolving-error-on-32bit]: https://github.com/moka-rs/moka#resolving-compile-errors-on-some-32-bit-platforms

[gh-pull-0042]: https://github.com/moka-rs/moka/pull/42/
[gh-issue-0038]: https://github.com/moka-rs/moka/issues/38/
[gh-pull-0037]: https://github.com/moka-rs/moka/pull/37/
[gh-pull-0033]: https://github.com/moka-rs/moka/pull/33/
[gh-issue-0031]: https://github.com/moka-rs/moka/issues/31/
Expand Down
12 changes: 10 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,24 @@ build = "build.rs"
features = ["future"]

[features]
default = []
default = ["atomic64"]

# Enable this feature to use `moka::future::Cache`.
future = ["async-io", "async-lock"]

# This feature is enabled by default. Disable it when the target platform does not
# support `std::sync::atomic::AtomicU64`. (e.g. `armv5te-unknown-linux-musleabi`
# or `mips-unknown-linux-musl`)
# https://github.com/moka-rs/moka#resolving-compile-errors-on-some-32-bit-platforms
atomic64 = []

[dependencies]
crossbeam-channel = "0.5"
moka-cht = "0.4.2"
num_cpus = "1.13"
once_cell = "1.7"
parking_lot = "0.11"
quanta = "0.9"
quanta = "0.9.3"
scheduled-thread-pool = "0.2"
thiserror = "1.0"
uuid = { version = "0.8", features = ["v4"] }
Expand Down
52 changes: 44 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,15 @@ available on crates.io, such as the [aHash][ahash-crate] crate.

This crate's minimum supported Rust versions (MSRV) are the followings:

| Enabled Feature | MSRV |
|:---------------------|:------------|
| no feature (default) | Rust 1.45.2 |
| `future` | Rust 1.46.0 |

If no feature is enabled, MSRV will be updated conservatively. When using other
features, like `future`, MSRV might be updated more frequently, up to the latest
stable. In both cases, increasing MSRV is _not_ considered a semver-breaking
| Feature | Enabled by default? | MSRV |
|:-----------|:-------------------:|:-----------:|
| no feature | | Rust 1.45.2 |
| `atomic64` | yes | Rust 1.45.2 |
| `future` | | Rust 1.46.0 |

If only the default features are enabled, MSRV will be updated conservatively. When
using other features, like `future`, MSRV might be updated more frequently, up to the
latest stable. In both cases, increasing MSRV is _not_ considered a semver-breaking
change.

<!--
Expand All @@ -334,6 +335,41 @@ change.
-->


## Resolving Compile Errors on Some 32-bit Platforms

On some 32-bit target platforms including the followings, you may encounter compile
errors in quanta crate and Moka itself.

- `armv5te-unknown-linux-musleabi`
- `mips-unknown-linux-musl`
- `mipsel-unknown-linux-musl`

```console
error[E0432]: unresolved import `std::sync::atomic::AtomicU64`
--> ... /moka-0.5.3/src/sync.rs:10:30
|
10 | atomic::{AtomicBool, AtomicU64, Ordering},
| ^^^^^^^^^
| |
| no `AtomicU64` in `sync::atomic`
```

These errors occur because `std::sync::atomic::AtomicU64` type is not provided on
these platforms but Moka uses it.

You can resolve the errors by disabling the default features of Moka. Edit your
Cargo.toml to add `default-features = false` option to the dependency declaration.

```toml:Cargo.toml
[dependencies]
moka = { version = "0.5", default-feautures = false }
# Or
moka = { version = "0.5", default-feautures = false, features = ["future"] }
```

This will enable a fall-back implementation in Moka, so it will compile.


## Developing Moka

**Running All Tests**
Expand Down
20 changes: 10 additions & 10 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use quanta::Instant;

pub(crate) mod deque;
pub(crate) mod error;
pub(crate) mod frequency_sketch;
pub(crate) mod thread_pool;
pub(crate) mod unsafe_weak_pointer;

// targe_has_atomic is more convenient but yet unstable (Rust 1.55)
// https://github.com/rust-lang/rust/issues/32976
// #[cfg_attr(target_has_atomic = "64", path = "common/time_atomic64.rs")]

#[cfg_attr(feature = "atomic64", path = "common/time_atomic64.rs")]
#[cfg_attr(not(feature = "atomic64"), path = "common/time_compat.rs")]
pub(crate) mod time;

use time::Instant;

pub(crate) trait AccessTime {
fn last_accessed(&self) -> Option<Instant>;
fn set_last_accessed(&mut self, timestamp: Instant);
fn last_modified(&self) -> Option<Instant>;
fn set_last_modified(&mut self, timestamp: Instant);
}

pub(crate) fn u64_to_instant(ts: u64) -> Option<Instant> {
if ts == u64::MAX {
None
} else {
Some(unsafe { std::mem::transmute(ts) })
}
}
5 changes: 4 additions & 1 deletion src/common/thread_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ impl ThreadPoolRegistry {
// and insert a new pool.
let mut pools = REGISTRY.pools.write();
pools.entry(name).or_insert_with(|| {
let num_threads = num_cpus::get();
// Some platforms may return 0. In that case, use 1.
// https://github.com/moka-rs/moka/pull/39#issuecomment-916888859
// https://github.com/seanmonstar/num_cpus/issues/69
let num_threads = num_cpus::get().max(1);
let pool =
ScheduledThreadPool::with_name(name.thread_name_template(), num_threads);
let t_pool = ThreadPool {
Expand Down
42 changes: 42 additions & 0 deletions src/common/time_atomic64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use std::sync::atomic::{AtomicU64, Ordering};

pub(crate) type Instant = quanta::Instant;
pub(crate) type Clock = quanta::Clock;

#[cfg(test)]
pub(crate) type Mock = quanta::Mock;

pub(crate) struct AtomicInstant {
instant: AtomicU64,
}

impl Default for AtomicInstant {
fn default() -> Self {
Self {
instant: AtomicU64::new(std::u64::MAX),
}
}
}

impl AtomicInstant {
pub(crate) fn reset(&self) {
self.instant.store(std::u64::MAX, Ordering::Release);
}

pub(crate) fn is_set(&self) -> bool {
self.instant.load(Ordering::Acquire) != u64::MAX
}

pub(crate) fn instant(&self) -> Option<Instant> {
let ts = self.instant.load(Ordering::Acquire);
if ts == u64::MAX {
None
} else {
Some(unsafe { std::mem::transmute(ts) })
}
}

pub(crate) fn set_instant(&self, instant: Instant) {
self.instant.store(instant.as_u64(), Ordering::Release);
}
}
37 changes: 37 additions & 0 deletions src/common/time_compat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use parking_lot::RwLock;

pub(crate) type Instant = quanta::Instant;
pub(crate) type Clock = quanta::Clock;

#[cfg(test)]
pub(crate) type Mock = quanta::Mock;

pub(crate) struct AtomicInstant {
instant: RwLock<Option<Instant>>,
}

impl Default for AtomicInstant {
fn default() -> Self {
Self {
instant: RwLock::new(None),
}
}
}

impl AtomicInstant {
pub(crate) fn reset(&self) {
*self.instant.write() = None;
}

pub(crate) fn is_set(&self) -> bool {
self.instant.read().is_some()
}

pub(crate) fn instant(&self) -> Option<Instant> {
*self.instant.read()
}

pub(crate) fn set_instant(&self, instant: Instant) {
*self.instant.write() = Some(instant);
}
}
5 changes: 2 additions & 3 deletions src/future/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ where
self.base.reconfigure_for_testing();
}

fn set_expiration_clock(&self, clock: Option<quanta::Clock>) {
fn set_expiration_clock(&self, clock: Option<crate::common::time::Clock>) {
self.base.set_expiration_clock(clock);
}
}
Expand All @@ -747,10 +747,9 @@ where
#[cfg(test)]
mod tests {
use super::{Cache, ConcurrentCacheExt};
use crate::future::CacheBuilder;
use crate::{common::time::Clock, future::CacheBuilder};

use async_io::Timer;
use quanta::Clock;
use std::time::Duration;

#[tokio::test]
Expand Down

0 comments on commit 19c0528

Please sign in to comment.