Mercurial > lbo > hg > leveldb-rs
changeset 521:c819897ec8fc
Add kvserver example
Just for fun
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 23 Feb 2020 22:59:01 +0100 |
parents | b339b1817b84 |
children | f4bbb33b6b4c |
files | Cargo.toml examples/kvserver/.hgignore examples/kvserver/Cargo.toml examples/kvserver/README.md examples/kvserver/src/main.rs |
diffstat | 5 files changed, 82 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Cargo.toml Sat Feb 22 23:29:55 2020 +0100 +++ b/Cargo.toml Sun Feb 23 22:59:01 2020 +0100 @@ -28,5 +28,5 @@ path = "src/benches/maps_bench.rs" [workspace] -members = ["examples/write-a-lot", "examples/leveldb-tool", "examples/word-analyze"] +members = ["examples/write-a-lot", "examples/leveldb-tool", "examples/word-analyze", "examples/kvserver"]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/kvserver/.hgignore Sun Feb 23 22:59:01 2020 +0100 @@ -0,0 +1,1 @@ +^target/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/kvserver/Cargo.toml Sun Feb 23 22:59:01 2020 +0100 @@ -0,0 +1,11 @@ +[package] +name = "kvserver" +version = "0.1.0" +authors = ["Lewin Bormann <lewin@lewin-bormann.info>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +canteen = "0.5" +rusty-leveldb = { path = "../../" }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/kvserver/README.md Sun Feb 23 22:59:01 2020 +0100 @@ -0,0 +1,10 @@ +# kvserver + +A simplistic Key/Value HTTP server using rusty-leveldb. + +It is not multi-threaded, and achieves around 13'000 ops per second (both +fetching and storing keys) on my somewhat old `Intel(R) Xeon(R) CPU E5-1650 v2 @ +3.50GHz` using `ab`. + +For comparison, writing of random keys directly (in-process) usually happens at +300'000 keys per second.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/kvserver/src/main.rs Sun Feb 23 22:59:01 2020 +0100 @@ -0,0 +1,59 @@ +use canteen; +use rusty_leveldb; + +struct KVService { + db: rusty_leveldb::DB, +} + +static mut STORAGE_SERVICE: Option<std::sync::Mutex<KVService>> = None; + +impl KVService { + fn handle_get(&mut self, req: &canteen::Request) -> canteen::Response { + let key: String = req.get("key"); + + let val = self.db.get(key.as_bytes()); + + let mut rp = canteen::Response::new(); + + rp.set_status(200); + rp.set_content_type("text/plain"); + + if let Some(val) = val { + rp.append(val); + } else { + rp.set_status(404); + } + rp + } + fn handle_put(&mut self, req: &canteen::Request) -> canteen::Response { + let mut rp = canteen::Response::new(); + let key: String = req.get("key"); + let val = &req.payload; + + self.db.put(key.as_bytes(), val.as_ref()).unwrap(); + + rp.set_status(200); + rp.set_content_type("text/plain"); + rp + } +} + +fn get_key_fn(rq: &canteen::Request) -> canteen::Response { + unsafe { STORAGE_SERVICE.as_ref().unwrap().lock().unwrap().handle_get(rq) } +} + +fn put_key_fn(rq: &canteen::Request) -> canteen::Response { + unsafe { STORAGE_SERVICE.as_ref().unwrap().lock().unwrap().handle_put(rq) } +} + +fn main() { + let db = rusty_leveldb::DB::open("httpdb", rusty_leveldb::Options::default()).unwrap(); + let service = KVService { db: db }; + unsafe { STORAGE_SERVICE = Some(std::sync::Mutex::new(service)) }; + + let mut ct = canteen::Canteen::new(); + ct.add_route("/kvs/get/<str:key>", &[canteen::Method::Get], get_key_fn); + ct.add_route("/kvs/put/<str:key>", &[canteen::Method::Put, canteen::Method::Post], put_key_fn); + ct.bind("0.0.0.0:8080"); + ct.run() +}