Reimplement hook registration and execution
This commit is contained in:
parent
d6a581e69f
commit
679865464b
1 changed files with 103 additions and 320 deletions
|
@ -23,11 +23,15 @@ use error::{StoreError, StoreErrorKind};
|
||||||
use storeid::{StoreId, StoreIdIterator};
|
use storeid::{StoreId, StoreIdIterator};
|
||||||
use lazyfile::LazyFile;
|
use lazyfile::LazyFile;
|
||||||
|
|
||||||
|
use hook::aspect::Aspect;
|
||||||
use hook::result::HookResult;
|
use hook::result::HookResult;
|
||||||
use hook::accessor::{ MutableHookDataAccessor,
|
use hook::accessor::{ MutableHookDataAccessor,
|
||||||
NonMutableHookDataAccessor,
|
NonMutableHookDataAccessor,
|
||||||
|
StoreIdAccessor,
|
||||||
HookDataAccessor,
|
HookDataAccessor,
|
||||||
HookDataAccessorProvider};
|
HookDataAccessorProvider};
|
||||||
|
use hook::position::HookPosition;
|
||||||
|
use hook::Hook;
|
||||||
|
|
||||||
/// The Result Type returned by any interaction with the store that could fail
|
/// The Result Type returned by any interaction with the store that could fail
|
||||||
pub type Result<T> = RResult<T, StoreError>;
|
pub type Result<T> = RResult<T, StoreError>;
|
||||||
|
@ -105,16 +109,16 @@ pub struct Store {
|
||||||
* Registered hooks
|
* Registered hooks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pre_read_hooks : Arc<Mutex<Vec<Box<PreReadHook>>>>,
|
pre_read_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
post_read_hooks : Arc<Mutex<Vec<Box<PostReadHook>>>>,
|
post_read_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
pre_create_hooks : Arc<Mutex<Vec<Box<PreCreateHook>>>>,
|
pre_create_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
post_create_hooks : Arc<Mutex<Vec<Box<PostCreateHook>>>>,
|
post_create_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
pre_retrieve_hooks : Arc<Mutex<Vec<Box<PreRetrieveHook>>>>,
|
pre_retrieve_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
post_retrieve_hooks : Arc<Mutex<Vec<Box<PostRetrieveHook>>>>,
|
post_retrieve_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
pre_update_hooks : Arc<Mutex<Vec<Box<PreUpdateHook>>>>,
|
pre_update_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
post_update_hooks : Arc<Mutex<Vec<Box<PostUpdateHook>>>>,
|
post_update_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
pre_delete_hooks : Arc<Mutex<Vec<Box<PreDeleteHook>>>>,
|
pre_delete_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
post_delete_hooks : Arc<Mutex<Vec<Box<PostDeleteHook>>>>,
|
post_delete_aspects : Arc<Mutex<Vec<Aspect>>>,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal Path->File cache map
|
* Internal Path->File cache map
|
||||||
|
@ -151,16 +155,16 @@ impl Store {
|
||||||
debug!("Store building succeeded");
|
debug!("Store building succeeded");
|
||||||
Ok(Store {
|
Ok(Store {
|
||||||
location: location,
|
location: location,
|
||||||
pre_read_hooks : Arc::new(Mutex::new(vec![])),
|
pre_read_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
post_read_hooks : Arc::new(Mutex::new(vec![])),
|
post_read_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
pre_create_hooks : Arc::new(Mutex::new(vec![])),
|
pre_create_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
post_create_hooks : Arc::new(Mutex::new(vec![])),
|
post_create_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
pre_retrieve_hooks : Arc::new(Mutex::new(vec![])),
|
pre_retrieve_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
post_retrieve_hooks : Arc::new(Mutex::new(vec![])),
|
post_retrieve_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
pre_update_hooks : Arc::new(Mutex::new(vec![])),
|
pre_update_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
post_update_hooks : Arc::new(Mutex::new(vec![])),
|
post_update_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
pre_delete_hooks : Arc::new(Mutex::new(vec![])),
|
pre_delete_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
post_delete_hooks : Arc::new(Mutex::new(vec![])),
|
post_delete_aspects : Arc::new(Mutex::new(vec![])),
|
||||||
entries: Arc::new(RwLock::new(HashMap::new())),
|
entries: Arc::new(RwLock::new(HashMap::new())),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -176,7 +180,7 @@ impl Store {
|
||||||
/// Creates the Entry at the given location (inside the entry)
|
/// Creates the Entry at the given location (inside the entry)
|
||||||
pub fn create<'a>(&'a self, id: StoreId) -> Result<FileLockEntry<'a>> {
|
pub fn create<'a>(&'a self, id: StoreId) -> Result<FileLockEntry<'a>> {
|
||||||
let id = self.storify_id(id);
|
let id = self.storify_id(id);
|
||||||
if let Err(e) = self.execute_pre_create_hooks(&id) {
|
if let Err(e) = self.execute_hooks_for_id(self.pre_create_aspects.clone(), &id) {
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,14 +198,17 @@ impl Store {
|
||||||
se
|
se
|
||||||
});
|
});
|
||||||
|
|
||||||
self.execute_post_create_hooks(FileLockEntry::new(self, Entry::new(id.clone()), id))
|
let mut fle = FileLockEntry::new(self, Entry::new(id.clone()), id);
|
||||||
|
self.execute_hooks_for_mut_file(self.post_create_aspects.clone(), &mut fle)
|
||||||
|
.map_err(|e| StoreError::new(StoreErrorKind::PostHookExecuteError, Some(Box::new(e))))
|
||||||
|
.map(|_| fle)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrow a given Entry. When the `FileLockEntry` is either `update`d or
|
/// Borrow a given Entry. When the `FileLockEntry` is either `update`d or
|
||||||
/// dropped, the new Entry is written to disk
|
/// dropped, the new Entry is written to disk
|
||||||
pub fn retrieve<'a>(&'a self, id: StoreId) -> Result<FileLockEntry<'a>> {
|
pub fn retrieve<'a>(&'a self, id: StoreId) -> Result<FileLockEntry<'a>> {
|
||||||
let id = self.storify_id(id);
|
let id = self.storify_id(id);
|
||||||
if let Err(e) = self.execute_pre_retrieve_hooks(&id) {
|
if let Err(e) = self.execute_hooks_for_id(self.pre_retrieve_aspects.clone(), &id) {
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +221,15 @@ impl Store {
|
||||||
se.status = StoreEntryStatus::Borrowed;
|
se.status = StoreEntryStatus::Borrowed;
|
||||||
entry
|
entry
|
||||||
})
|
})
|
||||||
.and_then(|e| self.execute_post_retrieve_hooks(FileLockEntry::new(self, e, id)))
|
.map(|e| FileLockEntry::new(self, e, id))
|
||||||
|
.and_then(|mut fle| {
|
||||||
|
if let Err(e) = self.execute_hooks_for_mut_file(self.pre_retrieve_aspects.clone(), &mut fle) {
|
||||||
|
Err(StoreError::new(StoreErrorKind::HookExecutionError, Some(Box::new(e))))
|
||||||
|
} else {
|
||||||
|
Ok(fle)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate over all StoreIds for one module name
|
/// Iterate over all StoreIds for one module name
|
||||||
|
@ -224,7 +239,7 @@ impl Store {
|
||||||
|
|
||||||
/// Return the `FileLockEntry` and write to disk
|
/// Return the `FileLockEntry` and write to disk
|
||||||
pub fn update<'a>(&'a self, mut entry: FileLockEntry<'a>) -> Result<()> {
|
pub fn update<'a>(&'a self, mut entry: FileLockEntry<'a>) -> Result<()> {
|
||||||
if let Err(e) = self.execute_pre_update_hooks(&mut entry) {
|
if let Err(e) = self.execute_hooks_for_mut_file(self.pre_update_aspects.clone(), &mut entry) {
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,8 +247,7 @@ impl Store {
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.execute_post_update_hooks(entry)
|
self.execute_hooks_for_mut_file(self.post_update_aspects.clone(), &mut entry)
|
||||||
.map(|_| ())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal method to write to the filesystem store.
|
/// Internal method to write to the filesystem store.
|
||||||
|
@ -284,7 +298,7 @@ impl Store {
|
||||||
/// Delete an entry
|
/// Delete an entry
|
||||||
pub fn delete(&self, id: StoreId) -> Result<()> {
|
pub fn delete(&self, id: StoreId) -> Result<()> {
|
||||||
let id = self.storify_id(id);
|
let id = self.storify_id(id);
|
||||||
if let Err(e) = self.execute_pre_delete_hooks(&id) {
|
if let Err(e) = self.execute_hooks_for_id(self.pre_delete_aspects.clone(), &id) {
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +320,7 @@ impl Store {
|
||||||
return Err(StoreError::new(StoreErrorKind::FileError, Some(Box::new(e))));
|
return Err(StoreError::new(StoreErrorKind::FileError, Some(Box::new(e))));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.execute_post_delete_hooks(&id)
|
self.execute_hooks_for_id(self.post_delete_aspects.clone(), &id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the path where this store is on the disk
|
/// Gets the path where this store is on the disk
|
||||||
|
@ -314,327 +328,96 @@ impl Store {
|
||||||
&self.location
|
&self.location
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_pre_read_hook(&self, h: Box<PreReadHook>) -> Result<()> {
|
pub fn register_hook(&mut self,
|
||||||
debug!("Registering pre-read hook: {:?}", h);
|
position: HookPosition,
|
||||||
self.pre_read_hooks
|
aspect_name: &String,
|
||||||
.deref()
|
h: Box<Hook>)
|
||||||
.lock()
|
-> Result<()>
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_post_read_hook(&self, h: Box<PostReadHook>) -> Result<()> {
|
|
||||||
debug!("Registering post-read hook: {:?}", h);
|
|
||||||
self.post_read_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_pre_create_hook(&self, h: Box<PreCreateHook>) -> Result<()> {
|
|
||||||
debug!("Registering pre-create hook: {:?}", h);
|
|
||||||
self.pre_create_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_post_create_hook(&self, h: Box<PostCreateHook>) -> Result<()> {
|
|
||||||
debug!("Registering post-create hook: {:?}", h);
|
|
||||||
self.post_create_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_pre_retrieve_hook(&self, h: Box<PreRetrieveHook>) -> Result<()> {
|
|
||||||
debug!("Registering pre-retrieve hook: {:?}", h);
|
|
||||||
self.pre_retrieve_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_post_retrieve_hook(&self, h: Box<PostRetrieveHook>) -> Result<()> {
|
|
||||||
debug!("Registering post-retrieve hook: {:?}", h);
|
|
||||||
self.post_retrieve_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_pre_update_hook(&self, h: Box<PreUpdateHook>) -> Result<()> {
|
|
||||||
debug!("Registering pre-update hook: {:?}", h);
|
|
||||||
self.pre_update_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_post_update_hook(&self, h: Box<PostUpdateHook>) -> Result<()> {
|
|
||||||
debug!("Registering post-update hook: {:?}", h);
|
|
||||||
self.post_update_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn register_pre_delete_hook(&self, h: Box<PreDeleteHook>) -> Result<()> {
|
|
||||||
debug!("Registering pre-delete hook: {:?}", h);
|
|
||||||
self.pre_delete_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_post_delete_hook(&self, h: Box<PostDeleteHook>) -> Result<()> {
|
|
||||||
debug!("Registering post-delete hook: {:?}", h);
|
|
||||||
self.post_delete_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None))
|
|
||||||
// TODO: cause: Some(Box::new(e))
|
|
||||||
.map(|mut guard| guard.deref_mut().push(h))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute_pre_read_hooks(&self, id: &StoreId) -> Result<()> {
|
|
||||||
debug!("Execute pre-read hooks: {:?}", self.pre_read_hooks);
|
|
||||||
let guard = self.pre_read_hooks.deref().lock();
|
|
||||||
if guard.is_err() { return Err(StoreError::new(StoreErrorKind::PreHookExecuteError, None)) }
|
|
||||||
|
|
||||||
guard.unwrap().deref().iter()
|
|
||||||
.fold(Ok(()), |acc, hook| {
|
|
||||||
debug!("[Hook][exec]: {:?}", hook);
|
|
||||||
acc.and_then(|_| hook.pre_read(id))
|
|
||||||
})
|
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PreHookExecuteError, Some(Box::new(e))))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute_post_read_hooks<'a>(&'a self, fle: FileLockEntry<'a>)
|
|
||||||
-> Result<FileLockEntry<'a>>
|
|
||||||
{
|
{
|
||||||
debug!("Execute post-read hooks: {:?}", self.post_read_hooks);
|
debug!("Registering hook: {:?}", h);
|
||||||
self.post_read_hooks
|
debug!(" in position: {:?}", position);
|
||||||
|
debug!(" with aspect: {:?}", aspect_name);
|
||||||
|
|
||||||
|
let mut guard = match position {
|
||||||
|
HookPosition::PreRead => self.pre_read_aspects.clone(),
|
||||||
|
HookPosition::PostRead => self.post_read_aspects.clone(),
|
||||||
|
HookPosition::PreCreate => self.pre_create_aspects.clone(),
|
||||||
|
HookPosition::PostCreate => self.post_create_aspects.clone(),
|
||||||
|
HookPosition::PreRetrieve => self.pre_retrieve_aspects.clone(),
|
||||||
|
HookPosition::PostRetrieve => self.post_retrieve_aspects.clone(),
|
||||||
|
HookPosition::PreUpdate => self.pre_update_aspects.clone(),
|
||||||
|
HookPosition::PostUpdate => self.post_update_aspects.clone(),
|
||||||
|
HookPosition::PreDelete => self.pre_delete_aspects.clone(),
|
||||||
|
HookPosition::PostDelete => self.post_delete_aspects.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut guard = guard
|
||||||
.deref()
|
.deref()
|
||||||
.lock()
|
.lock()
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PostHookExecuteError, None))
|
.map_err(|_| StoreError::new(StoreErrorKind::HookRegisterError, None));
|
||||||
.and_then(|guard| {
|
|
||||||
let accessors = guard.deref().iter().map(|h| h.accessor()).collect();
|
if guard.is_err() {
|
||||||
self.execute_hook_accessors(accessors, fle)
|
return Err(StoreError::new(StoreErrorKind::HookRegisterError,
|
||||||
.map_err(|e| {
|
Some(Box::new(guard.err().unwrap()))));
|
||||||
StoreError::new(StoreErrorKind::PostHookExecuteError, Some(Box::new(e)))
|
}
|
||||||
})
|
let mut guard = guard.unwrap();
|
||||||
})
|
for mut aspect in guard.deref_mut() {
|
||||||
|
if aspect.name().clone() == aspect_name.clone() {
|
||||||
|
aspect.register_hook(h);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Err(StoreError::new(StoreErrorKind::HookRegisterError, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_hook_accessors<'a>(&self,
|
fn execute_hooks_for_id(&self,
|
||||||
accessors: Vec<Box<HookDataAccessor>>,
|
aspects: Arc<Mutex<Vec<Aspect>>>,
|
||||||
fle: FileLockEntry<'a>)
|
id: &StoreId)
|
||||||
-> Result<FileLockEntry<'a>>
|
-> Result<()>
|
||||||
{
|
{
|
||||||
use std::thread;
|
let guard = aspects.deref().lock();
|
||||||
use std::thread::JoinHandle;
|
|
||||||
|
|
||||||
use hook::accessor::HookDataAccessor as HDA;
|
|
||||||
use error::StoreError as SE;
|
|
||||||
use error::StoreErrorKind as SEK;
|
|
||||||
|
|
||||||
let iter_par = accessors.iter().all(|a| {
|
|
||||||
match a.deref() { &HDA::NonMutableAccess(_) => true, _ => false }
|
|
||||||
});
|
|
||||||
debug!("Parallel execution of hooks = {}", iter_par);
|
|
||||||
|
|
||||||
if iter_par {
|
|
||||||
debug!("Parallel execution of hooks not implemented yet");
|
|
||||||
let threads : Vec<Result<()>> = accessors
|
|
||||||
.iter()
|
|
||||||
.map(|accessor| {
|
|
||||||
crossbeam::scope(|scope| {
|
|
||||||
scope.spawn(|| {
|
|
||||||
match accessor.deref() {
|
|
||||||
&HDA::NonMutableAccess(ref accessor) => accessor.access(&fle),
|
|
||||||
_ => panic!("There shouldn't be a MutableHookDataAcceessor but there is"),
|
|
||||||
}
|
|
||||||
.map_err(|e| ()) // TODO: We're losing the error cause here
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.map(|item| item.join().map_err(|_| SE::new(SEK::HookExecutionError, None)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
threads
|
|
||||||
.into_iter()
|
|
||||||
.fold(Ok(fle), |acc, elem| {
|
|
||||||
acc.and_then(|a| {
|
|
||||||
elem.map(|_| a)
|
|
||||||
.map_err(|_| SE::new(SEK::HookExecutionError, None))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
accessors.into_iter().fold(Ok(fle), move |acc, accessor| {
|
|
||||||
match accessor.deref() {
|
|
||||||
&HDA::MutableAccess(ref accessor) => {
|
|
||||||
match acc {
|
|
||||||
Ok(mut fle) => accessor
|
|
||||||
.access_mut(&mut fle)
|
|
||||||
.and(Ok(fle))
|
|
||||||
.map_err(|e| SE::new(SEK::HookExecutionError, Some(Box::new(e)))),
|
|
||||||
Err(e) => Err(SE::new(SEK::HookExecutionError, Some(Box::new(e)))),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
&HDA::NonMutableAccess(ref accessor) => {
|
|
||||||
match acc {
|
|
||||||
Ok(mut fle) => accessor
|
|
||||||
.access(&fle)
|
|
||||||
.and(Ok(fle))
|
|
||||||
.map_err(|e| SE::new(SEK::HookExecutionError, Some(Box::new(e)))),
|
|
||||||
Err(e) => Err(SE::new(SEK::HookExecutionError, Some(Box::new(e)))),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => Err(StoreError::new(StoreErrorKind::HookExecutionError, None)),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute_pre_create_hooks(&self, id: &StoreId) -> Result<()> {
|
|
||||||
debug!("Execute pre-create hooks: {:?}", self.pre_create_hooks);
|
|
||||||
let guard = self.pre_create_hooks.deref().lock();
|
|
||||||
if guard.is_err() { return Err(StoreError::new(StoreErrorKind::PreHookExecuteError, None)) }
|
if guard.is_err() { return Err(StoreError::new(StoreErrorKind::PreHookExecuteError, None)) }
|
||||||
|
|
||||||
guard.unwrap().deref().iter()
|
guard.unwrap().deref().iter()
|
||||||
.fold(Ok(()), |acc, hook| {
|
.fold(Ok(()), |acc, aspect| {
|
||||||
debug!("[Hook][exec]: {:?}", hook);
|
debug!("[Aspect][exec]: {:?}", aspect);
|
||||||
acc.and_then(|_| hook.pre_create(id))
|
acc.and_then(|_| (aspect as &StoreIdAccessor).access(id))
|
||||||
})
|
})
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PreHookExecuteError, Some(Box::new(e))))
|
.map_err(|e| StoreError::new(StoreErrorKind::PreHookExecuteError, Some(Box::new(e))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_post_create_hooks<'a>(&'a self, fle: FileLockEntry<'a>)
|
fn execute_hooks_for_mut_file(&self,
|
||||||
-> Result<FileLockEntry<'a>>
|
aspects: Arc<Mutex<Vec<Aspect>>>,
|
||||||
|
fle: &mut FileLockEntry)
|
||||||
|
-> Result<()>
|
||||||
{
|
{
|
||||||
debug!("Execute post-create hooks: {:?}", self.post_create_hooks);
|
let guard = aspects.deref().lock();
|
||||||
self.post_create_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PostHookExecuteError, None))
|
|
||||||
.and_then(|guard| {
|
|
||||||
let accessors = guard.deref().iter().map(|h| h.accessor()).collect();
|
|
||||||
self.execute_hook_accessors(accessors, fle)
|
|
||||||
.map_err(|e| {
|
|
||||||
StoreError::new(StoreErrorKind::PostHookExecuteError, Some(Box::new(e)))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute_pre_retrieve_hooks(&self, id: &StoreId) -> Result<()> {
|
|
||||||
debug!("Execute pre-retrieve hooks: {:?}", self.pre_retrieve_hooks);
|
|
||||||
let guard = self.pre_retrieve_hooks.deref().lock();
|
|
||||||
if guard.is_err() { return Err(StoreError::new(StoreErrorKind::PreHookExecuteError, None)) }
|
if guard.is_err() { return Err(StoreError::new(StoreErrorKind::PreHookExecuteError, None)) }
|
||||||
|
|
||||||
guard.unwrap().deref().iter()
|
guard.unwrap().deref().iter()
|
||||||
.fold(Ok(()), |acc, hook| {
|
.fold(Ok(()), |acc, aspect| {
|
||||||
debug!("[Hook][exec]: {:?}", hook);
|
debug!("[Aspect][exec]: {:?}", aspect);
|
||||||
acc.and_then(|_| hook.pre_retrieve(id))
|
acc.and_then(|_| aspect.access_mut(fle))
|
||||||
})
|
})
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PreHookExecuteError, Some(Box::new(e))))
|
.map_err(|e| StoreError::new(StoreErrorKind::PreHookExecuteError, Some(Box::new(e))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_post_retrieve_hooks<'a>(&'a self, fle: FileLockEntry<'a>)
|
fn execute_hooks_for_file(&self,
|
||||||
-> Result<FileLockEntry<'a>>
|
aspects: Arc<Mutex<Vec<Aspect>>>,
|
||||||
|
fle: &FileLockEntry)
|
||||||
|
-> Result<()>
|
||||||
{
|
{
|
||||||
debug!("Execute post-retrieve hooks: {:?}", self.post_retrieve_hooks);
|
let guard = aspects.deref().lock();
|
||||||
self.post_retrieve_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PostHookExecuteError, None))
|
|
||||||
.and_then(|guard| {
|
|
||||||
let accessors = guard.deref().iter().map(|h| h.accessor()).collect();
|
|
||||||
self.execute_hook_accessors(accessors, fle)
|
|
||||||
.map_err(|e| {
|
|
||||||
StoreError::new(StoreErrorKind::PostHookExecuteError, Some(Box::new(e)))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute_pre_update_hooks(&self, fle: &mut FileLockEntry) -> Result<()> {
|
|
||||||
debug!("Execute pre-update hooks: {:?}", self.pre_update_hooks);
|
|
||||||
let guard = self.pre_update_hooks.deref().lock();
|
|
||||||
if guard.is_err() { return Err(StoreError::new(StoreErrorKind::PreHookExecuteError, None)) }
|
if guard.is_err() { return Err(StoreError::new(StoreErrorKind::PreHookExecuteError, None)) }
|
||||||
|
|
||||||
guard.unwrap().deref().iter()
|
guard.unwrap().deref().iter()
|
||||||
.fold(Ok(()), |acc, hook| {
|
.fold(Ok(()), |acc, aspect| {
|
||||||
debug!("[Hook][exec]: {:?}", hook);
|
debug!("[Aspect][exec]: {:?}", aspect);
|
||||||
acc.and_then(|_| hook.pre_update(fle))
|
acc.and_then(|_| (aspect as &NonMutableHookDataAccessor).access(fle))
|
||||||
})
|
})
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PreHookExecuteError, Some(Box::new(e))))
|
.map_err(|e| StoreError::new(StoreErrorKind::PreHookExecuteError, Some(Box::new(e))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_post_update_hooks<'a>(&self, fle: FileLockEntry<'a>) -> Result<FileLockEntry<'a>> {
|
|
||||||
debug!("Execute post-update hooks: {:?}", self.post_update_hooks);
|
|
||||||
self.post_update_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PostHookExecuteError, None))
|
|
||||||
.and_then(|guard| {
|
|
||||||
let accessors = guard.deref().iter().map(|h| h.accessor()).collect();
|
|
||||||
self.execute_hook_accessors(accessors, fle)
|
|
||||||
.map_err(|e| {
|
|
||||||
StoreError::new(StoreErrorKind::PostHookExecuteError, Some(Box::new(e)))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute_pre_delete_hooks(&self, id: &StoreId) -> Result<()> {
|
|
||||||
debug!("Execute pre-delete hooks: {:?}", self.pre_delete_hooks);
|
|
||||||
let guard = self.pre_delete_hooks.deref().lock();
|
|
||||||
if guard.is_err() { return Err(StoreError::new(StoreErrorKind::PreHookExecuteError, None)) }
|
|
||||||
|
|
||||||
guard.unwrap().deref().iter()
|
|
||||||
.fold(Ok(()), |acc, hook| {
|
|
||||||
debug!("[Hook][exec]: {:?}", hook);
|
|
||||||
acc.and_then(|_| hook.pre_delete(id))
|
|
||||||
})
|
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PreHookExecuteError, Some(Box::new(e))))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute_post_delete_hooks(&self, id: &StoreId) -> Result<()> {
|
|
||||||
debug!("Execute post-delete hooks: {:?}", self.post_delete_hooks);
|
|
||||||
self.post_delete_hooks
|
|
||||||
.deref()
|
|
||||||
.lock()
|
|
||||||
.map_err(|e| StoreError::new(StoreErrorKind::PostHookExecuteError, None))
|
|
||||||
.and_then(|guard| {
|
|
||||||
guard.deref()
|
|
||||||
.iter()
|
|
||||||
.fold(Ok(()), move |res, hook| {
|
|
||||||
debug!("[Hook][exec]: {:?}", hook);
|
|
||||||
res.and_then(|_| hook.post_delete(id))
|
|
||||||
})
|
|
||||||
.map_err(|e| {
|
|
||||||
StoreError::new(StoreErrorKind::PostHookExecuteError, Some(Box::new(e)))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Store {
|
impl Drop for Store {
|
||||||
|
|
Loading…
Reference in a new issue