|
On detecting an indexing error, the build aborts immediately and proceeds to cleanup. During cleanup, there's a check to see if the index build is already in kAborted state. If an external aborter concurrently set the state to kAborted, before the builder performs the check, then the builder will exit early. On the other hand, it can be the case that the external abort happens after the builder checks, in which case we can hit a deadlock between the external and internal abort.
External abort happening before the check:
| Collection drop (external abort) |
Index Builder (self abort) |
|
|
Indexing error (still kInProgress) |
|
|
Transitioning to cleanup code |
| abortIndexBuildByBuildUUID |
|
| Coll Lock MODE_X |
|
| setState(kAborted) |
|
| killOp |
|
| _completeAbort |
|
| wait for future |
|
|
|
replState->isAborted() (true) |
|
|
signal promise |
| future wait ends |
|
External abort after the check (deadlock):
| Collection drop (external abort) |
Index Builder (self abort) |
|
|
Indexing error (still kInProgress) |
|
|
replState->isAborted() (false) |
| abortIndexBuildByBuildUUID |
|
| Coll Lock MODE_X |
|
| setState(kAborted) |
|
| killOp |
|
| _completeAbort |
|
| wait for future (stuck here) |
|
|
|
proceed with self abort |
|
|
Coll Lock MODE_X (waiting for lock) |
|
|
... |
|
|
signal promise (never gets here) |
|