Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR #590 introduced a more flexible unique job mechanism that allowed for the unique states to be customized, all while still benefiting from the performance improvements of using a unique index rather than an advisory lock. The
retryable
state is included in the default list of states, but can be removed if the user doesn't want to prevent an erroring job from blocking duplicate inserts.However this created an issue: when trying to schedule a
retryable
job (move it toavailable
) it could potentially have a conflict with a duplicate unique job. To handle this, special logic was added to try to deal with this scenario for unique jobs, moving the conflicting row todiscarded
rather thanavailable
. Unfortunately this logic had issues and was insufficiently tested. There were a couple specific scenarios that caused issues:scheduled
or had errored and becomeretryable
would actually be considered a conflict with itself because the query didn't properly exclude the row being scheduled.retryable
unique jobs at the same time would lead to a unique conflict because there was no mechanism to prevent this.The query changes in this PR address both of the above cases along with test coverage.
The increased complexity is unfortunate, and we're probably nearing the limit of what should be dealt with in a single SQL query. If this still isn't complete I'm more inclined to fix the issues by catching these conflicts at the application level, explicitly moving the conflicting row(s) to
discarded
, and trying again. This can be looped with a backoff or recursed to ensure that progress keeps being made as individual conflicts get resolved. But hopefully that won't be necessary.Fixes #618.