Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3084e9b
SQL: Prevent duplicated binds
ReinierMaas Jul 15, 2026
ae678e9
SQL: Filter already reserved chunks from `Chunk` selection
ReinierMaas Jul 15, 2026
2addea0
fixup! SQL: Filter already reserved chunks from `Chunk` selection
ReinierMaas Jul 16, 2026
d9aedfb
SQL: Order by ascending metadata counts, null first
ReinierMaas Jul 17, 2026
0baada3
SQL: Prevent duplicate `metadata_value` for `(submission_id, metadata…
ReinierMaas Jul 17, 2026
1f52f24
fixup! SQL: Order by ascending metadata counts, null first
ReinierMaas Jul 17, 2026
211080d
Add benchmark
jerbaroo Jul 21, 2026
a704437
fixup! Add benchmark
jerbaroo Jul 21, 2026
1e8a08e
fixup! Add benchmark
jerbaroo Jul 21, 2026
04f6115
fixup! Add benchmark
jerbaroo Jul 21, 2026
6a5b819
Prefer distinct strategy searches submissions (not counts)
jerbaroo Jul 21, 2026
bf97013
Test fairness of the prefer distinct strategy
jerbaroo Jul 21, 2026
9eaeb99
fixup! Prefer distinct strategy searches submissions (not counts)
jerbaroo Jul 21, 2026
8786708
Add random_order to submissions
jerbaroo Jul 21, 2026
e2d91d2
fixup! Add benchmark
jerbaroo Jul 21, 2026
9b7c26d
fixup! Add random_order to submissions
jerbaroo Jul 21, 2026
d4009f6
fixup! Add benchmark
jerbaroo Jul 21, 2026
f57d97a
Merge remote-tracking branch 'origin/reinier/pass_reserver_ids' into …
jerbaroo Jul 22, 2026
d560543
fixup! Merge remote-tracking branch 'origin/reinier/pass_reserver_ids…
jerbaroo Jul 22, 2026
2de9059
Merge remote-tracking branch 'origin/reinier/pass_metastate' into jer…
jerbaroo Jul 22, 2026
d07ee6b
fixup! Merge remote-tracking branch 'origin/reinier/pass_metastate' i…
jerbaroo Jul 22, 2026
6e21a62
fixup! Test fairness of the prefer distinct strategy
jerbaroo Jul 23, 2026
d05a9ab
Avoid duplicate materialization
jerbaroo Jul 23, 2026
b00a12f
Avoid duplicate FFI calls for the same value
jerbaroo Jul 23, 2026
073e7c1
better benchmark
jerbaroo Jul 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 3 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
[workspace]

# Resolver 3 is default in the 2024 Edition, but the workspace doesn't know that
resolver = "3"
# Resolver 2 is default in the 2021 Edition, but the workspace doesn't know that
resolver = "2"

members = [
"opsqueue/",
"libs/opsqueue_python",
]

[workspace.package]
version = "0.36.0"
version = "0.35.5"

[workspace.lints.clippy]
cargo = { level = "warn", priority = -1 }
Expand All @@ -27,10 +27,6 @@ restriction = { level = "allow", priority = -1 }
style = { level = "warn", priority = -1 }
suspicious = { level = "warn", priority = -1 }

# Prevent duplicate versions of crates from being used in the workspace. If an easy fix is not
# possible, you can add the crate to the `allowed-duplicate-crates` list in `clippy.toml`.
multiple_crate_versions = "deny"

[profile.release]
# Full fat LTO makes a big difference in performance, at the cost of a large
# compile time hit. You should only use release builds when performance matters.
Expand Down
2 changes: 2 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ let
# For the shell, libpython needs to be in the search path.
pythonEnv
];
# Fixes: libstdc++.so.6: cannot open shared object file: No such file or directory
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [ pkgs.stdenv.cc.cc.lib ];
};
};
in
Expand Down
16 changes: 14 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ test-integration *TEST_ARGS: build-bin build-python
cd libs/opsqueue_python
source "./.setup_local_venv.sh"

timeout {{pytest_timeout_seconds}} pytest --color=yes {{TEST_ARGS}}
pytest --timeout {{pytest_timeout_seconds}} --color=yes {{TEST_ARGS}}

# Python integration test suite, using artefacts built through Nix. Args are forwarded to pytest
[group('nix')]
Expand All @@ -68,7 +68,19 @@ nix-test-integration *TEST_ARGS: nix-build
export OPSQUEUE_BIN="${nix_build_bin_dir}/bin/opsqueue"
export RUST_LOG="opsqueue=debug"

timeout {{pytest_timeout_seconds}} pytest --color=yes {{TEST_ARGS}}
pytest --timeout {{pytest_timeout_seconds}} --color=yes {{TEST_ARGS}}

# Benchmark query cost and render a graph.
[group('bench')]
bench-chunks-select:
#!/usr/bin/env bash
set -euo pipefail
cargo bench --bench chunks_select

cd libs/opsqueue_python
source "./.setup_local_venv.sh"
cd -
python opsqueue/benches/plot_chunks_select.py

# Run all linters, fast and slow
[group('lint')]
Expand Down
3 changes: 2 additions & 1 deletion libs/opsqueue_python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ include = ["**/py.typed"]
# because otherwise `pytest` won't be able to see the locally build python package!
[project.optional-dependencies]
test = [
"matplotlib==3.11.1",
"multiprocess==0.70.19",
"pytest==9.0.3",
"pytest-xdist==3.8.0",
"multiprocess==0.70.19",
"pytest-timeout==2.4.0",
]

Expand Down
29 changes: 29 additions & 0 deletions libs/opsqueue_python/tests/test_roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,3 +667,32 @@ def test_lookup_too_many_submission_ids_by_strategic_metadata() -> None:
)
assert exc.type is TooManyMatchingSubmissionsError
assert exc.value.max_submissions == max_


def test_prefer_distinct_strategy_fairness(opsqueue: OpsqueueProcess) -> None:
"""Test the PreferDistinct strategy fairly interleaves chunks from different
submissions based on their strategic metadata.
"""
url = "file:///tmp/opsqueue/test_prefer_distinct_fairness"
producer_client = ProducerClient(f"localhost:{opsqueue.port}", url)
consumer_client = ConsumerClient(f"localhost:{opsqueue.port}", url)
company_ids = [1, 2, 3]
chunks_per_company = 4
company_id_per_submission = {}
for company_id in company_ids:
sub_id = producer_client.insert_submission(
[company_id] * chunks_per_company,
chunk_size=1,
strategic_metadata={"company_id": company_id},
)
company_id_per_submission[sub_id] = company_id
strategy = strategy_from_description(("PreferDistinct", "company_id", "Oldest"))
reserved_company_order = []
# Fetch 1 chunk at a time. Because we don't complete chunks, opsqueue's
# metastate tracks them as reserved, increasing the busy count for that
# company.
for _ in range(len(company_ids) * chunks_per_company):
[chunk] = consumer_client.reserve_chunks(strategy=strategy)
reserved_company_order.append(company_id_per_submission[chunk.submission_id])
assert reserved_company_order == [1, 2, 3] * chunks_per_company
12 changes: 7 additions & 5 deletions opsqueue/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ ux = "0.1.6"
anyhow = "1.0.102"
# Database:
sqlx = { version = "0.9.0", features = ["sqlite", "runtime-tokio", "chrono"], optional = true }
libsqlite3-sys = { version = "0.30.1", optional = true }
# Serialization:
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.149"
Expand Down Expand Up @@ -83,13 +84,14 @@ sqlformat = "0.5.0"
workspace = true

[dev-dependencies]
assert_matches = { version = "1.5.0" }
criterion = {version = "0.8", features = ["async_tokio"]}
insta = { version = "1.47.2" }
assert_matches = { version = "1.5.0" }

# [[bench]]
# name = "chunks_select"
# harness = false
[[bench]]
name = "chunks_select"
harness = false
required-features = ["server-logic"]

# [[bench]]
# name = "submissions_insert"
Expand All @@ -114,4 +116,4 @@ client-logic = [
"dep:tokio-tungstenite",
"dep:arc-swap",
]
default = ["server-logic"]
default = ["server-logic", "dep:libsqlite3-sys"]
Loading
Loading