migration to JS engine #1

Merged
akulij merged 131 commits from dev into main 2025-05-31 08:49:52 +00:00
2 changed files with 107 additions and 0 deletions
Showing only changes of commit ef5d74cf1c - Show all commits

106
src/bot_manager.rs Normal file
View File

@ -0,0 +1,106 @@
use std::{collections::HashMap, sync::RwLock, thread::JoinHandle};
use lazy_static::lazy_static;
use teloxide::{
dispatching::dialogue::serializer::Json,
dptree,
prelude::{Dispatcher, Requester},
Bot,
};
use crate::{
bot_handler::script_handler,
db::{bots::BotInstance, DbError, DB},
mongodb_storage::MongodbStorage,
BotController, BotError, BotResult,
};
pub struct BotRunner {
controller: BotController,
info: BotInfo,
thread: JoinHandle<BotResult<()>>,
}
unsafe impl Sync for BotRunner {}
unsafe impl Send for BotRunner {}
#[derive(Clone)]
pub struct BotInfo {
pub name: String,
}
lazy_static! {
static ref BOT_POOL: RwLock<HashMap<String, BotRunner>> = RwLock::new(HashMap::new());
}
static DEFAULT_SCRIPT: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/default_script.js"));
pub async fn deploy_bot(db: &mut DB, token: &str) -> BotResult<BotInfo> {
let bot = Bot::new(token);
let name = bot.get_me().await?.username().to_string();
let bi = BotInstance::new(name.clone(), token.to_string(), DEFAULT_SCRIPT.to_string())
.store(db)
.await?;
start_bot(bi, &mut db.clone().with_name(name)).await
}
pub async fn start_bot(bi: BotInstance, db: &mut DB) -> BotResult<BotInfo> {
let controller = BotController::with_db(db.clone(), &bi.token, &bi.script).await?;
let thread = spawn_bot_thread(controller.clone(), db).await?;
let info = BotInfo {
name: bi.name.clone(),
};
let runner = BotRunner {
controller,
info: info.clone(),
thread,
};
BOT_POOL
.write()
.map_or_else(
|err| {
Err(BotError::RwLockError(format!(
"Failed to lock BOT_POOL because previous thread paniced, err: {err}"
)))
},
Ok,
)?
.insert(bi.name.clone(), runner);
Ok(info)
}
pub async fn spawn_bot_thread(
bc: BotController,
db: &mut DB,
) -> BotResult<JoinHandle<BotResult<()>>> {
let state_mgr = MongodbStorage::from_db(db, Json)
.await
.map_err(DbError::from)?;
let thread = std::thread::spawn(move || -> BotResult<()> {
let state_mgr = state_mgr;
let handler = script_handler(bc.rc);
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?;
rt.block_on(
Dispatcher::builder(bc.bot, handler)
.dependencies(dptree::deps![bc.db, state_mgr])
.build()
.dispatch(),
);
Ok(())
});
Ok(thread)
}

View File

@ -1,4 +1,5 @@
pub mod admin; pub mod admin;
pub mod bot_manager;
pub mod botscript; pub mod botscript;
pub mod commands; pub mod commands;
pub mod db; pub mod db;