경쟁 상태란 두 개 이상의 프로세스나 스레드가 공유 자원에 동시에 접근하여 읽거나 쓰려고 할 때, 접근 순서에 따라 실행 결과가 달라지는 현상입니다.

다음은 이번에 OnPyRunner를 개선하면서 발생한 예시입니다. 처음에 제가 의도하고, 작성한 코드의 흐름은 다음과 같습니다.

API ServerWorker
1. 큐에 작업 추가
2. Redis에 PENDING 기록
3. 큐에서 작업 꺼내기
4. Redis에 RUNNING 기록

여기서 저는 당연히 코드가 의도한 대로 Redis에는 항상 PENDING 후에 RUNNING이 기록될 것이라고 생각했습니다.

하지만 아래의 경우는 아닙니다.

API ServerWorker
1. 큐에 작업 추가
2. 큐에서 작업 꺼내기
3. Redis에 RUNNING 기록
4. Redis에 PENDING 기록

제가 놓친 부분은 서로 다른 프로세스가 함께 돌아갈 때, 그 순서를 보장하도록 명시하지 않았다는 것입니다.
이 문제를 해결하기 위해 가장 간단한 방법은 그냥 순서를 바꾸는 것입니다.
API Server가 Redis에 PENDING을 먼저 기록하게 하고, 그 후 큐에 작업을 추가하는 것으로 해결할 수 있습니다.

API ServerWorker
1. Redis에 PENDING 기록
2. 큐에 작업 추가
3. 큐에서 작업 꺼내기
4. Redis에 RUNNING 기록

물건이 들어와야 나간다는 Queue의 특성을 이용하는 것입니다.

문제는 해결하였습니다.
하지만 같은 실수를 반복하지 않으려면 어떤식으로 생각해야할까요?

데이터를 바라볼 때 누가 그 데이터를 바꾸는지를 보아야 합니다.
Redis에 Job의 State를 기록하는 주체는 API Server와 Worker가 있습니다. 서로가 서로의 작업에 끼어들어 접근 순서가 달라질 때, 그 때도 데이터 상태의 순서(PENDING 다음 RUNNING이 오는 순서)가 역전되지 않는지를 생각해야 합니다.

나아가서 결정론적인 테스트를 통해 상태가 역전 흐름이 발생하는지를 검증하려면 어떻게 해야할까요?

아마 다음 이야기가 될 것 같습니다.