node: Implement simple worker thread pool
This commit is contained in:
parent
a7b1c19746
commit
947c89a398
|
|
@ -8,14 +8,13 @@ use reactor::poller::popol;
|
||||||
use reactor::Reactor;
|
use reactor::Reactor;
|
||||||
|
|
||||||
use radicle::profile;
|
use radicle::profile;
|
||||||
use radicle::storage::WriteStorage;
|
|
||||||
use radicle_node::client::handle::Handle;
|
use radicle_node::client::handle::Handle;
|
||||||
use radicle_node::client::{ADDRESS_DB_FILE, NODE_DIR, ROUTING_DB_FILE, TRACKING_DB_FILE};
|
use radicle_node::client::{ADDRESS_DB_FILE, NODE_DIR, ROUTING_DB_FILE, TRACKING_DB_FILE};
|
||||||
use radicle_node::crypto::ssh::keystore::MemorySigner;
|
use radicle_node::crypto::ssh::keystore::MemorySigner;
|
||||||
use radicle_node::prelude::{Address, NodeId};
|
use radicle_node::prelude::{Address, NodeId};
|
||||||
use radicle_node::service::{routing, tracking, FetchResult};
|
use radicle_node::service::{routing, tracking};
|
||||||
use radicle_node::wire::Transport;
|
use radicle_node::wire::Transport;
|
||||||
use radicle_node::worker::{WorkerReq, WorkerResp};
|
use radicle_node::worker::{WorkerPool, WorkerReq};
|
||||||
use radicle_node::{address, control, logger, service};
|
use radicle_node::{address, control, logger, service};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -126,27 +125,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (worker_send, worker_recv) = crossbeam_channel::unbounded::<WorkerReq<MemorySigner>>();
|
let (worker_send, worker_recv) = crossbeam_channel::unbounded::<WorkerReq<MemorySigner>>();
|
||||||
let workers = thread::spawn(move || {
|
let pool = WorkerPool::with(10, worker_storage, worker_recv);
|
||||||
while let Ok(WorkerReq {
|
|
||||||
fetch,
|
|
||||||
session,
|
|
||||||
channel,
|
|
||||||
..
|
|
||||||
}) = worker_recv.recv()
|
|
||||||
{
|
|
||||||
let result = match worker_storage.repository(fetch.repo) {
|
|
||||||
Ok(_) => todo!(),
|
|
||||||
Err(err) => FetchResult::Error {
|
|
||||||
from: fetch.remote,
|
|
||||||
error: err.into(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if channel.send(WorkerResp { result, session }).is_err() {
|
|
||||||
log::error!("Unable to report fetch result: worker channel disconnected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let wire = Transport::new(service, worker_send, negotiator.clone(), proxy_addr, clock);
|
let wire = Transport::new(service, worker_send, negotiator.clone(), proxy_addr, clock);
|
||||||
let reactor =
|
let reactor =
|
||||||
Reactor::new(wire, popol::Poller::new()).expect("unable to instantiate P2P reactor");
|
Reactor::new(wire, popol::Poller::new()).expect("unable to instantiate P2P reactor");
|
||||||
|
|
@ -162,9 +141,9 @@ fn main() -> anyhow::Result<()> {
|
||||||
let handle = Handle::from(controller);
|
let handle = Handle::from(controller);
|
||||||
let control = thread::spawn(move || control::listen(node, handle));
|
let control = thread::spawn(move || control::listen(node, handle));
|
||||||
|
|
||||||
|
pool.join().unwrap();
|
||||||
control.join().unwrap()?;
|
control.join().unwrap()?;
|
||||||
reactor.join().unwrap();
|
reactor.join().unwrap();
|
||||||
workers.join().unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
use crossbeam_channel as chan;
|
use crossbeam_channel as chan;
|
||||||
use netservices::noise::NoiseXk;
|
use netservices::noise::NoiseXk;
|
||||||
|
use std::thread;
|
||||||
|
use std::thread::JoinHandle;
|
||||||
|
|
||||||
use radicle::crypto::Negotiator;
|
use radicle::crypto::Negotiator;
|
||||||
|
use radicle::storage::WriteStorage;
|
||||||
|
use radicle::Storage;
|
||||||
|
|
||||||
use crate::service::reactor::Fetch;
|
use crate::service::reactor::Fetch;
|
||||||
use crate::service::FetchResult;
|
use crate::service::FetchResult;
|
||||||
|
|
@ -19,3 +23,70 @@ pub struct WorkerResp<G: Negotiator> {
|
||||||
pub result: FetchResult,
|
pub result: FetchResult,
|
||||||
pub session: NoiseXk<G>,
|
pub session: NoiseXk<G>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Worker<G: Negotiator> {
|
||||||
|
storage: Storage,
|
||||||
|
tasks: chan::Receiver<WorkerReq<G>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G: Negotiator> Worker<G> {
|
||||||
|
pub fn run(self) -> Result<(), chan::RecvError> {
|
||||||
|
loop {
|
||||||
|
let task = self.tasks.recv()?;
|
||||||
|
self.process(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process(&self, task: WorkerReq<G>) {
|
||||||
|
let WorkerReq {
|
||||||
|
fetch,
|
||||||
|
session,
|
||||||
|
// TODO: Implement logic.
|
||||||
|
drain: _drain,
|
||||||
|
channel,
|
||||||
|
} = task;
|
||||||
|
let result = match self.storage.repository(fetch.repo) {
|
||||||
|
Ok(_) => todo!(),
|
||||||
|
Err(err) => FetchResult::Error {
|
||||||
|
from: fetch.remote,
|
||||||
|
error: err.into(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if channel.send(WorkerResp { result, session }).is_err() {
|
||||||
|
log::error!("Unable to report fetch result: worker channel disconnected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WorkerPool {
|
||||||
|
pool: Vec<JoinHandle<Result<(), chan::RecvError>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WorkerPool {
|
||||||
|
pub fn with<G: Negotiator + 'static>(
|
||||||
|
capacity: usize,
|
||||||
|
storage: Storage,
|
||||||
|
tasks: chan::Receiver<WorkerReq<G>>,
|
||||||
|
) -> Self {
|
||||||
|
let mut pool = Vec::with_capacity(capacity);
|
||||||
|
for _ in 0..capacity {
|
||||||
|
let runtime = Worker {
|
||||||
|
tasks: tasks.clone(),
|
||||||
|
storage: storage.clone(),
|
||||||
|
};
|
||||||
|
let thread = thread::spawn(|| runtime.run());
|
||||||
|
pool.push(thread);
|
||||||
|
}
|
||||||
|
Self { pool }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn join(self) -> thread::Result<()> {
|
||||||
|
for worker in self.pool {
|
||||||
|
let result = worker.join()?;
|
||||||
|
if let Err(err) = result {
|
||||||
|
log::error!(target: "pool", "Worker failed: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue