Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,105 @@
|
||||
use super::http::Server;
|
||||
use super::*;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
#[path = "job/heartbeat.rs"]
|
||||
mod heartbeat;
|
||||
|
||||
#[test]
|
||||
fn dever_jobs_persist_execute_and_rollback_with_bounded_retries() {
|
||||
let directory = Directory::new();
|
||||
verify_queue(
|
||||
&directory,
|
||||
serde_json::json!({"type":"sqlite","path":"data/jobs.db","max_connections":4}),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
#[test]
|
||||
#[ignore = "requires explicit isolated config/setting.json database.postgres_test"]
|
||||
fn postgres_dever_jobs_persist_execute_and_rollback_with_bounded_retries() {
|
||||
let directory = Directory::new();
|
||||
let schema = super::database::postgres::Schema::new(
|
||||
&directory.0,
|
||||
"dever_native_jobs",
|
||||
"CREATE SCHEMA dever_native_jobs",
|
||||
"DROP SCHEMA dever_native_jobs CASCADE",
|
||||
);
|
||||
let mut connection = schema.connection.clone();
|
||||
connection["max_connections"] = 4.into();
|
||||
verify_queue(&directory, connection);
|
||||
}
|
||||
|
||||
// 两种驱动运行同一 Dever 源码,包含 worker 重启、失败回滚和活跃键幂等。
|
||||
fn verify_queue(directory: &Directory, connection: serde_json::Value) {
|
||||
let project = Project::load(&fixture().with_file_name("job")).unwrap();
|
||||
let program = project.check().unwrap();
|
||||
assert_eq!(program.jobs.len(), 1);
|
||||
let binary = build::build(
|
||||
&program,
|
||||
&project.sources,
|
||||
"main",
|
||||
&directory.0.join("jobs"),
|
||||
)
|
||||
.unwrap();
|
||||
std::fs::create_dir(directory.0.join("config")).unwrap();
|
||||
std::fs::write(directory.0.join("config/setting.json"), serde_json::to_vec(&serde_json::json!({"database":{"default":connection},"job":{"workers":2,"poll_ms":10,"lease_ms":2000,"retry_base_ms":10,"retry_max_ms":100},"runtime":{"shutdown_ms":1000}})).unwrap()).unwrap();
|
||||
let run = |name: &str, input: &str| {
|
||||
let result = execute(&binary, &format!("demo.queue.{name}"), input);
|
||||
assert!(
|
||||
result.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&result.stderr)
|
||||
);
|
||||
serde_json::from_slice::<serde_json::Value>(&result.stdout).unwrap()["data"].clone()
|
||||
};
|
||||
let first = run("submit", r#"{"name":"first","key":"one"}"#);
|
||||
assert_eq!(first, run("submit", r#"{"name":"ignored","key":"one"}"#));
|
||||
run("submit", r#"{"name":"fail","key":"bad"}"#);
|
||||
assert!(
|
||||
!execute(
|
||||
&binary,
|
||||
"demo.queue.rollback",
|
||||
r#"{"name":"rolled back","key":"rollback"}"#
|
||||
)
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
assert_eq!(run("count", "{}"), 0);
|
||||
let mut worker = Server(Command::new(&binary).spawn().unwrap());
|
||||
let deadline = Instant::now() + Duration::from_secs(10);
|
||||
loop {
|
||||
assert!(worker.0.try_wait().unwrap().is_none(), "worker exited");
|
||||
if run("count", "{}") == 1 {
|
||||
break;
|
||||
}
|
||||
assert!(
|
||||
Instant::now() < deadline,
|
||||
"worker did not execute queued Dever code"
|
||||
);
|
||||
std::thread::sleep(Duration::from_millis(20));
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(150));
|
||||
assert_eq!(run("count", "{}"), 1);
|
||||
assert!(
|
||||
Command::new("sh")
|
||||
.args(["-c", "kill -TERM \"$1\"", "--", &worker.0.id().to_string()])
|
||||
.status()
|
||||
.unwrap()
|
||||
.success()
|
||||
);
|
||||
assert!(worker.0.wait().unwrap().success());
|
||||
let next = run("submit", r#"{"name":"second","key":"one"}"#);
|
||||
assert_ne!(first, next);
|
||||
let mut worker = Server(Command::new(&binary).spawn().unwrap());
|
||||
let deadline = Instant::now() + Duration::from_secs(10);
|
||||
while run("count", "{}") != 2 {
|
||||
assert!(
|
||||
worker.0.try_wait().unwrap().is_none(),
|
||||
"restarted worker exited"
|
||||
);
|
||||
assert!(Instant::now() < deadline);
|
||||
std::thread::sleep(Duration::from_millis(20));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user