add job pool
This commit is contained in:
parent
3de7038e62
commit
3bc32c9c93
5 changed files with 104 additions and 60 deletions
|
@ -16,4 +16,6 @@ uuid = { version = "0.8", features = ["v4"] }
|
|||
chrono = "0.4"
|
||||
serde_json = "1.0"
|
||||
typetag = "0.1"
|
||||
log = "0.4.0"
|
||||
env_logger = "0.8.4"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
use crate::postgres::Postgres;
|
||||
use crate::postgres::Task;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct Executor {
|
||||
pub storage: Postgres,
|
||||
pub sleep_period: u64,
|
||||
pub max_sleep_period: u64,
|
||||
pub min_sleep_period: u64,
|
||||
pub sleep_step: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -17,7 +23,13 @@ pub trait Runnable {
|
|||
|
||||
impl Executor {
|
||||
pub fn new(storage: Postgres) -> Self {
|
||||
Self { storage }
|
||||
Self {
|
||||
storage,
|
||||
sleep_period: 5,
|
||||
max_sleep_period: 15,
|
||||
min_sleep_period: 5,
|
||||
sleep_step: 5,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self, task: &Task) {
|
||||
|
@ -29,11 +41,37 @@ impl Executor {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn run_tasks(&self) {
|
||||
while let Ok(Some(task)) = self.storage.fetch_and_touch() {
|
||||
self.run(&task)
|
||||
pub fn run_tasks(&mut self) {
|
||||
match self.storage.fetch_and_touch() {
|
||||
Ok(Some(task)) => {
|
||||
self.maybe_reset_sleep_period();
|
||||
self.run(&task);
|
||||
}
|
||||
Ok(None) => {
|
||||
self.sleep();
|
||||
}
|
||||
|
||||
Err(error) => {
|
||||
error!("Failed to fetch a task {:?}", error);
|
||||
|
||||
self.sleep();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn maybe_reset_sleep_period(&mut self) {
|
||||
if self.sleep_period != self.min_sleep_period {
|
||||
self.sleep_period = self.min_sleep_period;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sleep(&mut self) {
|
||||
if self.sleep_period < self.max_sleep_period {
|
||||
self.sleep_period = self.sleep_period + self.sleep_step;
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_secs(self.sleep_period));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
57
src/job_pool.rs
Normal file
57
src/job_pool.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use crate::executor::Executor;
|
||||
use crate::postgres::Postgres;
|
||||
use std::thread;
|
||||
|
||||
struct JobPool {
|
||||
pub number_of_workers: u16,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
struct JobThread {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl JobPool {
|
||||
pub fn new(number_of_workers: u16, name: String) -> Self {
|
||||
Self {
|
||||
number_of_workers,
|
||||
name,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&self) {
|
||||
for idx in 1..self.number_of_workers {
|
||||
let name = format!("{}{}", self.name, idx);
|
||||
|
||||
spawn_in_pool(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl JobThread {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self { name }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for JobThread {
|
||||
fn drop(&mut self) {
|
||||
spawn_in_pool(self.name.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_in_pool(name: String) {
|
||||
let mut builder = thread::Builder::new().name(name.clone());
|
||||
builder = builder;
|
||||
|
||||
builder
|
||||
.spawn(move || {
|
||||
// when _job is dropped, it will be restarted (see Drop trait impl)
|
||||
let _job = JobThread::new(name);
|
||||
|
||||
let postgres = Postgres::new(None);
|
||||
|
||||
Executor::new(postgres).run_tasks()
|
||||
})
|
||||
.unwrap();
|
||||
}
|
25
src/lib.rs
25
src/lib.rs
|
@ -1,29 +1,10 @@
|
|||
#[macro_use]
|
||||
extern crate diesel;
|
||||
|
||||
// pub trait JobQueue {
|
||||
// type Job;
|
||||
// type Error;
|
||||
|
||||
// fn push(job: Self::Job) -> Result<(), Self::Error> {
|
||||
|
||||
// }
|
||||
// fn pop(job: Self::Job) -> Result<(), Self::Error>;
|
||||
// }
|
||||
|
||||
// pub trait Storage {
|
||||
// fn save() ->
|
||||
// }
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
pub mod executor;
|
||||
pub mod job_pool;
|
||||
pub mod postgres;
|
||||
pub mod scheduler;
|
||||
mod schema;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
use crate::executor::Executor;
|
||||
use crate::postgres::Postgres;
|
||||
use std::thread;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
struct Scheduler {
|
||||
pub number_of_workers: u16,
|
||||
pub handles: Option<Vec<JoinHandle<()>>>,
|
||||
}
|
||||
|
||||
impl Scheduler {
|
||||
pub fn new(number_of_workers: u16) -> Self {
|
||||
Self {
|
||||
number_of_workers,
|
||||
handles: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
let mut handles: Vec<JoinHandle<()>> = vec![];
|
||||
|
||||
for _ in 1..self.number_of_workers {
|
||||
let handle = thread::spawn(|| {
|
||||
let postgres = Postgres::new(None);
|
||||
|
||||
Executor::new(postgres).run_tasks()
|
||||
});
|
||||
|
||||
handles.push(handle);
|
||||
}
|
||||
|
||||
self.handles = Some(handles);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue