Remove actix, move state to RwLock. Update dependencies.

This commit is contained in:
projectmoon 2020-10-17 13:30:07 +00:00
parent 1ef3b50a6e
commit d1c4a01871
8 changed files with 131 additions and 640 deletions

649
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -22,22 +22,12 @@ async-trait = "0.1"
url = "2.1" url = "2.1"
dirs = "3.0" dirs = "3.0"
indoc = "1.0" indoc = "1.0"
actix = "0.10"
actix-rt = "1.1"
combine = "4.3" combine = "4.3"
sled = "0.34" sled = "0.34"
zerocopy = "0.3" zerocopy = "0.3"
byteorder = "1.3" byteorder = "1.3"
futures = "0.3" futures = "0.3"
# The versioning of the matrix SDK follows its Cargo.toml. The SDK and
# macros are on master, but it imports the common and base from 0.1.0.
# https://github.com/matrix-org/matrix-rust-sdk/blob/master/matrix_sdk/Cargo.toml
matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk", rev = "master" } matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk", rev = "master" }
matrix-sdk-common-macros = { git = "https://github.com/matrix-org/matrix-rust-sdk", rev = "master" }
matrix-sdk-common = { git = "https://github.com/matrix-org/matrix-rust-sdk", rev = "0.1.0" }
matrix-sdk-base = { git = "https://github.com/matrix-org/matrix-rust-sdk", rev = "0.1.0", default_features = false }
[dependencies.serde] [dependencies.serde]
version = "1" version = "1"
@ -45,7 +35,7 @@ features = ['derive']
[dependencies.tokio] [dependencies.tokio]
version = "0.2" version = "0.2"
features = ["rt-core", "rt-util", "macros", "time", "signal"] features = [ "full" ]
[dev-dependencies] [dev-dependencies]
tempfile = "3.1" tempfile = "3.1"

View File

@ -1,25 +0,0 @@
use crate::config::Config;
use crate::db::Database;
use actix::prelude::*;
use state::DiceBotState;
use std::sync::Arc;
pub mod state;
pub struct Actors {
global_state: Addr<DiceBotState>,
}
impl Actors {
pub fn new(config: &Arc<Config>, _db: &Database) -> Actors {
let global_state = DiceBotState::new(&config);
Actors {
global_state: global_state.start(),
}
}
pub fn global_state(&self) -> Addr<DiceBotState> {
self.global_state.clone()
}
}

View File

