MapReduceWasm is a simple map-reduce framework using Rust. It features distributed multilingual tasks with Wasm Component Model. With the map/reduce interfaces descripting .wit file, tasks can be designed using Rust, Python, C++ or any other language that supports Wasm Component Model.
Build the main framework:
cargo build --releaseBuild multilingual map/reduce task (use word count as an example):
Rust map function:
cd map_wc
cargo install cargo-component
cargo component build --releasePython map function:
cd map_wc_py
pip install componentize-py
componentize-py --wit-path ./map.wit --world mapper componentize app -o map_wc.wasmStart Master server:
cargo run --release -- master localhost:12345 4 ./wasm_file/map_wc.wasm ./wasm_file/reduce_wc.wasm 10Start Worker server:
cargo run --release -- worker localhost:12345Or simply run the executable file with Usage: <server_type> <addr:port> [num_reduces map_wasm_file reduce_wasm_file [timeout_sec]].
All following examples build the map task, reduce task is all the same.
Rust:
cargo component new map_xx --lib && cd map_xxThen update the wit/world.wit with our ./worker/map.wit. Adjust the Cargo.toml as the following:
[package.metadata.component]
package = "component:mapxx"
Then design your own map logic in src/lib.rs:
#[allow(warnings)]
mod bindings;
use bindings::exports::component::mapxx::map::Guest;
struct Component;
#[allow(unused)]
impl Guest for Component {
fn map(key: String, value: String) -> Vec<(String, String)> {
...
return vec![("", "")];
}
}
bindings::export!(Component with_types_in bindings);There might be warnings, that's ok. As long as you build it with the following, the bindings will be generated and all warnings will be nowhere.
cargo component build --releaseFind the compiled Wasm in target/wasm32-wasip1/release/.
Python:
mkdir map_xx && cd map_xx
touch app.pyPlace the map.wit to this folder and create bindings:
componentize-py --wit-path ./map.wit --world mapper bindings .You do not need to generate the bindings in order to componentize in the next step. componentize will generate bindings on-the-fly and bundle them into the produced component.
Then design your own map logic in app.py:
from typing import List
from typing import Tuple
import mapper
class Map(mapper.Mapper):
def map(self, key: str, value: str) -> List[Tuple[str, str]]:
...
return [("", "")]Finally compile our application to a Wasm component using the componentize subcommand:
componentize-py --wit-path ./map.wit --world mapper componentize app -o map_wc.wasmOther language support at guide.
An idea that Wasm is a super light-weight VM which solves the plugin problem.