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.

This commit is contained in:
Adrian Malacoda 2018-02-25 02:33:04 -06:00
parent 9295b603aa
commit 6fe20b8b86
5 changed files with 35 additions and 29 deletions

View File

@ -71,9 +71,9 @@ impl Tenquestionmarks {
Result::Ok(Tenquestionmarks::with_modules(modules)) 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 { 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()); module.reconfigure(module_configuration_table.clone());
} }
} }

View File

@ -37,8 +37,8 @@ fn main () {
Ok(tqm) => { Ok(tqm) => {
info!("tenquestionmarks initialized successfully"); info!("tenquestionmarks initialized successfully");
crossbeam::scope(|scope| { crossbeam::scope(|scope| {
//scope.spawn(move || { //scope.spawn(|| {
// tqm_mut.reconfigure(&read_config_from_file(&config_file_name)); // tqm.reconfigure(&read_config_from_file(&config_file_name));
//}); //});
tqm.run(); tqm.run();

View File

@ -50,10 +50,6 @@ implement_lua_push!(Message, |mut metatable| {
}); });
impl EventLoop for LuaModule { impl EventLoop for LuaModule {
fn reconfigure (&mut self, configuration: &Table) {
self.variables = configuration.clone();
}
fn run (&self, _: Box<ExtSender<Event>>, receiver: Receiver<Arc<Envelope>>) { fn run (&self, _: Box<ExtSender<Event>>, receiver: Receiver<Arc<Envelope>>) {
let mut lua = Lua::new(); let mut lua = Lua::new();
lua.openlibs(); lua.openlibs();
@ -76,6 +72,11 @@ impl EventLoop for LuaModule {
match receiver.recv() { match receiver.recv() {
Ok(envelope) => { Ok(envelope) => {
match envelope.event { match envelope.event {
Event::Configure { ref configuration } => {
for (key, value) in configuration {
set(&mut lua, key, value);
}
},
Event::Message { ref message } => { Event::Message { ref message } => {
let on_message: Option<LuaFunction<_>> = lua.get("on_message"); let on_message: Option<LuaFunction<_>> = lua.get("on_message");
match on_message { match on_message {

View File

@ -30,9 +30,13 @@ impl Module {
self.event_loop.run(sender, receiver); self.event_loop.run(sender, receiver);
} }
pub fn reconfigure (&mut self, configuration: Table) { pub fn reconfigure (&self, configuration: Table) {
self.event_loop.reconfigure(&configuration); self.send(Envelope {
self.config = configuration; from: "reconfigure".to_owned(),
event: Event::Configure {
configuration: configuration
}
});
} }
pub fn send (&self, event: Envelope) { 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<ExtSender<Event>>, _: Receiver<Arc<Envelope>>) {} fn run (&self, _: Box<ExtSender<Event>>, _: Receiver<Arc<Envelope>>) {}
fn reconfigure (&mut self, _: &Table) {}
} }

View File

@ -12,15 +12,13 @@ use event::{Event, Envelope};
use rand; use rand;
pub struct RandomModule { pub struct RandomModule {
pattern: Regex, initial_configuration: Table,
responses: Vec<String>
} }
impl RandomModule { impl RandomModule {
pub fn new (_: &Table, configuration: &Table) -> Box<EventLoop> { pub fn new (_: &Table, configuration: &Table) -> Box<EventLoop> {
Box::new(RandomModule { Box::new(RandomModule {
pattern: RandomModule::pattern_from_config(&configuration), initial_configuration: configuration.clone()
responses: RandomModule::responses_from_config(&configuration)
}) })
} }
@ -47,24 +45,28 @@ impl RandomModule {
} }
impl EventLoop for 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<ExtSender<Event>>, receiver: Receiver<Arc<Envelope>>) { fn run (&self, _: Box<ExtSender<Event>>, receiver: Receiver<Arc<Envelope>>) {
let mut rng = rand::thread_rng(); 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 { loop {
match receiver.recv() { match receiver.recv() {
Ok(envelope) => { Ok(envelope) => {
if let Event::Message { ref message } = envelope.event { match envelope.event {
debug!("Received message from module {:?}... {:?}", envelope.from, message.content); Event::Configure { ref configuration } => {
if let Some(captures) = self.pattern.captures(&message.content) { pattern = RandomModule::pattern_from_config(configuration);
let mut response = String::new(); responses = RandomModule::responses_from_config(configuration);
captures.expand(&rand::sample(&mut rng, &self.responses, 1)[0], &mut response); },
message.reply(&response); 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) } Err(error) => { error!("Error {:?}", error) }