I also wonder how the Import/Export process works; it can take half an hour depending on the number of records, yet it is never interrupted by this restart. I would appreciate any comments on this matter, as well as any recommendations you might offer to resolve my issue and allow the transaction to proceed to completion without being interrupted by the worker's meeting.
To pytanie dostało ostrzeżenie
Yeah, I've hit this exact thing before. What's happening is your whole Odoo process is getting SIGTERM'd from outside, not one worker timing out. You can tell from the exact wording — "Initiating shutdown" only gets logged when the master process itself catches SIGINT/SIGTERM and starts tearing everything down. If it was Odoo's own CPU or real-time limit killing a worker, the log would say something like "CPU time limit reached" or "timeout after Xs," and only that one worker would die and get respawned — the rest of the server keeps running fine. What you've got is the container itself getting killed, which is why your cursors and sessions vanish all at once instead of just one request failing. Pull up the Logs tab on that branch and check what's logged right at 20:34:03, it'll usually line up with a build or deploy on that branch. That's your actual trigger, not a code-side timeout.
Also don't bother protecting against overlapping runs, that's already built in. ir.cron locks the row it's working on (FOR NO KEY UPDATE SKIP LOCKED), so if you set it to run every minute and the previous run's still going, it just gets skipped, not double-run. So the 5 minute interval was never buying you safety, it was just slowing you down for no reason.
The actual fix for your batching problem: Odoo 18 added a proper progress API to ir.cron that a lot of people haven't found yet. It didn't exist in 17. Instead of your cron method running once per interval, Odoo will now call it up to 10 times back to back in a single pass, committing in between each call, as long as your method reports progress with _notify_progress(done=X, remaining=Y). If there's still stuff left after those 10 rounds, it doesn't wait for the interval to come back around, it just marks itself ready again and gets picked up on the next poll, which is about 60 seconds, not 5 minutes. And if a worker dies mid-batch like yours is doing, it counts that as a timeout and retries automatically instead of just failing the whole job.
That's what fixes your 225 minute problem. 45k records at 100 per batch was 450 runs waiting 5 minutes apart. With this you get up to 1,000 records per minute-ish poll cycle, and it survives the restarts on its own instead of you babysitting where it left off.
def _cron_migrate_records(self):
Model = self.env['my.model']
domain = [('migration_state', '=', 'pending')]
batch = Model.search(domain, limit=200, order='id')
if not batch:
self.env['ir.cron']._notify_progress(done=0, remaining=0)
return
for rec in batch:
rec._do_migration_step()
batch.write({'migration_state': 'done'})
self.env.cr.commit()
remaining = Model.search_count(domain)
self.env['ir.cron']._notify_progress(done=len(batch), remaining=remaining)
Set the cron's own interval to daily or whatever, doesn't matter, then just call _trigger() once to kick it off. The progress loop does the rest on its own.
For the "records might change mid-run" thing, skip the table lock entirely, long locks on Odoo.sh just bite you later. Grab max(id) once when the run starts and filter every batch against that. Anything created or edited after that point just doesn't exist as far as this run's concerned, it'll get caught next time.
And to answer why import/export doesn't choke on this — same trick, different driver. execute_import takes a limit param and returns a batch flag when there's more rows left, so it's actually your browser firing off request after request behind the scenes, not one big call. Same batching idea, just the client's doing the looping instead of the cron scheduler.
If you outgrow even this — need retries with backoff, priority queues, a way to see what actually failed — grab OCA's queue_job, that's what it's for. SSH + tmux works too for a one-time migration, just remember it's sitting in the same container, so a branch restart takes that down exactly the same way, it's not actually safer.
Podoba Ci się ta dyskusja? Dołącz do niej!
Stwórz konto dzisiaj, aby cieszyć się ekskluzywnymi funkcjami i wchodzić w interakcje z naszą wspaniałą społecznością!
Zarejestruj się| Powiązane posty | Odpowiedzi | Widoki | Czynność | |
|---|---|---|---|---|
|
|
1
lis 25
|
10680 | ||
|
|
1
paź 25
|
8794 | ||
|
|
0
lip 26
|
25 | ||
|
|
0
mar 26
|
3 | ||
|
|
1
lis 25
|
4498 |