From 6fe20b8b861c45e674c03bb98648922e161b3cf8 Mon Sep 17 00:00:00 2001 From: Adrian Malacoda Date: Sun, 25 Feb 2018 02:33:04 -0600 Subject: [PATCH] reimplement reconfigure as an event that is transmitted to all modules whenever the config file changes. THis allows reconfiguration to be done in a threadsafe and relatively simple way. --- src/lib.rs | 4 ++-- src/main.rs | 4 ++-- src/modules/lua.rs | 9 +++++---- src/modules/mod.rs | 13 ++++++++----- src/modules/random.rs | 34 ++++++++++++++++++---------------- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c1298a9..1f5b25c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,9 +71,9 @@ impl Tenquestionmarks { Result::Ok(Tenquestionmarks::with_modules(modules)) } - pub fn reconfigure (&mut self, configuration: &Table) { + pub fn reconfigure (&self, configuration: &Table) { for (key, module_configuration) in configuration { - if let (Some(module_configuration_table), Some(ref mut module)) = (module_configuration.as_table(), self.modules.get_mut(key)) { + if let (Some(module_configuration_table), Some(ref module)) = (module_configuration.as_table(), self.modules.get(key)) { module.reconfigure(module_configuration_table.clone()); } } diff --git a/src/main.rs b/src/main.rs index a97b9e2..18e40ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,8 +37,8 @@ fn main () { Ok(tqm) => { info!("tenquestionmarks initialized successfully"); crossbeam::scope(|scope| { - //scope.spawn(move || { - // tqm_mut.reconfigure(&read_config_from_file(&config_file_name)); + //scope.spawn(|| { + // tqm.reconfigure(&read_config_from_file(&config_file_name)); //}); tqm.run(); diff --git a/src/modules/lua.rs b/src/modules/lua.rs index 75b629d..aeea54a 100644 --- a/src/modules/lua.rs +++ b/src/modules/lua.rs @@ -50,10 +50,6 @@ implement_lua_push!(Message, |mut metatable| { }); impl EventLoop for LuaModule { - fn reconfigure (&mut self, configuration: &Table) { - self.variables = configuration.clone(); - } - fn run (&self, _: Box>, receiver: Receiver>) { let mut lua = Lua::new(); lua.openlibs(); @@ -76,6 +72,11 @@ impl EventLoop for LuaModule { match receiver.recv() { Ok(envelope) => { match envelope.event { + Event::Configure { ref configuration } => { + for (key, value) in configuration { + set(&mut lua, key, value); + } + }, Event::Message { ref message } => { let on_message: Option> = lua.get("on_message"); match on_message { diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 5c81444..cf6e284 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -30,9 +30,13 @@ impl Module { self.event_loop.run(sender, receiver); } - pub fn reconfigure (&mut self, configuration: Table) { - self.event_loop.reconfigure(&configuration); - self.config = configuration; + pub fn reconfigure (&self, configuration: Table) { + self.send(Envelope { + from: "reconfigure".to_owned(), + event: Event::Configure { + configuration: configuration + } + }); } pub fn send (&self, event: Envelope) { @@ -74,7 +78,6 @@ impl Module { } } -pub trait EventLoop : Sync { +pub trait EventLoop : Sync + Send { fn run (&self, _: Box>, _: Receiver>) {} - fn reconfigure (&mut self, _: &Table) {} } diff --git a/src/modules/random.rs b/src/modules/random.rs index fe71bb1..02637c7 100644 --- a/src/modules/random.rs +++ b/src/modules/random.rs @@ -12,15 +12,13 @@ use event::{Event, Envelope}; use rand; pub struct RandomModule { - pattern: Regex, - responses: Vec + initial_configuration: Table, } impl RandomModule { pub fn new (_: &Table, configuration: &Table) -> Box { Box::new(RandomModule { - pattern: RandomModule::pattern_from_config(&configuration), - responses: RandomModule::responses_from_config(&configuration) + initial_configuration: configuration.clone() }) } @@ -47,24 +45,28 @@ impl RandomModule { } impl EventLoop for RandomModule { - fn reconfigure (&mut self, configuration: &Table) { - self.pattern = RandomModule::pattern_from_config(&configuration); - self.responses = RandomModule::responses_from_config(&configuration) - } - fn run (&self, _: Box>, receiver: Receiver>) { let mut rng = rand::thread_rng(); + let mut pattern = RandomModule::pattern_from_config(&self.initial_configuration); + let mut responses = RandomModule::responses_from_config(&self.initial_configuration); loop { match receiver.recv() { Ok(envelope) => { - if let Event::Message { ref message } = envelope.event { - debug!("Received message from module {:?}... {:?}", envelope.from, message.content); - if let Some(captures) = self.pattern.captures(&message.content) { - let mut response = String::new(); - captures.expand(&rand::sample(&mut rng, &self.responses, 1)[0], &mut response); - message.reply(&response); - } + match envelope.event { + Event::Configure { ref configuration } => { + pattern = RandomModule::pattern_from_config(configuration); + responses = RandomModule::responses_from_config(configuration); + }, + Event::Message { ref message } => { + debug!("Received message from module {:?}... {:?}", envelope.from, message.content); + if let Some(captures) = pattern.captures(&message.content) { + let mut response = String::new(); + captures.expand(&rand::sample(&mut rng, &responses, 1)[0], &mut response); + message.reply(&response); + } + }, + _ => {} } } Err(error) => { error!("Error {:?}", error) }