add thread requirement for jobs
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use clap::{App, Arg};
|
use clap::{arg, value_parser, App, Arg};
|
||||||
use env_logger::Env;
|
use env_logger::Env;
|
||||||
use futures::future::{AbortHandle, Abortable};
|
use futures::future::{AbortHandle, Abortable};
|
||||||
use log;
|
use log;
|
||||||
@@ -37,10 +37,11 @@ struct Worker {
|
|||||||
id: String,
|
id: String,
|
||||||
secret: String,
|
secret: String,
|
||||||
server: String,
|
server: String,
|
||||||
|
threads: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Worker {
|
impl Worker {
|
||||||
async fn new(server: &str, secret: &str) -> Result<Worker, Box<dyn Error>> {
|
async fn new(server: &str, secret: &str, threads: i32) -> Result<Worker, Box<dyn Error>> {
|
||||||
let res = build_client(secret)
|
let res = build_client(secret)
|
||||||
.get(format!("{}/register", server))
|
.get(format!("{}/register", server))
|
||||||
.send()
|
.send()
|
||||||
@@ -53,6 +54,7 @@ impl Worker {
|
|||||||
id: r.id,
|
id: r.id,
|
||||||
secret: secret.to_string(),
|
secret: secret.to_string(),
|
||||||
server: server.to_string(),
|
server: server.to_string(),
|
||||||
|
threads,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +85,7 @@ impl Worker {
|
|||||||
.post(format!("{}/fetch", self.server))
|
.post(format!("{}/fetch", self.server))
|
||||||
.json(&FetchRequest {
|
.json(&FetchRequest {
|
||||||
worker_id: self.id.clone(),
|
worker_id: self.id.clone(),
|
||||||
|
threads: self.threads,
|
||||||
})
|
})
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
@@ -136,15 +139,26 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
.required(true)
|
.required(true)
|
||||||
.help("Set Zoidberg server address"),
|
.help("Set Zoidberg server address"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
arg!(-j --threads <VALUE> "Sets number of threads")
|
||||||
|
.required(false)
|
||||||
|
.value_parser(value_parser!(i32)),
|
||||||
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
let server = matches.value_of("server").unwrap();
|
let server = matches.value_of("server").unwrap();
|
||||||
|
let threads: i32 = if let Some(t) = matches.get_one::<i32>("threads") {
|
||||||
|
*t
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
let secret = std::env::var("ZOIDBERG_SECRET").unwrap_or_else(|_| {
|
let secret = std::env::var("ZOIDBERG_SECRET").unwrap_or_else(|_| {
|
||||||
eprintln!("Please set the $ZOIDBERG_SECRET environment variable");
|
eprintln!("Please set the $ZOIDBERG_SECRET environment variable");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
let client = Arc::new(
|
let client = Arc::new(
|
||||||
Worker::new(server, &secret)
|
Worker::new(server, &secret, threads)
|
||||||
.await
|
.await
|
||||||
.expect("Could not create client"),
|
.expect("Could not create client"),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ pub struct Job {
|
|||||||
pub cmd: String,
|
pub cmd: String,
|
||||||
#[serde(default = "Status::default")]
|
#[serde(default = "Status::default")]
|
||||||
pub status: Status,
|
pub status: Status,
|
||||||
|
#[serde(default)]
|
||||||
|
pub threads: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -61,6 +63,8 @@ pub struct RegisterResponse {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct FetchRequest {
|
pub struct FetchRequest {
|
||||||
pub worker_id: String,
|
pub worker_id: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub threads: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
|||||||
@@ -64,7 +64,9 @@ async fn fetch(
|
|||||||
f: web::Json<FetchRequest>,
|
f: web::Json<FetchRequest>,
|
||||||
_: Authorization,
|
_: Authorization,
|
||||||
) -> Result<impl Responder> {
|
) -> Result<impl Responder> {
|
||||||
let requesting_worker = f.into_inner().worker_id;
|
let f = f.into_inner();
|
||||||
|
let requesting_worker = f.worker_id;
|
||||||
|
let threads = f.threads;
|
||||||
{
|
{
|
||||||
let workers = data.workers.lock().unwrap();
|
let workers = data.workers.lock().unwrap();
|
||||||
if workers.iter().filter(|w| w.id == requesting_worker).count() != 1 {
|
if workers.iter().filter(|w| w.id == requesting_worker).count() != 1 {
|
||||||
@@ -74,15 +76,24 @@ async fn fetch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut new_jobs = data.new_jobs.lock().unwrap();
|
let mut new_jobs = data.new_jobs.lock().unwrap();
|
||||||
if let Some(j) = new_jobs.pop() {
|
new_jobs.sort_by(|a, b| b.threads.cmp(&a.threads));
|
||||||
|
|
||||||
|
if let Some(j) = new_jobs
|
||||||
|
.iter()
|
||||||
|
.filter(|x| x.threads <= threads)
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<Job>>()
|
||||||
|
.first()
|
||||||
|
{
|
||||||
let mut jobs = data.jobs.lock().unwrap();
|
let mut jobs = data.jobs.lock().unwrap();
|
||||||
for cj in jobs.iter_mut() {
|
for cj in jobs.iter_mut() {
|
||||||
if cj.id == j.id {
|
if cj.id == j.id {
|
||||||
cj.status = Status::Running(requesting_worker.clone())
|
cj.status = Status::Running(requesting_worker.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(web::Json(FetchResponse::Jobs(vec![j])));
|
new_jobs.retain(|x| x.id != j.id);
|
||||||
}
|
return Ok(web::Json(FetchResponse::Jobs(vec![j.clone()])));
|
||||||
|
};
|
||||||
Ok(web::Json(FetchResponse::Nop))
|
Ok(web::Json(FetchResponse::Nop))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,11 +288,26 @@ mod tests {
|
|||||||
id: "some_worker".to_string(),
|
id: "some_worker".to_string(),
|
||||||
last_heartbeat: None,
|
last_heartbeat: None,
|
||||||
}]),
|
}]),
|
||||||
new_jobs: Mutex::new(vec![Job {
|
new_jobs: Mutex::new(vec![
|
||||||
id: jobid,
|
Job {
|
||||||
cmd: cmd.clone(),
|
id: jobid,
|
||||||
status: Status::Submitted,
|
cmd: cmd.clone(),
|
||||||
}]),
|
status: Status::Submitted,
|
||||||
|
threads: 1,
|
||||||
|
},
|
||||||
|
Job {
|
||||||
|
id: jobid + 1,
|
||||||
|
cmd: cmd.clone(),
|
||||||
|
status: Status::Submitted,
|
||||||
|
threads: 2,
|
||||||
|
},
|
||||||
|
Job {
|
||||||
|
id: jobid + 2,
|
||||||
|
cmd: cmd.clone(),
|
||||||
|
status: Status::Submitted,
|
||||||
|
threads: 3,
|
||||||
|
},
|
||||||
|
]),
|
||||||
jobs: Mutex::new(Vec::new()),
|
jobs: Mutex::new(Vec::new()),
|
||||||
}))
|
}))
|
||||||
.service(fetch),
|
.service(fetch),
|
||||||
@@ -291,6 +317,7 @@ mod tests {
|
|||||||
.append_header(("cookie", "secret"))
|
.append_header(("cookie", "secret"))
|
||||||
.set_json(FetchRequest {
|
.set_json(FetchRequest {
|
||||||
worker_id: "some_worker".to_string(),
|
worker_id: "some_worker".to_string(),
|
||||||
|
threads: 1,
|
||||||
})
|
})
|
||||||
.uri("/fetch")
|
.uri("/fetch")
|
||||||
.to_request();
|
.to_request();
|
||||||
@@ -324,6 +351,7 @@ mod tests {
|
|||||||
id: jobid,
|
id: jobid,
|
||||||
cmd: cmd.clone(),
|
cmd: cmd.clone(),
|
||||||
status: Status::Submitted,
|
status: Status::Submitted,
|
||||||
|
threads: 1,
|
||||||
}]),
|
}]),
|
||||||
}))
|
}))
|
||||||
.service(status),
|
.service(status),
|
||||||
@@ -375,6 +403,7 @@ mod tests {
|
|||||||
id: 0,
|
id: 0,
|
||||||
cmd: String::from("hi"),
|
cmd: String::from("hi"),
|
||||||
status: Status::Submitted,
|
status: Status::Submitted,
|
||||||
|
threads: 1,
|
||||||
}])
|
}])
|
||||||
.uri("/submit")
|
.uri("/submit")
|
||||||
.to_request();
|
.to_request();
|
||||||
|
|||||||
Reference in New Issue
Block a user