Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,98 @@
|
||||
use super::*;
|
||||
use dever_runtime::{
|
||||
database::{Database, Options},
|
||||
task::{Limits, Runtime},
|
||||
};
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires explicit isolated config/setting.json database.postgres_test"]
|
||||
fn postgres_native_job_renews_short_lease_during_business_transaction() {
|
||||
let directory = Directory::new();
|
||||
let schema = super::super::database::postgres::Schema::new(
|
||||
&directory.0,
|
||||
"dever_native_job_heartbeat",
|
||||
"CREATE SCHEMA dever_native_job_heartbeat",
|
||||
"DROP SCHEMA dever_native_job_heartbeat CASCADE",
|
||||
);
|
||||
let project = Project::load(&fixture().with_file_name("job")).unwrap();
|
||||
let program = project.check().unwrap();
|
||||
assert_eq!(program.models[0].table, "demo_queue_model");
|
||||
let binary = build::build(
|
||||
&program,
|
||||
&project.sources,
|
||||
"main",
|
||||
&directory.0.join("heartbeat"),
|
||||
)
|
||||
.unwrap();
|
||||
let mut connection = schema.connection.clone();
|
||||
connection["max_connections"] = 4.into();
|
||||
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":200,"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()
|
||||
};
|
||||
run("submit", r#"{"name":"slow","key":"heartbeat"}"#);
|
||||
let runtime = Runtime::new(Limits::default()).unwrap();
|
||||
let database = runtime.run(async |scope| {
|
||||
let options: Options = serde_json::from_value(connection).unwrap();
|
||||
let database = Database::open(&directory.0, options, scope).await.unwrap();
|
||||
database.executor().await.unwrap().initialize(scope, "CREATE FUNCTION slow_job() RETURNS trigger LANGUAGE plpgsql AS 'BEGIN PERFORM pg_sleep(0.6); RETURN NEW; END'; CREATE TRIGGER slow_job BEFORE INSERT ON demo_queue_model FOR EACH ROW EXECUTE FUNCTION slow_job()").await.unwrap();
|
||||
database
|
||||
}).unwrap();
|
||||
let started = Instant::now();
|
||||
let mut worker = Server(Command::new(&binary).spawn().unwrap());
|
||||
while run("count", "{}") != 1 {
|
||||
assert!(
|
||||
worker.0.try_wait().unwrap().is_none(),
|
||||
"worker exited before completion"
|
||||
);
|
||||
assert!(
|
||||
started.elapsed() < Duration::from_secs(5),
|
||||
"short lease job did not complete"
|
||||
);
|
||||
std::thread::sleep(Duration::from_millis(20));
|
||||
}
|
||||
assert!(started.elapsed() >= Duration::from_millis(500));
|
||||
runtime
|
||||
.run(async |scope| {
|
||||
let rows = database
|
||||
.executor()
|
||||
.await
|
||||
.unwrap()
|
||||
.query(
|
||||
scope,
|
||||
"SELECT attempt,state FROM _dever_job",
|
||||
vec![],
|
||||
1,
|
||||
|row| Ok((row.get::<_, i64>(0)?, row.get::<_, String>(1)?)),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(rows, vec![(1, "completed".into())]);
|
||||
})
|
||||
.unwrap();
|
||||
assert!(
|
||||
Command::new("sh")
|
||||
.args(["-c", "kill -TERM \"$1\"", "--", &worker.0.id().to_string()])
|
||||
.status()
|
||||
.unwrap()
|
||||
.success()
|
||||
);
|
||||
assert!(worker.0.wait().unwrap().success());
|
||||
database.close();
|
||||
}
|
||||
Reference in new issue
Block a user