Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 12 additions & 4 deletions queue_job/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,15 +245,23 @@ def _job_store_values(self, job):

@api.model
def _job_prepare_context_before_enqueue_keys(self):
"""Keys to keep in context of stored jobs
Empty by default for backward compatibility.
"""
return ("tz", "lang", "allowed_company_ids", "force_company", "active_test")
"""Keys to keep in context of stored jobs"""
keys = self.env.context.get("queue_job_context_keys")
return (
"tz",
"lang",
"allowed_company_ids",
"force_company",
"active_test",
*(keys or ()),
)

def _job_prepare_context_before_enqueue(self):
"""Return the context to store in the jobs
Can be used to keep only safe keys.
"""
if self.env.context.get("queue_job_keep_context"):
return self.env.context
return {
key: value
for key, value in self.env.context.items()
Expand Down
28 changes: 25 additions & 3 deletions queue_job/readme/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,16 +276,38 @@ Based on this configuration, we can tell that:
- retries 10 to 15 postponed 30 seconds later
- all subsequent retries postponed 5 minutes later

**Job Context**
#### Job Context

The context of the recordset of the job, or any recordset passed in
arguments of a job, is transferred to the job according to an
allow-list.

The default allow-list is ("tz", "lang", "allowed_company_ids",
"force_company", "active_test"). It can be customized in
`Base._job_prepare_context_before_enqueue_keys`. **Bypass jobs on
running Odoo**
`Base._job_prepare_context_before_enqueue_keys`.

When the `queue_job_context_keys` context variable is set, preserve
the given keys in addition to those normally specified by
`_job_prepare_context_before_enqueue_keys`. Examples:

```python
# existing context
record.with_context(queue_job_context_keys=['a']).with_delay().func()
# new context
record.with_context(b=1, queue_job_context_keys=['b']).with_delay().func()
```

When the `queue_job_keep_context` context variable is set, always
preserve the entire context. This honors the principle of least
surprise, in that a developer can easily convert a record.method()
call to record.with_delay().method() with the expectation that it will
actually execute the same, simply at a later time. Example:

```python
record.with_context(queue_job_keep_context=True).with_delay().func()
```

**Bypass jobs on running Odoo**

When you are developing (ie: connector modules) you might want to bypass
the queue job and run your code immediately.
Expand Down
46 changes: 46 additions & 0 deletions queue_job/tests/test_json_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,52 @@ def test_encoder_recordset(self):
}
self.assertEqual(json.loads(value_json), expected)

def test_encoder_recordset_context_keys(self):
demo_user = self.env.ref("base.user_demo")
context = {
**demo_user.context_get(),
"foo": "bar",
"baz": "zeb",
"queue_job_context_keys": ["foo"],
}
partner = self.env(user=demo_user, context=context).ref("base.main_partner")
value = partner
value_json = json.dumps(value, cls=JobEncoder)
expected_context = context.copy()
expected_context.pop("baz")
expected_context.pop("queue_job_context_keys")
expected_context.pop("uid")
expected = {
"uid": demo_user.id,
"_type": "odoo_recordset",
"model": "res.partner",
"ids": [partner.id],
"su": False,
"context": expected_context,
}
self.assertEqual(json.loads(value_json), expected)

def test_encoder_recordset_keep_context(self):
demo_user = self.env.ref("base.user_demo")
context = {
**demo_user.context_get(),
"foo": "bar",
"queue_job_keep_context": True,
}
partner = self.env(user=demo_user, context=context).ref("base.main_partner")
value = partner
value_json = json.dumps(value, cls=JobEncoder)
expected_context = context.copy()
expected = {
"uid": demo_user.id,
"_type": "odoo_recordset",
"model": "res.partner",
"ids": [partner.id],
"su": False,
"context": expected_context,
}
self.assertEqual(json.loads(value_json), expected)

def test_encoder_recordset_list(self):
demo_user = self.env.ref("base.user_demo")
context = demo_user.context_get()
Expand Down