@ -1,16 +1,16 @@
//Needed for nested Result handling from tokio. Probably can go away after 1.47.0. //Needed for nested Result handling from tokio. Probably can go away after 1.47.0.
#![type_length_limit = "7605144"] #![type_length_limit = "7605144"]
use actix::prelude::*;
use chronicle_dicebot::actors::Actors;
use chronicle_dicebot::bot::DiceBot; use chronicle_dicebot::bot::DiceBot;
use chronicle_dicebot::config::*; use chronicle_dicebot::config::*;
use chronicle_dicebot::db::Database; use chronicle_dicebot::db::Database;
use chronicle_dicebot::error::BotError; use chronicle_dicebot::error::BotError;
use chronicle_dicebot::state::DiceBotState;
use env_logger::Env; use env_logger::Env;
use log::error; use log::error;
use std::sync::Arc; use std::sync::{Arc, RwLock};
use tokio::prelude::*;
#[actix_rt::main] #[tokio::main]
async fn main() { async fn main() {
env_logger::from_env(Env::default().default_filter_or("chronicle_dicebot=info,dicebot=info")) env_logger::from_env(Env::default().default_filter_or("chronicle_dicebot=info,dicebot=info"))
.init(); .init();
@ -28,13 +28,12 @@ async fn run() -> Result<(), BotError> {
let cfg = Arc::new(read_config(config_path)?); let cfg = Arc::new(read_config(config_path)?);
let db = Database::new(&sled::open(cfg.database_path())?); let db = Database::new(&sled::open(cfg.database_path())?);
let actors = Actors::new(&cfg, &db); let state = Arc::new(RwLock::new(DiceBotState::new(&cfg)));
match DiceBot::new(&cfg, actors, &db) { match DiceBot::new(&cfg, &state, &db) {
Ok(bot) => bot.run().await?, Ok(bot) => bot.run().await?,
Err(e) => println!("Error connecting: {:?}", e), Err(e) => println!("Error connecting: {:?}", e),
}; };
System::current().stop();
Ok(()) Ok(())
} }

View File

@ -1,10 +1,10 @@
use crate::actors::state::LogSkippedOldMessages;
use crate::actors::Actors;
use crate::commands::execute_command; use crate::commands::execute_command;
use crate::config::*; use crate::config::*;
use crate::context::Context; use crate::context::Context;
use crate::db::Database; use crate::db::Database;
use crate::error::BotError; use crate::error::BotError;
use crate::state::DiceBotState;
use async_trait::async_trait;
use dirs; use dirs;
use log::{debug, error, info, trace, warn}; use log::{debug, error, info, trace, warn};
use matrix_sdk::{ use matrix_sdk::{
@ -16,11 +16,11 @@ use matrix_sdk::{
}, },
Client, ClientConfig, EventEmitter, JsonStore, SyncRoom, SyncSettings, Client, ClientConfig, EventEmitter, JsonStore, SyncRoom, SyncSettings,
}; };
use matrix_sdk_common_macros::async_trait; //use matrix_sdk_common_macros::async_trait;
use std::clone::Clone; use std::clone::Clone;
use std::ops::Sub; use std::ops::Sub;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::{Arc, RwLock};
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use url::Url; use url::Url;
@ -33,8 +33,8 @@ pub struct DiceBot {
/// The matrix client. /// The matrix client.
client: Client, client: Client,
/// Actors used by the dice bot to manage internal state. /// State of the dicebot
actors: Actors, state: Arc<RwLock<DiceBotState>>,
/// Active database layer /// Active database layer
db: Database, db: Database,
@ -61,11 +61,15 @@ impl DiceBot {
/// actor. This function returns a Result because it is possible /// actor. This function returns a Result because it is possible
/// for client creation to fail for some reason (e.g. invalid /// for client creation to fail for some reason (e.g. invalid
/// homeserver URL). /// homeserver URL).
pub fn new(config: &Arc<Config>, actors: Actors, db: &Database) -> Result<Self, BotError> { pub fn new(
config: &Arc<Config>,
state: &Arc<RwLock<DiceBotState>>,
db: &Database,
) -> Result<Self, BotError> {
Ok(DiceBot { Ok(DiceBot {
client: create_client(&config)?, client: create_client(&config)?,
config: config.clone(), config: config.clone(),
actors: actors, state: state.clone(),
db: db.clone(), db: db.clone(),
}) })
} }
@ -146,11 +150,12 @@ async fn should_process<'a>(
) -> Result<(String, String), BotError> { ) -> Result<(String, String), BotError> {
//Ignore messages that are older than configured duration. //Ignore messages that are older than configured duration.
if !check_message_age(event, bot.config.oldest_message_age()) { if !check_message_age(event, bot.config.oldest_message_age()) {
let res = bot.actors.global_state().send(LogSkippedOldMessages).await; let state_check = bot.state.read().unwrap();
if !((*state_check).logged_skipped_old_messages()) {
if let Err(e) = res { drop(state_check);
error!("Actix error: {:?}", e); let mut state = bot.state.write().unwrap();
}; (*state).skipped_old_messages();
}
return Err(BotError::ShouldNotProcessError); return Err(BotError::ShouldNotProcessError);
} }

View File

@ -37,9 +37,6 @@ pub enum BotError {
#[error("future canceled")] #[error("future canceled")]
FutureCanceledError, FutureCanceledError,
#[error("tokio task join error")]
TokioTaskJoinError(#[from] tokio::task::JoinError),
//de = deserialization //de = deserialization
#[error("toml parsing error")] #[error("toml parsing error")]
TomlParsingError(#[from] toml::de::Error), TomlParsingError(#[from] toml::de::Error),
@ -47,9 +44,6 @@ pub enum BotError {
#[error("i/o error: {0}")] #[error("i/o error: {0}")]
IoError(#[from] std::io::Error), IoError(#[from] std::io::Error),
#[error("actor mailbox error: {0}")]
ActixMailboxError(#[from] actix::MailboxError),
#[error("parsing error")] #[error("parsing error")]
ParserError(#[from] combine::error::StringStreamError), ParserError(#[from] combine::error::StringStreamError),

View File

@ -1,4 +1,3 @@
pub mod actors;
pub mod bot; pub mod bot;
pub mod cofd; pub mod cofd;
pub mod commands; pub mod commands;
@ -10,4 +9,5 @@ pub mod error;
mod help; mod help;
mod parser; mod parser;
pub mod roll; pub mod roll;
pub mod state;
pub mod variables; pub mod variables;

View File

@ -1,30 +1,14 @@
use crate::config::*; use crate::config::*;
use actix::prelude::*;
use log::info; use log::info;
use std::sync::Arc; use std::sync::Arc;
#[derive(Message)]
#[rtype(result = "bool")]
pub struct LogSkippedOldMessages;
/// Holds state of the dice bot, for anything requiring mutable /// Holds state of the dice bot, for anything requiring mutable
/// transitions. This is a simple mutable trait whose values represent /// transitions. This is a simple mutable trait whose values represent
/// the current state of the dicebot. It provides mutable methods to /// the current state of the dicebot. It provides mutable methods to
/// change state. /// change state.
pub struct DiceBotState { pub struct DiceBotState {
logged_skipped_old_messages: bool, logged_skipped_old_messages: bool,
config: Arc<Config>, _config: Arc<Config>,
}
impl Actor for DiceBotState {
type Context = Context<Self>;
fn started(&mut self, _ctx: &mut Self::Context) {
info!(
"Oldest allowable message time is {} seconds ago",
&self.config.oldest_message_age()
);
}
} }
impl DiceBotState { impl DiceBotState {
@ -32,10 +16,14 @@ impl DiceBotState {
pub fn new(config: &Arc<Config>) -> DiceBotState { pub fn new(config: &Arc<Config>) -> DiceBotState {
DiceBotState { DiceBotState {
logged_skipped_old_messages: false, logged_skipped_old_messages: false,
config: config.clone(), _config: config.clone(),
} }
} }
pub fn logged_skipped_old_messages(&self) -> bool {
self.logged_skipped_old_messages
}
/// Log and record that we have skipped some old messages. This /// Log and record that we have skipped some old messages. This
/// method will log once, and then no-op from that point on. /// method will log once, and then no-op from that point on.
pub fn skipped_old_messages(&mut self) { pub fn skipped_old_messages(&mut self) {
@ -46,12 +34,3 @@ impl DiceBotState {
self.logged_skipped_old_messages = true; self.logged_skipped_old_messages = true;
} }
} }
impl Handler<LogSkippedOldMessages> for DiceBotState {
type Result = bool;
fn handle(&mut self, _msg: LogSkippedOldMessages, _ctx: &mut Context<Self>) -> Self::Result {
self.skipped_old_messages();
self.logged_skipped_old_messages
}
}