oxedyne/fe2o3/fe2o3_shield/src/app/server.rs
5.5 KiB, 204 runs
created by r1870400018:4072, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | use crate::{ |
| 2 | app::{ |
| 3 | cfg::AppConfig, |
| 4 | constant as app_const, |
| 5 | tui::AppStatus, |
| 6 | }, |
| 7 | srv::{ |
| 8 | cfg::ServerConfig, |
| 9 | cmd::Command, |
| 10 | constant as srv_const, |
| 11 | context::ServerContext, |
| 12 | msg::{ |
| 13 | protocol::{ |
| 14 | DefaultProtocolTypes, |
| 15 | Protocol, |
| 16 | ProtocolMode, |
| 17 | }, |
| 18 | syntax as srv_syntax, |
| 19 | }, |
| 20 | schemes::WireSchemesInput, |
| 21 | server::{ |
| 22 | answer_nothing, |
| 23 | Server, |
| 24 | }, |
| 25 | }, |
| 26 | }; |
| 27 | |
| 28 | use oxedyne_fe2o3_core::{ |
| 29 | prelude::*, |
| 30 | alt::Alt, |
| 31 | channels::Simplex, |
| 32 | path::NormalPath, |
| 33 | }; |
| 34 | use oxedyne_fe2o3_crypto::enc::EncryptionScheme; |
| 35 | use oxedyne_fe2o3_hash::{ |
| 36 | csum::ChecksumScheme, |
| 37 | hash::HashScheme, |
| 38 | }; |
| 39 | use oxedyne_fe2o3_jdat::{ |
| 40 | prelude::*, |
| 41 | cfg::Config, |
| 42 | }; |
| 43 | use oxedyne_fe2o3_net::id; |
| 44 | use oxedyne_fe2o3_o3db_sync::O3db; |
| 45 | use oxedyne_fe2o3_syntax::{ |
| 46 | msg::{ |
| 47 | MsgCmd, |
| 48 | }, |
| 49 | }; |
| 50 | use oxedyne_fe2o3_tui::lib_tui::{ |
| 51 | repl::Evaluation, |
| 52 | }; |
| 53 | |
| 54 | use std::{ |
| 55 | path::Path, |
| 56 | time::Duration, |
| 57 | }; |
| 58 | |
| 59 | use tokio; |
| 60 | |
| 61 | |
| 62 | pub async fn start_server( |
| 63 | app_cfg: &AppConfig, |
| 64 | stat: &AppStatus, |
| 65 | mut db: O3db< |
| 66 | { id::UID_LEN }, |
| 67 | id::Uid, |
| 68 | EncryptionScheme, |
| 69 | HashScheme, |
| 70 | HashScheme, |
| 71 | ChecksumScheme, |
| 72 | >, |
| 73 | cmd: Option<&MsgCmd>, |
| 74 | test_stream: Option<String>, // Constains log stream id. |
| 75 | ) |
| 76 | -> Outcome<( |
| 77 | Evaluation, |
| 78 | Option<( |
| 79 | Simplex<Command>, |
| 80 | tokio::task::JoinHandle<Outcome<()>>, |
| 81 | )>, |
| 82 | )> |
| 83 | { |
| 84 | msg!("log_stream = {}",async_log::stream()); |
| 85 | let root_path = Path::new(&app_cfg.app_root) |
| 86 | .normalise() // Now a NormPathBuf. |
| 87 | .absolute(); |
| 88 | debug!("Reading server config..."); |
| 89 | let mut server_cfg = res!(ServerConfig::from_datmap(app_cfg.server_cfg.clone())); |
| 90 | info!("Validating server config..."); |
| 91 | res!(server_cfg.check_and_fix()); |
| 92 | res!(server_cfg.validate(&root_path)); |
| 93 | |
| 94 | // ┌───────────────────────┐ |
| 95 | // │ Determine mode. │ |
| 96 | // └───────────────────────┘ |
| 97 | let mut mode = ProtocolMode::Production; |
| 98 | if let Some(msg_cmd) = cmd { |
| 99 | if msg_cmd.has_arg("dev") { |
| 100 | mode = ProtocolMode::Dev; |
| 101 | info!("Running in dev mode."); |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | if stat.first && matches!(mode, ProtocolMode::Production) { |
| 106 | return Ok(( |
| 107 | Evaluation::Error(fmt!( |
| 108 | "You should update values in {} before running the server in production mode.", |
| 109 | app_const::CONFIG_NAME, |
| 110 | )), |
| 111 | None, |
| 112 | )); |
| 113 | } |
| 114 | |
| 115 | // ┌───────────────────────┐ |
| 116 | // │ Start database. │ |
| 117 | // └───────────────────────┘ |
| 118 | info!(async_log::stream(), "Starting database..."); |
| 119 | res!(db.start(test_stream.clone().unwrap_or_else(|| fmt!("main")))); |
| 120 | res!(ok!(db.updated_api()).activate_gc(true)); |
| 121 | |
| 122 | std::thread::sleep(Duration::from_secs(1)); |
| 123 | |
| 124 | let uid = id::Uid::new(0); |
| 125 | |
| 126 | // Ping all bots. |
| 127 | let (start, msgs) = res!(db.api().ping_bots(app_const::GET_DATA_WAIT)); |
| 128 | info!(async_log::stream(), "{} ping replies received in {:?}.", msgs.len(), start.elapsed()); |
| 129 | |
| 130 | // ┌───────────────────────┐ |
| 131 | // │ Start server. │ |
| 132 | // └───────────────────────┘ |
| 133 | |
| 134 | let chunk_cfg = ServerConfig::new_chunk_cfg(1_000, 200, true, true); |
| 135 | |
| 136 | let protocol: Protocol< |
| 137 | 8, |
| 138 | {id::MID_LEN}, |
| 139 | {id::SID_LEN}, |
| 140 | {id::UID_LEN}, |
| 141 | DefaultProtocolTypes< |
| 142 | {id::MID_LEN}, |
| 143 | {id::SID_LEN}, |
| 144 | {id::UID_LEN}, |
| 145 | >, |
| 146 | > = |
| 147 | res!(Protocol::new( |
| 148 | &server_cfg, |
| 149 | WireSchemesInput { |
| 150 | enc: Alt::Specific(None::<EncryptionScheme>), |
| 151 | csum: Alt::Specific(None::<ChecksumScheme>), |
| 152 | powh: Alt::Specific(ServerConfig::default_packet_pow_hash_scheme()), |
| 153 | sign: Alt::Specific(ServerConfig::default_packet_signature_scheme()), |
| 154 | hsenc: Alt::Specific(None::<EncryptionScheme>), |
| 155 | chnk: Some(chunk_cfg), |
| 156 | }, |
| 157 | [0u8; 8], |
| 158 | id::Mid::default(), |
| 159 | id::Sid::default(), |
| 160 | id::Uid::default(), |
| 161 | if test_stream.is_some() { ProtocolMode::Test } else { mode }, |
| 162 | )); |
| 163 | |
| 164 | let server_context = ServerContext::new( |
| 165 | server_cfg, |
| 166 | root_path.clone(), |
| 167 | Some((db.clone(), uid)), |
| 168 | protocol, |
| 169 | ); |
| 170 | |
| 171 | let syntax = res!(srv_syntax::base_msg()); |
| 172 | let (mut server, cmd_chan) = Server::new(server_context, syntax.clone()); |
| 173 | |
| 174 | info!(async_log::stream(), "Starting server..."); |
| 175 | for line in srv_const::SPLASH.lines() { |
| 176 | info!(async_log::stream(), "{}", line); |
| 177 | } |
| 178 | |
| 179 | // The reference server has no application of its own, so it hears payloads |
| 180 | // and answers none of them. An application built on the library passes its |
| 181 | // own handler here. |
| 182 | let handle = tokio::spawn(async_log::LOG_STREAM_ID.scope( |
| 183 | test_stream.unwrap_or_else(|| fmt!("main")), |
| 184 | async move { server.start(answer_nothing).await }, |
| 185 | )); |
| 186 | |
| 187 | Ok((Evaluation::Exit, Some((cmd_chan, handle)))) |
| 188 | } |