[18.0][ADD] queue_job: per DB channel managers with UI configuration and hot reload - #962
[18.0][ADD] queue_job: per DB channel managers with UI configuration and hot reload#962guewen wants to merge 9 commits into
Conversation
|
Hi @sbidoul, |
Not used at this point by the jobrunner, but the changes on channels trigger a notify to the jobrunner.
688eee4 to
9b9e3fd
Compare
9b9e3fd to
934ccb4
Compare
…el managers by DB
|
Hi @sbidoul , can I have your thoughts on this, before I start completing the tests and docs? |
|
Hi @sbidoul, |
sbidoul
left a comment
There was a problem hiding this comment.
Hi Guewen,
I have not had time to do a proper review, but I think I'm on board with this.
Great solution!
I have some doubts about the round robin rule, but on the other hand I don't have serious multi-db use cases myself so this can be addressed later.
| capacity: int = 0 | ||
| sequential: bool = False | ||
| throttle: int = 0 | ||
| paused: bool = False |
There was a problem hiding this comment.
Handle the new default subchannel capacity too?
There was a problem hiding this comment.
It looks like the subchannel pull request (#767) has a merge conflict. I'll take a look at it today.
There was a problem hiding this comment.
Ah I thought that was merged already.
|
I'm writing a benchmark script to have some comparison points (I'll open another PR for the script at some point). It also demonstrates an interesting effect of the round-robin (nothing surprising but nice to see it with numbers). In the current state of my benchmark, the script enqueues 5k jobs in db0, then 5k in db1, then 5k in db2. With the global channel manager, the jobrunner executes the jobs strictly by creation order, so the 5k jobs of db0 are executed, then those of db1 and finally those of db2. The round-robin (yet to test in real situation, which I do not have as we have a single DB in production), might help in situations where a large DB clutters the queue with a large quantity of jobs and starve other databases. Do not give much value to the number otherwise, it is only a single run of each. global channel manager The throughput per database is much higher than the round-robin version: this is because the results are based on when the 5000 jobs are started and when they are all done, and all jobs the bench0 are done before the others, the 5k jobs are done much earlier. round-robin In the round-robin version, the throughput is equal for each database, because their jobs are all starting and ending at about the same points. memo for myself on the benchmark |
A single database running multiple companies can also find itself at the mercy of strict creation order. |
This one won't be solved though |
Implements #765 (comment)
Introduction of new configuration parameters
With this in the config file, the job runner uses the static server-side configuration as before, with no hot-reload (single, shared channel manager):
With this in the config file, the job runner uses the channels configured in the database (the job runner builds one channel manager per database):
When capacity or other options of a channel (or channels are created/deleted, paused) change, the channel manager for the concerned database is hot reloaded.
Capacity can be constrained by database:
Or with patterns
When
db_max_capacityis not configured, each database gets a max capacity of the globalmax_capacity.When there is more jobs pending than
max_capacityacross the databases, a round-robin allows each database to enqueue jobs in turns.The
channelsoption for server-side configuration takes precedence over the new configuration.What does this bring?
Using this, I can, for instance
Migration path
Since the server-side configuration (
ODOO_QUEUE_JOB_CHANNELSorchannelsin config file) is used by default, updating the addon has no effect. It allows to configure the channels capacity and other options on the UI / by script of the databases, then the server-side configuration can be replaced by the parametersmax_capacityanddb_max_capacity(or their environment variables counterparts).Caveat
When using per DB channel managers, we cannot have a shared channel for several databases since each database has its own channels (use case mentioned in #765 (comment)). It could be possible to implement it using a single channel manager that coexists with the db channel managers, yet to define the specifics, e.g. use another root (
shared:3, shared.foo:2) or a new optionshared_channels = root.sharedwhere the subchannels defined in this option are excluded from the DB channels.In the meantime, using the server-side channels instead of per-db channels is a trade-off to accept if this use case is essential for a server.