Skip to content

[WIP] FEAT! Make queue_job dependencies optional#2105

Draft
ecino wants to merge 1 commit into
18.0from
ecino/queue-job-sh
Draft

[WIP] FEAT! Make queue_job dependencies optional#2105
ecino wants to merge 1 commit into
18.0from
ecino/queue-job-sh

Conversation

@ecino

@ecino ecino commented Jun 25, 2026

Copy link
Copy Markdown
Member
  • NEW module queue_job_sh_safe that will safely use queue_jobs when available and fallback to an alternate mechanism with ir_cron in case the module is not installed.
  • This is useful for Nordic using odoo.sh on which queue jobs are prohibited and not optimal for the infrastructure

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the queue_job_sh_safe module, which abstracts the OCA queue_job module to provide a fallback database-backed queue processed via a cron job when queue_job is not installed. This allows compatibility between dedicated environments and odoo.sh. Other modules are updated to depend on this new module and use the with_delay_sh method. Feedback on the changes highlights a critical transaction handling issue where exceptions caught inside the context manager could lead to partial commits, a performance bottleneck from instantiating a new registry with Registry.new(), and another bottleneck from querying ir.module.module on every delay call. Additionally, suggestions were made to use sudo() to prevent potential access errors for regular users and to dynamically filter unsupported fields during record creation.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread queue_job_sh_safe/models/queue_job_replacement.py Outdated
Comment thread queue_job_sh_safe/models/queue_job_replacement.py Outdated
Comment thread queue_job_sh_safe/models/base.py Outdated
Comment thread queue_job_sh_safe/models/queue_job_replacement.py
Comment thread queue_job_sh_safe/models/base.py Outdated
@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown

Confidence Score: 1/5

The queue fallback has multiple runtime paths that can fail or run work with the wrong execution context.

  • No-split fallback calls can crash before creating replacement jobs.
  • Chained replacement jobs can update the parent while leaving the child pending.
  • Cron execution does not switch to the stored enqueuing user.
  • partner_communication still reaches the queue-job-only API despite no longer depending on that module.

queue_job_sh_safe/models/base.py, queue_job_sh_safe/models/queue_job_replacement.py, and partner_communication/manifest.py

T-Rex T-Rex Logs

What T-Rex did

  • Inspected the pre-run log queue-fallback-01-before.log, which shows queue_job_present: false, a cron trigger, and two queue.job.replacement jobs in pending state for IDs [10] and [20] after with_delay_sh('safe_increment', 5, split=1).
  • Inspected the post-run log queue-fallback-02-after.log, which shows both replacement jobs processed by cron_run_jobs and now in done state with job_result values captured.
  • Validated the verification command exited with code 0.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (3): Last reviewed commit: "[WIP] FEAT! Make queue_job dependencies ..." | Re-trigger Greptile

Comment thread queue_job_sh_safe/security/ir.model.access.csv Outdated
Comment thread queue_job_sh_safe/models/queue_job_replacement.py
Comment thread queue_job_sh_safe/models/base.py Outdated
Comment thread queue_job_sh_safe/models/queue_job_replacement.py
Comment thread queue_job_sh_safe/models/base.py Outdated
@ecino ecino force-pushed the ecino/queue-job-sh branch from 07f6d5f to a0cad46 Compare June 25, 2026 18:40
@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_queue_job_replacement_group,queue.job.replacement.all,model_queue_job_replacement,queue_job_sh_safe.group_queue_job_replacement_user,1,1,1,1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Executable Jobs Remain Editable

The new access group still has full create and write access to rows that cron_run_jobs() executes from stored res_model, res_ids, job_function, and job_args. When an operator is assigned this UI group, they can create or edit a replacement job that the cron later runs as stored executable work, so the dispatch path still needs a read-only/operator split or an allowlist tied to jobs created by with_delay_sh.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment thread queue_job_sh_safe/models/base.py Outdated
Comment thread queue_job_sh_safe/models/queue_job_replacement.py
"base_report_to_printer", # OCA/report-print-send
"contacts",
"queue_job", # OCA/queue
"queue_job_sh_safe", # OCA/queue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Old Queue API Still Runs

This manifest no longer installs queue_job, but the automated-action code in partner_communication/models/ir_actions.py still searches self.env["queue.job"] and calls self.with_delay(...). In the intended no-queue_job deployment, triggering that action raises at runtime instead of using the replacement queue.

Comment thread message_center_compassion/__manifest__.py
- NEW module queue_job_sh_safe that will safely use queue_jobs when available and fallback to an alternate mechanism with ir_cron in case the module is not installed.
- This is useful for Nordic using odoo.sh on which queue jobs are prohibited and not optimal for the infrastructure
@ecino ecino force-pushed the ecino/queue-job-sh branch from a0cad46 to e2d8348 Compare June 25, 2026 19:08
"user_id": self.env.user.id,
**delay_args,
}
for i in range(0, len(self), min(split, 1))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Unsplit Jobs Crash Immediately

When a caller omits split, split defaults to 0, so this fallback builds range(0, len(self), 0) and raises ValueError before creating any replacement job. The migrated S2B button calls with_delay_sh("generate_letters_job", identity_key=...) without split, so no-queue_job deployments show a traceback and never queue the letter generation.

Comment on lines +69 to +77
while job_new_env and not job_new_env.is_predecessor_complete:
job_new_env = job_new_env.parent_job_id
if not job_new_env:
continue
job_new_env.state = "processing"
records = new_env[job.res_model].browse(literal_eval(job.res_ids))
job_function = getattr(records, job.job_function)
job_result = job_function(*literal_eval(job.job_args))
job_new_env.write({"state": "done", "job_result": str(job_result)})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Blocked Child Rewrites Parent

When a chained child is pending and its parent is failed or still not done, this loop walks job_new_env to the parent but still executes the original child's stored method. The cron then writes processing and done onto the parent with the child's result while leaving the child pending, so the GMC chained batches can revive a failed predecessor and rerun the child on the next cron cycle.

Comment on lines +74 to +76
records = new_env[job.res_model].browse(literal_eval(job.res_ids))
job_function = getattr(records, job.job_function)
job_result = job_function(*literal_eval(job.job_args))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Queued Work Runs As Admin

with_delay_sh stores the enqueuing user_id, but cron dispatch browses records and calls the job method in the cron environment instead of switching to that user. In no-queue_job deployments, queued methods that normally depend on record rules or env.user now run as the cron/admin user and can perform work outside the original caller's permissions.

"contacts",
"queue_job", # OCA/queue
"queue_job_sh_safe", # OCA/queue
"mass_mailing_sms",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Queue API Still Required

This manifest no longer installs queue_job, but partner_communication still has direct with_delay() callers in its models and wizard code. On the intended Odoo.sh setup with only queue_job_sh_safe, those workflows raise AttributeError instead of using the fallback queue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant