Skip to content

Instantly share code, notes, and snippets.

@silen-z
Created December 20, 2020 22:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save silen-z/61bca05256d886a497126b27b2893557 to your computer and use it in GitHub Desktop.
Save silen-z/61bca05256d886a497126b27b2893557 to your computer and use it in GitHub Desktop.
use std::sync::{Arc, RwLock};
use actix_web::{get, post, web, App, Error, HttpServer};
use rkv::backend::{SafeMode, SafeModeDatabase, SafeModeEnvironment};
use rkv::{Manager, Rkv, SingleStore, StoreOptions, Value};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct SomeData {
number: u32,
string: String,
}
struct RkvStore {
manager: Arc<RwLock<Rkv<SafeModeEnvironment>>>,
store: SingleStore<SafeModeDatabase>,
}
impl RkvStore {
fn new() -> Self {
let path = std::env::current_dir().unwrap();
let mut manager = Manager::<SafeModeEnvironment>::singleton().write().unwrap();
let created_arc = manager
.get_or_create(path.as_ref(), Rkv::new::<SafeMode>)
.unwrap();
let store = {
let env = created_arc.read().unwrap();
env.open_single("mydb", StoreOptions::create()).unwrap()
};
RkvStore {
manager: created_arc,
store,
}
}
}
#[post("/{key}")]
async fn save_value(
params: web::Path<(String,)>,
data: web::Json<SomeData>,
rkv: web::Data<RkvStore>,
) -> Result<String, Error> {
let (key,) = params.into_inner();
let env = rkv.manager.read()?;
let mut writer = env.write().unwrap();
let encoded = bincode::serialize(&data.into_inner()).unwrap();
rkv.store
.put(&mut writer, &key, &Value::Blob(&encoded))
.unwrap();
writer.commit().unwrap();
Ok("value saved".to_owned())
}
#[get("/{key}")]
async fn load_value(params: web::Path<(String,)>, rkv: web::Data<RkvStore>) -> String {
let (key,) = params.into_inner();
let env = rkv.manager.read().unwrap();
let reader = env.read().unwrap();
match rkv.store.get(&reader, &key).unwrap() {
Some(Value::Blob(encoded)) => {
let data: SomeData = bincode::deserialize(encoded).unwrap();
format!("found {:?}!", data)
}
Some(_) => panic!(),
None => "no value found".to_owned(),
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.data(RkvStore::new())
.service(save_value)
.service(load_value)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment