Skip to content
16 changes: 15 additions & 1 deletion servers/src/common/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use std::sync::Arc;
use chrono::prelude::Utc;
use rand::prelude::*;

use crate::api;
use crate::chain;
use crate::core::global::{ChainTypes, DEFAULT_FUTURE_TIME_LIMIT};
use crate::core::{core, libtx, pow};
Expand All @@ -28,6 +27,7 @@ use crate::p2p;
use crate::pool;
use crate::pool::types::DandelionConfig;
use crate::store;
use crate::{api, Server};

/// Error type wrapping underlying module errors.
#[derive(Debug)]
Expand Down Expand Up @@ -405,3 +405,17 @@ impl DandelionEpoch {
self.relay_peer.clone()
}
}

/// Server initialization status.
pub enum ServerInitStatus {
/// Database loading.
LoadDatabase,
/// P2P server initialization.
StartSync,
/// API server initialization.
StartAPI,
/// Server instance after successful initialization.
FinishedLoading(Server),
/// Error on initialization.
ErrorLoading(Error),
}
31 changes: 19 additions & 12 deletions servers/src/grin/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use crate::common::hooks::{init_chain_hooks, init_net_hooks};
use crate::common::stats::{
ChainStats, DiffBlock, DiffStats, PeerStats, ServerStateInfo, ServerStats, TxStats,
};
use crate::common::types::{Error, ServerConfig, StratumServerConfig};
use crate::common::types::{Error, ServerConfig, ServerInitStatus, StratumServerConfig};
use crate::core::core::hash::{Hashed, ZERO_HASH};
use crate::core::ser::ProtocolVersion;
use crate::core::{consensus, genesis, global, pow};
Expand All @@ -52,7 +52,6 @@ use crate::pool;
use crate::util::file::get_first_line;
use crate::util::{RwLock, StopState};
use futures::channel::oneshot;
use grin_util::logger::LogEntry;

/// Arcified thread-safe TransactionPool with type parameters used by server components
pub type ServerTxPool = Arc<RwLock<pool::TransactionPool<PoolToChainAdapter, PoolToNetAdapter>>>;
Expand Down Expand Up @@ -84,20 +83,16 @@ impl Server {
/// Instantiates and starts a new server. Optionally takes a callback
/// for the server to send an ARC copy of itself, to allow another process
/// to poll info about the server status
pub fn start<F>(
pub fn start(
config: ServerConfig,
logs_rx: Option<mpsc::Receiver<LogEntry>>,
mut info_callback: F,
stop_state: Option<Arc<StopState>>,
server_tx: Option<mpsc::Sender<ServerInitStatus>>,
api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>),
) -> Result<(), Error>
where
F: FnMut(Server, Option<mpsc::Receiver<LogEntry>>),
{
) -> Result<Server, Error> {
let mining_config = config.stratum_mining_config.clone();
let enable_test_miner = config.run_test_miner;
let test_miner_wallet_url = config.test_miner_wallet_url.clone();
let serv = Server::new(config, stop_state, api_chan)?;
let serv = Server::new(config, stop_state, server_tx, api_chan)?;

if let Some(c) = mining_config {
let enable_stratum_server = c.enable_stratum_server;
Expand All @@ -118,8 +113,7 @@ impl Server {
}
}

info_callback(serv, logs_rx);
Ok(())
Ok(serv)
}

// Exclusive (advisory) lock_file to ensure we do not run multiple
Expand Down Expand Up @@ -151,6 +145,7 @@ impl Server {
pub fn new(
config: ServerConfig,
stop_state: Option<Arc<StopState>>,
server_tx: Option<mpsc::Sender<ServerInitStatus>>,
api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>),
) -> Result<Server, Error> {
// Obtain our lock_file or fail immediately with an error.
Expand Down Expand Up @@ -193,6 +188,10 @@ impl Server {

info!("Starting server, genesis block: {}", genesis.hash());

if let Some(ref server_tx) = server_tx {
let _ = server_tx.send(ServerInitStatus::LoadDatabase);
}

let shared_chain = Arc::new(chain::Chain::init(
config.db_root.clone(),
chain_adapter.clone(),
Expand Down Expand Up @@ -220,6 +219,10 @@ impl Server {
};
debug!("Capabilities: {:?}", capabilities);

if let Some(ref server_tx) = server_tx {
let _ = server_tx.send(ServerInitStatus::StartSync);
}

let p2p_server = Arc::new(p2p::Server::new(
&config.db_root,
capabilities,
Expand Down Expand Up @@ -265,6 +268,10 @@ impl Server {
}
})?;

if let Some(ref server_tx) = server_tx {
let _ = server_tx.send(ServerInitStatus::StartAPI);
}

info!("Starting rest apis at: {}", &config.api_http_addr);
let api_secret = get_first_line(config.api_secret_path.clone());
let foreign_api_secret = get_first_line(config.foreign_api_secret_path.clone());
Expand Down
59 changes: 34 additions & 25 deletions src/bin/cmd/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ use crate::tui::ui;
use futures::channel::oneshot;
use grin_p2p::msg::PeerAddrs;
use grin_p2p::PeerAddr;
use grin_servers::common::types::ServerInitStatus;
use grin_servers::Server;
use grin_util::logger::LogEntry;
use std::sync::mpsc;

Expand All @@ -46,29 +48,36 @@ fn start_server_tui(
logs_rx: Option<mpsc::Receiver<LogEntry>>,
api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>),
) {
// Run the UI controller.. here for now for simplicity to access
// everything it might need
if config.run_tui.unwrap_or(false) {
warn!("Starting GRIN in UI mode...");
servers::Server::start(
config,
logs_rx,
|serv: servers::Server, logs_rx: Option<mpsc::Receiver<LogEntry>>| {
let mut controller = ui::Controller::new(logs_rx.unwrap()).unwrap_or_else(|e| {
panic!("Error loading UI controller: {}", e);
});
controller.run(serv);
},
None,
api_chan,
)
.unwrap();
// Run the UI controller.
let (serv_tx, serv_rx) = mpsc::channel::<ServerInitStatus>();
let mut controller = ui::Controller::new(logs_rx, serv_rx).unwrap_or_else(|e| {
panic!("Error loading UI controller: {}", e);
});
let tui_running = Arc::new(AtomicBool::new(true));
let serv_tx_clone = serv_tx.clone();
let tui_running_clone = tui_running.clone();
thread::spawn(move || {
Comment thread
ardocrat marked this conversation as resolved.
match Server::start(config, None, Some(serv_tx_clone.clone()), api_chan) {
Ok(s) => {
if !tui_running_clone.load(Ordering::Relaxed) {
s.stop();
return;
}
let _ = serv_tx_clone.send(ServerInitStatus::FinishedLoading(s));
}
Err(e) => {
let _ = serv_tx_clone.send(ServerInitStatus::ErrorLoading(e));
}
}
});
controller.run();
tui_running.store(false, Ordering::Relaxed);
} else {
warn!("Starting GRIN w/o UI...");
servers::Server::start(
config,
logs_rx,
|serv: servers::Server, _: Option<mpsc::Receiver<LogEntry>>| {
match Server::start(config, None, None, api_chan) {
Ok(s) => {
let running = Arc::new(AtomicBool::new(true));
let r = running.clone();
ctrlc::set_handler(move || {
Expand All @@ -79,12 +88,12 @@ fn start_server_tui(
thread::sleep(Duration::from_secs(1));
}
warn!("Received SIGINT (Ctrl+C) or SIGTERM (kill).");
serv.stop();
},
None,
api_chan,
)
.unwrap();
s.stop();
}
Err(e) => {
Comment thread
ardocrat marked this conversation as resolved.
panic!("Error starting GRIN: {:?}", e);
}
}
}
}

Expand Down
Loading
Loading