Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,267 @@
|
||||
// 入队计时含具体编码和外层提交;执行计时含真实生成分派、任务作用域、解码、业务写入和确认。
|
||||
// 单阶段对照把 claim 放在计时外;完整循环另计入入队、claim、执行和确认。
|
||||
struct JobInput {
|
||||
name: String,
|
||||
amount: i64,
|
||||
key: String,
|
||||
}
|
||||
|
||||
fn inputs(count: usize) -> Vec<JobInput> {
|
||||
(0..count)
|
||||
.map(|index| JobInput {
|
||||
name: format!("job-{index:04} 中文\""),
|
||||
amount: index as i64 % 997,
|
||||
key: format!("key-{index:04}"),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
async fn submit(
|
||||
generated: bool,
|
||||
input: &JobInput,
|
||||
scope: &Scope<'_>,
|
||||
registry: &Arc<Registry>,
|
||||
) -> String {
|
||||
let mut database = DbContext::new(registry.clone());
|
||||
let owner = database.enter();
|
||||
let execution = Execution::System { tenant: None };
|
||||
let id = if generated {
|
||||
GENERATED_SUBMIT(
|
||||
&input.name,
|
||||
input.amount,
|
||||
&input.key,
|
||||
scope,
|
||||
&mut database,
|
||||
&execution,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
} else {
|
||||
rust_submit(
|
||||
&input.name,
|
||||
input.amount,
|
||||
&input.key,
|
||||
scope,
|
||||
&mut database,
|
||||
&execution,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
};
|
||||
database.finish(scope, owner, true).await.unwrap();
|
||||
id.into_text()
|
||||
}
|
||||
|
||||
async fn execute(
|
||||
generated: bool,
|
||||
claim: Arc<Claim>,
|
||||
scope: &Scope<'_>,
|
||||
registry: &Arc<Registry>,
|
||||
) -> Result<(), JobFailure> {
|
||||
let registry = registry.clone();
|
||||
let timeout = claim.policy.timeout_ms;
|
||||
let outcome = if generated {
|
||||
scope
|
||||
.spawn(move |child| job_execute(JOB_BINDING, None, claim, child, registry))
|
||||
.unwrap()
|
||||
.timeout(timeout)
|
||||
.await
|
||||
.unwrap()
|
||||
} else {
|
||||
scope
|
||||
.spawn(move |child| rust_execute(JOB_BINDING, claim, child, registry))
|
||||
.unwrap()
|
||||
.timeout(timeout)
|
||||
.await
|
||||
.unwrap()
|
||||
};
|
||||
match outcome {
|
||||
dever_runtime::task::Timed::Ready(value) => value,
|
||||
_ => panic!("benchmark handler timed out"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn claims(scope: &Scope<'_>, registry: &Arc<Registry>, count: usize) -> Vec<Arc<Claim>> {
|
||||
let mut database = DbContext::new(registry.clone());
|
||||
let executor = database.on(JOB_BINDING, scope).await.unwrap();
|
||||
let mut claims = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
let claim = job::claim(
|
||||
executor,
|
||||
scope,
|
||||
dever_runtime::database::now().unwrap(),
|
||||
60000,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(claim.schema, SCHEMA);
|
||||
assert_eq!(claim.target, TARGET);
|
||||
assert_eq!(claim.attempt, 1);
|
||||
claims.push(Arc::new(claim));
|
||||
}
|
||||
assert!(
|
||||
job::claim(
|
||||
executor,
|
||||
scope,
|
||||
dever_runtime::database::now().unwrap(),
|
||||
60000
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
claims
|
||||
}
|
||||
|
||||
fn measure_jobs(
|
||||
runtime: &Runtime,
|
||||
registry: &Arc<Registry>,
|
||||
generated: bool,
|
||||
handler: bool,
|
||||
inputs: Vec<JobInput>,
|
||||
) -> (u128, u64) {
|
||||
runtime
|
||||
.run(async |scope| {
|
||||
clear(scope, registry).await;
|
||||
let claims = if handler {
|
||||
for input in &inputs {
|
||||
black_box(submit(false, input, scope, registry).await);
|
||||
}
|
||||
claims(scope, registry, inputs.len()).await
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let mut checksum = 0u64;
|
||||
let start = Instant::now();
|
||||
if handler {
|
||||
for claim in claims {
|
||||
execute(generated, black_box(claim), scope, registry)
|
||||
.await
|
||||
.unwrap();
|
||||
checksum += black_box(1);
|
||||
}
|
||||
} else {
|
||||
for input in &inputs {
|
||||
let id = black_box(submit(generated, black_box(input), scope, registry).await);
|
||||
checksum += id.len() as u64 + input.name.len() as u64 + input.amount as u64;
|
||||
}
|
||||
}
|
||||
let elapsed = start.elapsed().as_nanos();
|
||||
check_rows(scope, registry, &inputs, handler).await;
|
||||
(elapsed, checksum)
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (directory, path) = directory("jobs", r#""runtime":{"mode":"worker"}"#);
|
||||
let runtime = runtime();
|
||||
let registry = runtime
|
||||
.run(async |scope| database_registry(&path, scope).await)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
check_jobs(&runtime, ®istry);
|
||||
header();
|
||||
for (name, handler) in [("job_enqueue_commit", false), ("job_handler_commit", true)] {
|
||||
samples(name, |generated, count| {
|
||||
measure_jobs(&runtime, ®istry, generated, handler, inputs(count))
|
||||
});
|
||||
}
|
||||
samples("job_enqueue_large_payload_commit", |generated, count| {
|
||||
let mut inputs = inputs(count.div_ceil(64));
|
||||
for input in &mut inputs {
|
||||
input.name.push_str(&"a".repeat(64 * 1024));
|
||||
}
|
||||
measure_jobs(&runtime, ®istry, generated, false, inputs)
|
||||
});
|
||||
samples("job_submit_claim_complete", |generated, count| {
|
||||
// 完整循环的每个样本包含 250 项实际任务;初始化及独立 SQL 核验不计时。
|
||||
measure_cycle(&runtime, ®istry, generated, count.div_ceil(8), false)
|
||||
});
|
||||
samples("job_backlog_claim_complete", |generated, count| {
|
||||
measure_cycle(&runtime, ®istry, generated, count.div_ceil(8), true)
|
||||
});
|
||||
samples("job_enqueue_duplicate_commit", |generated, count| {
|
||||
measure_duplicate(&runtime, ®istry, generated, inputs(count))
|
||||
});
|
||||
drop(registry);
|
||||
drop(runtime);
|
||||
drop(directory);
|
||||
}
|
||||
|
||||
fn measure_duplicate(
|
||||
runtime: &Runtime,
|
||||
registry: &Arc<Registry>,
|
||||
generated: bool,
|
||||
inputs: Vec<JobInput>,
|
||||
) -> (u128, u64) {
|
||||
runtime
|
||||
.run(async |scope| {
|
||||
clear(scope, registry).await;
|
||||
let mut expected = Vec::with_capacity(inputs.len());
|
||||
for input in &inputs {
|
||||
expected.push(submit(false, input, scope, registry).await);
|
||||
}
|
||||
let mut actual = Vec::with_capacity(inputs.len());
|
||||
let mut checksum = 0u64;
|
||||
let start = Instant::now();
|
||||
for input in &inputs {
|
||||
let id = submit(generated, black_box(input), scope, registry).await;
|
||||
checksum += black_box(id.len() as u64);
|
||||
actual.push(id);
|
||||
}
|
||||
let elapsed = start.elapsed().as_nanos();
|
||||
assert_eq!(actual, expected);
|
||||
check_rows(scope, registry, &inputs, false).await;
|
||||
(elapsed, checksum)
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn measure_cycle(
|
||||
runtime: &Runtime,
|
||||
registry: &Arc<Registry>,
|
||||
generated: bool,
|
||||
count: usize,
|
||||
backlog: bool,
|
||||
) -> (u128, u64) {
|
||||
let inputs = inputs(count);
|
||||
runtime
|
||||
.run(async |scope| {
|
||||
clear(scope, registry).await;
|
||||
if backlog {
|
||||
for input in &inputs {
|
||||
submit(generated, input, scope, registry).await;
|
||||
}
|
||||
}
|
||||
let start = Instant::now();
|
||||
let mut checksum = 0u64;
|
||||
for input in &inputs {
|
||||
if !backlog {
|
||||
submit(generated, black_box(input), scope, registry).await;
|
||||
}
|
||||
let claim = {
|
||||
let mut database = DbContext::new(registry.clone());
|
||||
let executor = database.on(JOB_BINDING, scope).await.unwrap();
|
||||
job::claim(
|
||||
executor,
|
||||
scope,
|
||||
dever_runtime::database::now().unwrap(),
|
||||
60000,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
};
|
||||
execute(generated, Arc::new(claim), scope, registry)
|
||||
.await
|
||||
.unwrap();
|
||||
checksum += black_box(1);
|
||||
}
|
||||
let elapsed = start.elapsed().as_nanos();
|
||||
check_rows(scope, registry, &inputs, true).await;
|
||||
(elapsed, checksum)
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
Reference in new issue
Block a user