Skip to content

Commit 273a641

Browse files
committed
documentation updates, changelog
1 parent ea8b94b commit 273a641

File tree

4 files changed

+39
-16
lines changed

4 files changed

+39
-16
lines changed

CHANGELOG.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Breaking
11+
12+
- **Breaking change:** The return type of `Client#insert_many` and `Client#insert_many_tx` has been changed. Rather than returning just the number of rows inserted, it returns an array of all the `InsertResult` values for each inserted row. Unique conflicts which are skipped as duplicates are indicated in the same fashion as single inserts (the `unique_skipped_as_duplicated` attribute), and in such cases the conflicting row will be returned instead. [PR #38](https://github.com/riverqueue/riverqueue-python/pull/38).
13+
- **Breaking change:** Unique jobs no longer allow total customization of their states when using the `by_state` option. The pending, scheduled, available, and running states are required whenever customizing this list.
14+
15+
### Added
16+
17+
- The `UniqueOpts` class gains an `exclude_kind` option for cases where uniqueness needs to be guaranteed across multiple job types.
18+
- Unique jobs utilizing `by_args` can now also opt to have a subset of the job's arguments considered for uniqueness. For example, you could choose to consider only the `customer_id` field while ignoring the other fields:
19+
20+
```python
21+
UniqueOpts(by_args=["customer_id"])
22+
```
23+
24+
Any fields considered in uniqueness are also sorted alphabetically in order to guarantee a consistent result across implementations, even if the encoded JSON isn't sorted consistently.
25+
26+
### Changed
27+
28+
- Unique jobs have been improved to allow bulk insertion of unique jobs via `Client#insert_many`.
29+
30+
This updated implementation is significantly faster due to the removal of advisory locks in favor of an index-backed uniqueness system, while allowing some flexibility in which job states are considered. However, not all states may be removed from consideration when using the `by_state` option; pending, scheduled, available, and running states are required whenever customizing this list.
31+
1032
## [0.7.0] - 2024-07-30
1133

1234
### Changed
@@ -79,4 +101,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
79101

80102
### Added
81103

82-
- Initial release, supporting insertion through [SQLAlchemy](https://www.sqlalchemy.org/) and its underlying Postgres drivers like [`psycopg2`](https://pypi.org/project/psycopg2/) or [`asyncpg`](https://github.com/MagicStack/asyncpg) (for async).
104+
- Initial release, supporting insertion through [SQLAlchemy](https://www.sqlalchemy.org/) and its underlying Postgres drivers like [`psycopg2`](https://pypi.org/project/psycopg2/) or [`asyncpg`](https://github.com/MagicStack/asyncpg) (for async).

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,14 @@ insert_res.job
9595
insert_res.unique_skipped_as_duplicated
9696
```
9797

98+
Unique jobs can also be inserted in bulk.
99+
98100
## Inserting jobs in bulk
99101

100102
Use `#insert_many` to bulk insert jobs as a single operation for improved efficiency:
101103

102104
```python
103-
num_inserted = client.insert_many([
105+
results = client.insert_many([
104106
SimpleArgs(job_num=1),
105107
SimpleArgs(job_num=2)
106108
])
@@ -109,7 +111,7 @@ num_inserted = client.insert_many([
109111
Or with `InsertManyParams`, which may include insertion options:
110112

111113
```python
112-
num_inserted = client.insert_many([
114+
results = client.insert_many([
113115
InsertManyParams(args=SimpleArgs(job_num=1), insert_opts=riverqueue.InsertOpts(max_attempts=5)),
114116
InsertManyParams(args=SimpleArgs(job_num=2), insert_opts=riverqueue.InsertOpts(queue="high_priority"))
115117
])

src/riverqueue/insert_opts.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,8 @@ class UniqueOpts:
8282
args and queues. If either args or queue is changed on a new job, it's
8383
allowed to be inserted as a new job.
8484
85-
TODO update description ⚠ ⚠️ ⚠
86-
87-
Uniquenes is checked at insert time by taking a Postgres advisory lock,
88-
doing a look up for an equivalent row, and inserting only if none was found.
89-
There's no database-level mechanism that guarantees jobs stay unique, so if
90-
an equivalent row is inserted out of band (or batch inserted, where a unique
91-
check doesn't occur), it's conceivable that duplicates could coexist.
85+
Uniqueness relies on a hash of the job kind and any unique properties along
86+
with a database unique constraint.
9287
"""
9388

9489
by_args: Optional[Union[Literal[True], List[str]]] = None
@@ -98,6 +93,14 @@ class UniqueOpts:
9893
9994
Default is false, meaning that as long as any other unique property is
10095
enabled, uniqueness will be enforced for a kind regardless of input args.
96+
97+
When set to true, the entire encoded args will be included in the uniqueness
98+
hash, which requires care to ensure that no irrelevant args are factored
99+
into the uniqueness check. It is also possible to use a subset of the args
100+
by passing a list of string keys to include in the uniqueness check.
101+
102+
All keys are sorted alphabetically before hashing to ensure consistent
103+
results.
101104
"""
102105

103106
by_period: Optional[int] = None

tests/client_test.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,8 @@ def to_json(self) -> str:
295295
ordered_json = '{"a": 1, "b": 2, "c": 3}'
296296
reverse_ordered_json = '{"c": 3, "b": 2, "a": 1}'
297297

298-
insert_res1 = client.insert(
299-
JsonArgs(json_str=ordered_json), insert_opts=insert_opts
300-
)
301-
insert_res2 = client.insert(
302-
JsonArgs(json_str=reverse_ordered_json), insert_opts=insert_opts
303-
)
298+
client.insert(JsonArgs(json_str=ordered_json), insert_opts=insert_opts)
299+
client.insert(JsonArgs(json_str=reverse_ordered_json), insert_opts=insert_opts)
304300

305301
# Get the unique keys that were generated
306302
call_args1 = mock_exec.job_insert_many.call_args_list[0][0][0] # type: ignore[index]

0 commit comments

Comments
 (0)