Add support for job dependencies in pg boss - #747
Conversation
0b130fa to
fb7a8e7
Compare
|
Thanks for submitting this. I have a few change requests on the implementation. When creating a "dep graph", "flow", etc., there is the possibility of race conditions, and I'm wondering what weaknesses this introduces into how to support issues that may come up. Since the job creation is not batched into a transaction, there is the possibility that a dependent job is completed before a dependency on it is created. I'm not sure what complexity this creates, but one mitigation I noticed after reading Bull's flow docs is they require all payloads/jobs in the same request. If we constrain ourselves to a single batch request, we could assign blocking and blocked simultaneously without requiring another round trip. My other primary concern is how to mitigate excessive querying that starts with the join in the children_to_check CTE, since the where condition won't prevent hitting the dependency table. I don't have a quick suggestion to this yet, but I'm thinking about how that query could become opt-in somehow. |
|
I agree with both of your concerns. For the first one: For the second: Add a Queues that never participate in dependencies never see the extra CTEs — zero overhead, not even in the query plan. WDYT? |
|
I like your thought of using the queue and maybe also the cache. That would address a noisy neighbor use case. It does have the downside of affecting all jobs in that queue, however. Are you imagining a situation where you either only use deps on a queue for every job or never use them? My first thought when you opened the issue was "some jobs in this queue might have deps and some won't". |
Yes, my requirement is some jobs would have deps and some not. Do you have any other idea? |
This will require resetting the cache across all connected instances. I like the concept, but in a distributed setup, we'd have a race condition issue to deal with. I'm still looking at alternatives to bypassing the downstream CTE. One option is to inspect the results to see if flows were involved, then have the client issue another query to process them. It's not as elegant as a single command, for sure. A pg function could also be created that would be able to run this in a single transaction via control flow. |
|
I find the pg function a nice idea. Do you want me to approach this way and discuss after this? The function would be: |
|
Moved here #777 |
Summary
Add first-class job dependencies to pg-boss — a job can declare
dependsOnparent jobs and won't be fetched until all parents complete. Enables fan-in and pipeline patterns without application-level orchestration.What changed
dependsOnoption onsend()/insert()— dependent jobs are inserted asblocked = true, invisible tofetchjob_dependencytable — normalized parent/child tracking with efficient indexes for both directionscompleteJobschecks and unblocks children when all parents are done (no-op for queues without dependencies)blockingflag on parent jobs — lets the completion CTE short-circuitjob_i5fetch index — addsAND NOT blockedat the index level, zero cost for non-dependent jobsgetDependencies()/getDependents()— query the dependency graphUsage
Resolves #745