Merge pull request #343 from matthiasbeyer/libimagstorestdhook/flock
Libimagstorestdhook/flock
This commit is contained in:
commit
c3618ecfde
3 changed files with 130 additions and 0 deletions
|
@ -6,6 +6,7 @@ authors = ["Matthias Beyer <mail@beyermatthias.de>"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
toml = "0.1.25"
|
toml = "0.1.25"
|
||||||
log = "0.3.5"
|
log = "0.3.5"
|
||||||
|
fs2 = "0.2.3"
|
||||||
|
|
||||||
[dependencies.libimagstore]
|
[dependencies.libimagstore]
|
||||||
path = "../libimagstore"
|
path = "../libimagstore"
|
||||||
|
|
127
libimagstorestdhook/src/flock.rs
Normal file
127
libimagstorestdhook/src/flock.rs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
use std::io::Result as IoResult;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use toml::Value;
|
||||||
|
|
||||||
|
use fs2::FileExt;
|
||||||
|
|
||||||
|
use libimagstore::hook::Hook;
|
||||||
|
use libimagstore::hook::accessor::HookDataAccessor as HDA;
|
||||||
|
use libimagstore::hook::accessor::HookDataAccessorProvider;
|
||||||
|
use libimagstore::hook::accessor::StoreIdAccessor;
|
||||||
|
use libimagstore::hook::accessor::MutableHookDataAccessor;
|
||||||
|
use libimagstore::hook::accessor::NonMutableHookDataAccessor;
|
||||||
|
use libimagstore::hook::result::HookResult;
|
||||||
|
use libimagstore::hook::error::{HookError, HookErrorKind};
|
||||||
|
use libimagstore::storeid::StoreId;
|
||||||
|
use libimagstore::store::FileLockEntry;
|
||||||
|
use libimagstore::store::Entry;
|
||||||
|
|
||||||
|
trait EntryFlock {
|
||||||
|
fn lock(&self, store_location: &PathBuf) -> IoResult<()>;
|
||||||
|
fn unlock(&self, store_location: &PathBuf) -> IoResult<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntryFlock for Entry {
|
||||||
|
|
||||||
|
fn lock(&self, store_location: &PathBuf) -> IoResult<()> {
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
|
let mut location = store_location.clone();
|
||||||
|
location.push(self.get_location());
|
||||||
|
|
||||||
|
File::open(location).and_then(|file| file.lock_exclusive())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unlock(&self, store_location: &PathBuf) -> IoResult<()> {
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
|
let mut location = store_location.clone();
|
||||||
|
location.push(self.get_location());
|
||||||
|
|
||||||
|
File::open(location).and_then(|file| file.unlock())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
|
pub enum Action {
|
||||||
|
Lock,
|
||||||
|
Unlock
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_to_str(a: &Action) -> &'static str {
|
||||||
|
match a {
|
||||||
|
&Action::Lock => "lock",
|
||||||
|
&Action::Unlock => "unlock",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FlockUpdateHook {
|
||||||
|
action: Action,
|
||||||
|
store_location: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlockUpdateHook {
|
||||||
|
|
||||||
|
pub fn new(action: Action, store_location: PathBuf) -> FlockUpdateHook {
|
||||||
|
FlockUpdateHook {
|
||||||
|
action: action,
|
||||||
|
store_location: store_location,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hook for FlockUpdateHook {
|
||||||
|
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"stdhook_flock_update"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_config(&mut self, _: &Value) {
|
||||||
|
() // We are not configurable here.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HookDataAccessorProvider for FlockUpdateHook {
|
||||||
|
|
||||||
|
fn accessor(&self) -> HDA {
|
||||||
|
HDA::StoreIdAccess(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StoreIdAccessor for FlockUpdateHook {
|
||||||
|
|
||||||
|
fn access(&self, id: &StoreId) -> HookResult<()> {
|
||||||
|
debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MutableHookDataAccessor for FlockUpdateHook {
|
||||||
|
|
||||||
|
fn access_mut(&self, fle: &mut FileLockEntry) -> HookResult<()> {
|
||||||
|
debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), fle.get_location());
|
||||||
|
fle.lock(&self.store_location)
|
||||||
|
.map_err(|e| HookError::new(HookErrorKind::HookExecutionError, Some(Box::new(e))))
|
||||||
|
.map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NonMutableHookDataAccessor for FlockUpdateHook {
|
||||||
|
|
||||||
|
fn access(&self, fle: &FileLockEntry) -> HookResult<()> {
|
||||||
|
debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), fle.get_location());
|
||||||
|
fle.unlock(&self.store_location)
|
||||||
|
.map_err(|e| HookError::new(HookErrorKind::HookExecutionError, Some(Box::new(e))))
|
||||||
|
.map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -16,8 +16,10 @@
|
||||||
|
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
extern crate toml;
|
extern crate toml;
|
||||||
|
extern crate fs2;
|
||||||
|
|
||||||
extern crate libimagstore;
|
extern crate libimagstore;
|
||||||
|
|
||||||
pub mod debug;
|
pub mod debug;
|
||||||
|
pub mod flock;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue