fix(search_jobs): prevent job state flip-flopping between 'queued' and 'processing' (#64098)

Fixes SPLF-170

This fixes a bug in our status reporting where we would report a job as
"queued" although it should be reported as "processing". In some cases
this led to the state flip-flopping between "queued" and "processing".

This happens, for example, if a worker has just finished a repo-rev job
(and set it to completed) but hasn't yet dequeued a new job. In this
brief period we reported the entire search job as queued.

Test plan:
- updated unit test
- manual testing

I ran the following search job which previously exhibited this behavior
and verified that now it doesn't.
```
context:global r:^github\.com/sourcegraph/sourcegraph$@*refs/heads/* ghp_.+ patterntype:regexp
```
This commit is contained in:
Stefan Hengl 2024-07-29 14:57:12 +02:00 committed by GitHub
parent 67c9a09059
commit 5d4d003107
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 3 deletions

View File

@ -264,8 +264,11 @@ const aggStateSubQuery = `
CASE
WHEN canceled > 0 THEN 'canceled'
WHEN processing > 0 THEN 'processing'
WHEN queued > 0 THEN 'queued'
-- errored jobs will be retried, so we treat them as processing
WHEN errored > 0 THEN 'processing'
WHEN queued > 0 AND completed is null THEN 'queued'
-- this condition is necessary to avoid returning 'queued' when there are no jobs processing at the moment
WHEN queued > 0 THEN 'processing'
WHEN failed > 0 THEN 'failed'
WHEN completed > 0 THEN 'completed'
-- This should never happen

View File

@ -368,7 +368,16 @@ func TestStore_AggregateStatus(t *testing.T) {
searchJob: types.JobStateCompleted,
repoJobs: []types.JobState{types.JobStateQueued},
},
want: types.JobStateQueued,
want: types.JobStateProcessing,
},
{
name: "no job is processing, some are completed, some are queued",
c: stateCascade{
searchJob: types.JobStateCompleted,
repoJobs: []types.JobState{types.JobStateCompleted},
repoRevJobs: []types.JobState{types.JobStateCompleted, types.JobStateQueued},
},
want: types.JobStateProcessing,
},
{
name: "search job is queued, but no other job has been created yet",
@ -380,7 +389,7 @@ func TestStore_AggregateStatus(t *testing.T) {
}
for i, tt := range tc {
t.Run("", func(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
userID, err := createUser(bs, fmt.Sprintf("user_%d", i))
require.NoError(t, err)