From 2ad5cb48aa3fc763207d1f8ab9b4c20974f56af7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 26 May 2016 18:40:58 +0200 Subject: [PATCH] Implement store-unload hooks --- libimagstore/src/configuration.rs | 9 ++++++++- libimagstore/src/hook/position.rs | 2 ++ libimagstore/src/store.rs | 21 ++++++++++++++++++++- libimagstorestdhook/src/debug.rs | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/libimagstore/src/configuration.rs b/libimagstore/src/configuration.rs index 33e0a49e..cdad60d2 100644 --- a/libimagstore/src/configuration.rs +++ b/libimagstore/src/configuration.rs @@ -117,7 +117,10 @@ pub fn config_is_valid(config: &Option) -> bool { } match *config { - Some(Value::Table(ref t)) => { has_key_with_string_ary(t, "pre-create-hook-aspects") && + Some(Value::Table(ref t)) => { + has_key_with_string_ary(t, "store-unload-hook-aspects") && + + has_key_with_string_ary(t, "pre-create-hook-aspects") && has_key_with_string_ary(t, "post-create-hook-aspects") && has_key_with_string_ary(t, "pre-retrieve-hook-aspects") && has_key_with_string_ary(t, "post-retrieve-hook-aspects") && @@ -143,6 +146,10 @@ pub fn config_is_valid(config: &Option) -> bool { } } +pub fn get_store_unload_aspect_names(value: &Option) -> Vec { + get_aspect_names_for_aspect_position("store-unload-hook-aspects", value) +} + pub fn get_pre_create_aspect_names(value: &Option) -> Vec { get_aspect_names_for_aspect_position("pre-create-hook-aspects", value) } diff --git a/libimagstore/src/hook/position.rs b/libimagstore/src/hook/position.rs index 6e74436d..0ccb563e 100644 --- a/libimagstore/src/hook/position.rs +++ b/libimagstore/src/hook/position.rs @@ -1,5 +1,7 @@ #[derive(Debug, Clone)] pub enum HookPosition { + StoreUnload, + PreCreate, PostCreate, PreRetrieve, diff --git a/libimagstore/src/store.rs b/libimagstore/src/store.rs index b7013b4d..1ab53093 100644 --- a/libimagstore/src/store.rs +++ b/libimagstore/src/store.rs @@ -171,6 +171,8 @@ pub struct Store { * Registered hooks */ + store_unload_aspects : Arc>>, + pre_create_aspects : Arc>>, post_create_aspects : Arc>>, pre_retrieve_aspects : Arc>>, @@ -216,6 +218,12 @@ impl Store { return Err(SE::new(SEK::StorePathExists, None)); } + let store_unload_aspects = get_store_unload_aspect_names(&store_config) + .into_iter().map(|n| { + let cfg = AspectConfig::get_for(&store_config, n.clone()); + Aspect::new(n, cfg) + }).collect(); + let pre_create_aspects = get_pre_create_aspect_names(&store_config) .into_iter().map(|n| { let cfg = AspectConfig::get_for(&store_config, n.clone()); @@ -265,8 +273,11 @@ impl Store { }).collect(); let store = Store { - location: location, + location: location.clone(), configuration: store_config, + + store_unload_aspects : Arc::new(Mutex::new(store_unload_aspects)), + pre_create_aspects : Arc::new(Mutex::new(pre_create_aspects)), post_create_aspects : Arc::new(Mutex::new(post_create_aspects)), pre_retrieve_aspects : Arc::new(Mutex::new(pre_retrieve_aspects)), @@ -544,6 +555,8 @@ impl Store { debug!(" with aspect: {:?}", aspect_name); let guard = match position { + HookPosition::StoreUnload => self.store_unload_aspects.clone(), + HookPosition::PreCreate => self.pre_create_aspects.clone(), HookPosition::PostCreate => self.post_create_aspects.clone(), HookPosition::PreRetrieve => self.pre_retrieve_aspects.clone(), @@ -649,6 +662,12 @@ impl Drop for Store { * TODO: Unlock them */ fn drop(&mut self) { + let store_id = StoreId::from(self.location.clone()); + if let Err(e) = self.execute_hooks_for_id(self.store_unload_aspects.clone(), &store_id) { + debug!("Store-load hooks execution failed. Cannot create store object."); + warn!("Store Unload Hook error: {:?}", e); + } + debug!("Dropping store"); } diff --git a/libimagstorestdhook/src/debug.rs b/libimagstorestdhook/src/debug.rs index 830c8e3d..9f7bd63e 100644 --- a/libimagstorestdhook/src/debug.rs +++ b/libimagstorestdhook/src/debug.rs @@ -43,6 +43,7 @@ impl HookDataAccessorProvider for DebugHook { use libimagstore::hook::accessor::HookDataAccessor as HDA; match self.position { + HP::StoreUnload | HP::PreCreate | HP::PreRetrieve | HP::PreDelete |