Skip to content

Commit

Permalink
Merge pull request wasmerio#2402 from Hywan/doc-middlewares
Browse files Browse the repository at this point in the history
doc(middlewares) Add more examples and more doctests
  • Loading branch information
syrusakbary authored Jun 7, 2021
2 parents c98d3a8 + df2f961 commit 0ca884d
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 21 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C

## 2.0.0-rc2 - 2020/06/03

### Changed
### Added
- [#2402](https://github.com/wasmerio/wasmer/pull/2402) Add more examples and more doctests for `wasmer-middlewares`.

### Changed
- [#2399](https://github.com/wasmerio/wasmer/pull/2399) Add the Dart integration in the `README.md`.

### Fixed
Expand Down
3 changes: 3 additions & 0 deletions lib/middlewares/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ wasmer-types = { path = "../types", version = "2.0.0-rc2" }
wasmer-vm = { path = "../vm", version = "2.0.0-rc2" }
loupe = "0.1"

[dev-dependencies]
wasmer = { path = "../api", version = "2.0.0-rc2", features = ["compiler"] }

[badges]
maintenance = { status = "actively-developed" }
4 changes: 4 additions & 0 deletions lib/middlewares/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ middlewares:
- `metering`: A middleware for tracking how many operators are
executed in total and putting a limit on the total number of
operators executed.

[See the `metering`
example](https://github.com/wasmerio/wasmer/blob/master/examples/metering.rs)
to get a concrete and complete example.
5 changes: 3 additions & 2 deletions lib/middlewares/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod metering;

// The most commonly used symbol are exported at top level of the module. Others are available
// via modules, e.g. `wasmer_middlewares::metering::get_remaining_points`
// The most commonly used symbol are exported at top level of the
// module. Others are available via modules,
// e.g. `wasmer_middlewares::metering::get_remaining_points`
pub use metering::Metering;
110 changes: 92 additions & 18 deletions lib/middlewares/src/metering.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
//! `metering` is a middleware for tracking how many operators are executed in total
//! and putting a limit on the total number of operators executed.
//! `metering` is a middleware for tracking how many operators are
//! executed in total and putting a limit on the total number of
//! operators executed. The WebAssemblt instance execution is stopped
//! when the limit is reached.
//!
//! # Example
//!
//! [See the `metering` detailed and complete
//! example](https://github.com/wasmerio/wasmer/blob/master/examples/metering.rs).
use loupe::{MemoryUsage, MemoryUsageTracker};
use std::convert::TryInto;
Expand Down Expand Up @@ -46,9 +53,36 @@ impl fmt::Debug for MeteringGlobalIndexes {
///
/// # Panic
///
/// An instance of `Metering` should not be shared among different modules, since it tracks
/// module-specific information like the global index to store metering state. Attempts to use
/// a `Metering` instance from multiple modules will result in a panic.
/// An instance of `Metering` should _not_ be shared among different
/// modules, since it tracks module-specific information like the
/// global index to store metering state. Attempts to use a `Metering`
/// instance from multiple modules will result in a panic.
///
/// # Example
///
/// ```rust
/// use std::sync::Arc;
/// use wasmer::{wasmparser::Operator, CompilerConfig};
/// use wasmer_middlewares::Metering;
///
/// fn create_metering_middleware(compiler_config: &mut dyn CompilerConfig) {
/// // Let's define a dummy cost function,
/// // which counts 1 for all operators.
/// let cost_function = |_operator: &Operator| -> u64 { 1 };
///
/// // Let's define the initial limit.
/// let initial_limit = 10;
///
/// // Let's creating the metering middleware.
/// let metering = Arc::new(Metering::new(
/// initial_limit,
/// cost_function
/// ));
///
/// // Finally, let's push the middleware.
/// compiler_config.push_middleware(metering);
/// }
/// ```
pub struct Metering<F: Fn(&Operator) -> u64 + Send + Sync> {
/// Initial limit of points.
initial_limit: u64,
Expand All @@ -72,13 +106,22 @@ pub struct FunctionMetering<F: Fn(&Operator) -> u64 + Send + Sync> {
accumulated_cost: u64,
}

/// Represents the type of the metering points, either `Remaining` or
/// `Exhausted`.
///
/// # Example
///
/// See the [`get_remaining_points`] function to get an example.
#[derive(Debug, PartialEq)]
pub enum MeteringPoints {
/// The given number of metering points is left for the execution.
/// If the value is 0, all points are consumed but the execution was not terminated.
/// If the value is 0, all points are consumed but the execution
/// was not terminated.
Remaining(u64),
/// The execution was terminated because the metering points were exhausted.
/// You can recover from this state by setting the points via `set_remaining_points` and restart the execution.

/// The execution was terminated because the metering points were
/// exhausted. You can recover from this state by setting the
/// points via [`set_remaining_points`] and restart the execution.
Exhausted,
}

Expand Down Expand Up @@ -225,15 +268,29 @@ impl<F: Fn(&Operator) -> u64 + Send + Sync> FunctionMiddleware for FunctionMeter
}
}

/// Get the remaining points in an `Instance`.
/// Get the remaining points in an [`Instance`][wasmer::Instance].
///
/// This can be used in a headless engine after an ahead-of-time compilation
/// as all required state lives in the instance.
/// Note: This can be used in a headless engine after an ahead-of-time
/// compilation as all required state lives in the instance.
///
/// # Panic
///
/// The instance Module must have been processed with the [`Metering`] middleware
/// at compile time, otherwise this will panic.
/// The [`Instance`][wasmer::Instance) must have been processed with
/// the [`Metering`] middleware at compile time, otherwise this will
/// panic.
///
/// # Example
///
/// ```rust
/// use wasmer::Instance;
/// use wasmer_middlewares::metering::{get_remaining_points, MeteringPoints};
///
/// /// Check whether the instance can continue to run based on the
/// /// number of remaining points.
/// fn can_continue_to_run(instance: &Instance) -> bool {
/// matches!(get_remaining_points(instance), MeteringPoints::Remaining(points) if points > 0)
/// }
/// ```
pub fn get_remaining_points(instance: &Instance) -> MeteringPoints {
let exhausted: i32 = instance
.exports
Expand All @@ -258,15 +315,32 @@ pub fn get_remaining_points(instance: &Instance) -> MeteringPoints {
MeteringPoints::Remaining(points)
}

/// Set the provided remaining points in an `Instance`.
/// Set the new provided remaining points in an
/// [`Instance`][wasmer::Instance].
///
/// This can be used in a headless engine after an ahead-of-time compilation
/// as all required state lives in the instance.
/// Note: This can be used in a headless engine after an ahead-of-time
/// compilation as all required state lives in the instance.
///
/// # Panic
///
/// The instance Module must have been processed with the [`Metering`] middleware
/// at compile time, otherwise this will panic.
/// The given [`Instance`][wasmer::Instance] must have been processed
/// with the [`Metering`] middleware at compile time, otherwise this
/// will panic.
///
/// # Example
///
/// ```rust
/// use wasmer::Instance;
/// use wasmer_middlewares::metering::set_remaining_points;
///
/// fn update_remaining_points(instance: &Instance) {
/// // The new limit.
/// let new_limit = 10;
///
/// // Update the remaining points to the `new_limit`.
/// set_remaining_points(instance, new_limit);
/// }
/// ```
pub fn set_remaining_points(instance: &Instance, points: u64) {
instance
.exports
Expand Down

0 comments on commit 0ca884d

Please sign in to comment.