I know almost nothing about TOML. I’m actually more of a YAML “man”.

  • 2 Posts
  • 8 Comments
Joined 1Y ago
cake
Cake day: Nov 07, 2021

help-circle
rss

I’m going to tackle Rust from a variety of angles, one of which is by studying Lemmy.


So I think I figured a few things out.

HttpServer::new(move || {...}) is doing a few things. First, HttpServer is calling a method new which moves the context (settings_bind) into a closure ({...}), which is kind of like a local-use function. The || denotes that no variables are being passed into the closure. Instead, the context is being moved in so I guess it can be destroyed once the scope of HttpServer disappears.

App::new() must refer to a method of HttpServer but I haven’t investigated that yet. I suspect .run() applies the App construct, whatever it is.


Initial observations

HttpServer::new(move || { [1] }).bind[2].run().await?; is the basic structure. [1] consists of two parts,

  1. Defining the context and rate_limiter variables
  2. Setting up something called App:new()

We see context being loaded as .app_data in App::new(), and rate_limiter being loaded into the config.

Then routes are added.

Part of what is unusual to me is defining variables within the server setup. But this may have something to do with the way Rust deals with variables. Since context has no meaning outside of this setup, better to use it here and throw it away once we’re done setting up the HttpServer?

Whereas App::new() dealt with Lemmy specific app configuration and behavior, .bind appears to involve more generic HttpServer configuration stuff [2], including the port to bind to.

Then the whole thing .run()s, and then .await?s for multithreading.


Task one: comprehend HTTP server startup in main.rs
Coming from a bash scripting background, Rust's syntax is mind boggling. The code from `HttpServer...` to `await?` is a single object. Trying to figure out how it works is going to be my first task. I will return later with results in the replies. ``` // Create Http server with websocket support let settings_bind = settings.clone(); HttpServer::new(move || { let context = LemmyContext::create( pool.clone(), chat_server.to_owned(), client.clone(), activity_queue.to_owned(), settings.to_owned(), secret.to_owned(), ); let rate_limiter = rate_limiter.clone(); App::new() .wrap(middleware::Logger::default()) .app_data(Data::new(context)) // The routes .configure(|cfg| api_routes::config(cfg, &rate_limiter)) .configure(|cfg| lemmy_apub::http::routes::config(cfg, &settings)) .configure(feeds::config) .configure(|cfg| images::config(cfg, &rate_limiter)) .configure(nodeinfo::config) .configure(|cfg| webfinger::config(cfg, &settings)) }) .bind((settings_bind.bind, settings_bind.port))? .run() .await?; ```

Here color indentation is clear because it’s a single reply thread.


The colored indentation on replies… underperforms. Multicolor is a tad confusing, and it’s not always clear what is replying to what.


The left hand indentation on comments is inadequate.


Syntax highlighting doesn’t work, which is unfortunate.


Test posting of lemmy-main/src/main.rs
Test to see how source code looks on Lemmy. Last post crashed perhaps due to missing triple backtick... And `preview` doesn't work? ```rust #[macro_use] extern crate diesel_migrations; use actix::prelude::*; use actix_web::{web::Data, *}; use diesel::{ r2d2::{ConnectionManager, Pool}, PgConnection, }; use doku::json::{AutoComments, Formatting}; use lemmy_api::match_websocket_operation; use lemmy_api_common::blocking; use lemmy_api_crud::match_websocket_operation_crud; use lemmy_apub_lib::activity_queue::create_activity_queue; use lemmy_db_schema::{get_database_url_from_env, source::secret::Secret}; use lemmy_routes::{feeds, images, nodeinfo, webfinger}; use lemmy_server::{api_routes, code_migrations::run_advanced_migrations, scheduled_tasks}; use lemmy_utils::{ rate_limit::{rate_limiter::RateLimiter, RateLimit}, request::build_user_agent, settings::structs::Settings, LemmyError, }; use lemmy_websocket::{chat_server::ChatServer, LemmyContext}; use reqwest::Client; use std::{env, sync::Arc, thread}; use tokio::sync::Mutex; embed_migrations!(); #[actix_web::main] async fn main() -> Result<(), LemmyError> { let args: Vec<String> = env::args().collect(); if args.len() == 2 && args[1] == "--print-config-docs" { let fmt = Formatting { auto_comments: AutoComments::none(), ..Default::default() }; println!("{}", doku::to_json_fmt_val(&fmt, &Settings::default())); return Ok(()); } env_logger::init(); let settings = Settings::init().expect("Couldn't initialize settings."); // Set up the r2d2 connection pool let db_url = match get_database_url_from_env() { Ok(url) => url, Err(_) => settings.get_database_url(), }; let manager = ConnectionManager::<PgConnection>::new(&db_url); let pool = Pool::builder() .max_size(settings.database.pool_size) .build(manager) .unwrap_or_else(|_| panic!("Error connecting to {}", db_url)); // Run the migrations from code let protocol_and_hostname = settings.get_protocol_and_hostname(); blocking(&pool, move |conn| { embedded_migrations::run(conn)?; run_advanced_migrations(conn, &protocol_and_hostname)?; Ok(()) as Result<(), LemmyError> }) .await??; let pool2 = pool.clone(); thread::spawn(move || { scheduled_tasks::setup(pool2); }); // Set up the rate limiter let rate_limiter = RateLimit { rate_limiter: Arc::new(Mutex::new(RateLimiter::default())), rate_limit_config: settings.rate_limit.to_owned().unwrap_or_default(), }; // Initialize the secrets let conn = pool.get()?; let secret = Secret::init(&conn).expect("Couldn't initialize secrets."); println!( "Starting http server at {}:{}", settings.bind, settings.port ); let client = Client::builder() .user_agent(build_user_agent(&settings)) .build()?; let activity_queue = create_activity_queue(); let chat_server = ChatServer::startup( pool.clone(), rate_limiter.clone(), |c, i, o, d| Box::pin(match_websocket_operation(c, i, o, d)), |c, i, o, d| Box::pin(match_websocket_operation_crud(c, i, o, d)), client.clone(), activity_queue.clone(), settings.clone(), secret.clone(), ) .start(); // Create Http server with websocket support let settings_bind = settings.clone(); HttpServer::new(move || { let context = LemmyContext::create( pool.clone(), chat_server.to_owned(), client.clone(), activity_queue.to_owned(), settings.to_owned(), secret.to_owned(), ); let rate_limiter = rate_limiter.clone(); App::new() .wrap(middleware::Logger::default()) .app_data(Data::new(context)) // The routes .configure(|cfg| api_routes::config(cfg, &rate_limiter)) .configure(|cfg| lemmy_apub::http::routes::config(cfg, &settings)) .configure(feeds::config) .configure(|cfg| images::config(cfg, &rate_limiter)) .configure(nodeinfo::config) .configure(|cfg| webfinger::config(cfg, &settings)) }) .bind((settings_bind.bind, settings_bind.port))? .run() .await?; Ok(()) } ```

I hope it fails so Americans can spend the next century making plastic junk for the Chinese middle class. I love how Intel is rebranding it’s 7nm vaporware process as “Intel 4” so it can sound like it’s better than TSMC’s 5nm process. Notwithstanding the hope that full integration between capitalism and the military industrial complex can bring, the above laughable rebrand reveals much about the heart and soul of American power: today, after all the torture chambers and war of terror, the death and displacement of millions of people around the world to prop up Dick Cheney’s “American Way of Life”, we peripheral peoples get to witness America’s humiliating descent into self-parody and delusion.


Moderates