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"
dirs = "3.0"
indoc = "1.0"
actix = "0.10"
actix-rt = "1.1"
combine = "4.3"
sled = "0.34"
zerocopy = "0.3"
byteorder = "1.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-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]
version = "1"
@ -45,7 +35,7 @@ features = ['derive']
[dependencies.tokio]
version = "0.2"
features = ["rt-core", "rt-util", "macros", "time", "signal"]
features = [ "full" ]
[dev-dependencies]
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.
#![type_length_limit = "7605144"]
use actix::prelude::*;
use chronicle_dicebot::actors::Actors;
use chronicle_dicebot::bot::DiceBot;
use chronicle_dicebot::config::*;
use chronicle_dicebot::db::Database;
use chronicle_dicebot::error::BotError;
use chronicle_dicebot::state::DiceBotState;
use env_logger::Env;
use log::error;
use std::sync::Arc;
use std::sync::{Arc, RwLock};
use tokio::prelude::*;
#[actix_rt::main]
#[tokio::main]
async fn main() {
env_logger::from_env(Env::default().default_filter_or("chronicle_dicebot=info,dicebot=info"))
.init();
@ -28,13 +28,12 @@ async fn run() -> Result<(), BotError> {
let cfg = Arc::new(read_config(config_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?,
Err(e) => println!("Error connecting: {:?}", e),
};
System::current().stop();
Ok(())
}

View File

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

View File

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

View File

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

View File

@ -1,30 +1,14 @@
use crate::config::*;
use actix::prelude::*;
use log::info;
use std::sync::Arc;
#[derive(Message)]
#[rtype(result = "bool")]
pub struct LogSkippedOldMessages;
/// Holds state of the dice bot, for anything requiring mutable
/// transitions. This is a simple mutable trait whose values represent
/// the current state of the dicebot. It provides mutable methods to
/// change state.
pub struct DiceBotState {
logged_skipped_old_messages: bool,
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()
);
}
_config: Arc<Config>,
}
impl DiceBotState {
@ -32,10 +16,14 @@ impl DiceBotState {
pub fn new(config: &Arc<Config>) -> DiceBotState {
DiceBotState {
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
/// method will log once, and then no-op from that point on.
pub fn skipped_old_messages(&mut self) {
@ -46,12 +34,3 @@ impl DiceBotState {
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
}
}