application.rs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. use crate::{
  2. config::{get_configuration, DatabaseSettings, Settings},
  3. context::AppContext,
  4. routers::*,
  5. user_service::Auth,
  6. ws_service::WSServer,
  7. };
  8. use actix::Actor;
  9. use actix_web::{dev::Server, middleware, web, web::Data, App, HttpServer, Scope};
  10. use sqlx::{postgres::PgPoolOptions, PgPool};
  11. use std::{net::TcpListener, sync::Arc};
  12. pub struct Application {
  13. port: u16,
  14. server: Server,
  15. app_ctx: Arc<AppContext>,
  16. }
  17. impl Application {
  18. pub async fn build(configuration: Settings) -> Result<Self, std::io::Error> {
  19. let app_ctx = init_app_context(&configuration).await;
  20. let address = format!(
  21. "{}:{}",
  22. configuration.application.host, configuration.application.port
  23. );
  24. let listener = TcpListener::bind(&address)?;
  25. let port = listener.local_addr().unwrap().port();
  26. let server = run(listener, app_ctx.clone())?;
  27. Ok(Self {
  28. port,
  29. server,
  30. app_ctx,
  31. })
  32. }
  33. pub async fn run_until_stopped(self) -> Result<(), std::io::Error> { self.server.await }
  34. }
  35. pub fn run(listener: TcpListener, app_ctx: Arc<AppContext>) -> Result<Server, std::io::Error> {
  36. let server = HttpServer::new(move || {
  37. App::new()
  38. .wrap(middleware::Logger::default())
  39. .app_data(web::JsonConfig::default().limit(4096))
  40. .service(ws_scope())
  41. .service(user_scope())
  42. .app_data(Data::new(app_ctx.ws_server.clone()))
  43. .app_data(Data::new(app_ctx.db_pool.clone()))
  44. .app_data(Data::new(app_ctx.auth.clone()))
  45. })
  46. .listen(listener)?
  47. .run();
  48. Ok(server)
  49. }
  50. fn ws_scope() -> Scope { web::scope("/ws").service(ws::start_connection) }
  51. fn user_scope() -> Scope {
  52. web::scope("/user").service(web::resource("/register").route(web::post().to(user::register)))
  53. }
  54. async fn init_app_context(configuration: &Settings) -> Arc<AppContext> {
  55. let _ = flowy_log::Builder::new("flowy").env_filter("Debug").build();
  56. let pg_pool = Arc::new(
  57. get_connection_pool(&configuration.database)
  58. .await
  59. .expect("Failed to connect to Postgres."),
  60. );
  61. let ws_server = WSServer::new().start();
  62. let auth = Arc::new(Auth::new(pg_pool.clone()));
  63. let ctx = AppContext::new(ws_server, pg_pool, auth);
  64. Arc::new(ctx)
  65. }
  66. pub async fn get_connection_pool(configuration: &DatabaseSettings) -> Result<PgPool, sqlx::Error> {
  67. PgPoolOptions::new()
  68. .connect_timeout(std::time::Duration::from_secs(2))
  69. .connect_with(configuration.with_db())
  70. .await
  71. }