aboutsummaryrefslogtreecommitdiffstats
path: root/src/web_server.rs
diff options
context:
space:
mode:
authorJokler <jokler@protonmail.com>2020-01-30 15:55:41 +0100
committerJokler <jokler@protonmail.com>2020-02-22 23:20:10 +0100
commit757edd214f841e8d95e4c5430d7ead7a0e8fecbb (patch)
tree3d0721d1d1f73c9bc1fd5ac23aef505e1051d5e5 /src/web_server.rs
parent2792ba9c8a7120a91b3bd2c6075e737690e73405 (diff)
downloadpokebot-757edd214f841e8d95e4c5430d7ead7a0e8fecbb.tar.gz
pokebot-757edd214f841e8d95e4c5430d7ead7a0e8fecbb.zip
Spawn actix-web server with access to the bot
Additionally replace all Mutexes with RwLocks. Hopefully this makes it possible for the web server to serve many requests at once since they would just hold read locks.
Diffstat (limited to 'src/web_server.rs')
-rw-r--r--src/web_server.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/web_server.rs b/src/web_server.rs
new file mode 100644
index 0000000..1edbc50
--- /dev/null
+++ b/src/web_server.rs
@@ -0,0 +1,60 @@
+use std::sync::Arc;
+
+use actix::{Actor, Addr, Handler, Message, SyncArbiter, SyncContext};
+use actix_web::{get, middleware::Logger, web, App, HttpResponse, HttpServer, Responder};
+
+use crate::bot::MasterBot;
+
+struct GetNames;
+
+impl Message for GetNames {
+ type Result = Result<Vec<String>, ()>;
+}
+
+#[get("/")]
+async fn index(bot: web::Data<Addr<BotExecutor>>) -> impl Responder {
+ let names = bot.send(GetNames).await.unwrap().unwrap();
+ HttpResponse::Ok().body(&format!("Music bots connected: {}", names.join(", ")))
+}
+
+pub struct WebServerArgs {
+ pub domain: String,
+ pub bind_address: String,
+ pub bot: Arc<MasterBot>,
+}
+
+#[actix_rt::main]
+pub async fn start(args: WebServerArgs) -> std::io::Result<()> {
+ let cbot = args.bot.clone();
+ let bot_addr: Addr<BotExecutor> = SyncArbiter::start(4, move || BotExecutor(cbot.clone()));
+
+ HttpServer::new(move || {
+ App::new()
+ .data(bot_addr.clone())
+ .wrap(Logger::default())
+ .service(index)
+ })
+ .bind(args.bind_address)?
+ .run()
+ .await?;
+
+ args.bot.quit(String::from("Stopping"));
+
+ Ok(())
+}
+
+pub struct BotExecutor(pub Arc<MasterBot>);
+
+impl Actor for BotExecutor {
+ type Context = SyncContext<Self>;
+}
+
+impl Handler<GetNames> for BotExecutor {
+ type Result = Result<Vec<String>, ()>;
+
+ fn handle(&mut self, _: GetNames, _: &mut Self::Context) -> Self::Result {
+ let bot = &self.0;
+
+ Ok(bot.names())
+ }
+}