Testing, connecting and finding documents can take long, up to the driver's server selection timeout. They run as background tasks in Rust, so the UI stays responsive and the user can cancel them.
Rust (task_manager/)
TaskManagerkeeps two maps keyed by a uuid: the tokioJoinHandleof each task and itsAbortHandle.- A
start_*command passes its future tospawn_task, which spawns it and returns the id at once. The future resolves toResult<serde_json::Value, serde_json::Value>: the result, or the serialized error. await_task_result(id)takes theJoinHandleout of the map and awaits it:Ok(value)is the result.- The future's error becomes
TaskError::Failed(value). - An aborted task becomes
TaskError::Cancelled, a panic becomesFailedwith kindPanic. - Afterwards the abort handle is removed.
cancel_task(id)callsabort()on the handle. An unknown id isTaskError::NotFound.TaskErrorserializes like every other error, withkind,messageanduser_message. ForFailedthemessageis the JSON text of the original error.
The commands that use it are start_test_connection, start_connect and start_find_documents.
UI (composables/useAbortableCommand.ts)
abortableInvoke(startCommand, args, { signal })invokes the start command, thenawait_task_result. If theAbortSignalfires in between, it callscancel_task.- Errors are unwrapped:
- an aborted signal or kind
CancelledthrowsTaskCancelledError - kind
Failedthrows the original error, parsed back frommessage, so the caller gets the driver'suser_message - anything else is rethrown as it is
- an aborted signal or kind
ConnectionServiceIPC.testConnection,connectandfindDocumentsuse it. The store keeps oneAbortControllerfor the test and one for connecting; Cancel callsabort()on it.
- A task registry of our own instead of a timeout (
a14c8fc, issue #27). The user decides when to give up, and the same mechanism serves every slow command. - The error travels as JSON and is unwrapped in the UI, so the toast shows the driver's message and not "The operation failed".
| Date | Step | Commit |
|---|---|---|
| 2026-02-21 | TaskManager, cancel_task, await_task_result, abortableInvoke; test and connect as tasks |
a14c8fc |
| 2026-02-23 | start_find_documents as a task |
cbc9b83 |
- The query tab doesn't use it.
TabViewQueryinvokesstart_find_documentsandawait_task_resultdirectly instead ofConnectionServiceIPC.findDocuments. A query can't be cancelled, and its errors aren't unwrapped (see query-tab.md). - A task that is never awaited stays in both maps. Today every start is awaited right after.
- Aborting drops the future. A MongoDB operation that already reached the server is not killed on the server.
- No tests for the task manager.
| What | Path |
|---|---|
| Registry | src-tauri/src/task_manager/task_manager.rs |
| Commands | src-tauri/src/task_manager/commands.rs |
| Error | src-tauri/src/task_manager/task_error.rs |
| UI helper | src/composables/useAbortableCommand.ts |
| Callers | src/domains/connections/services/ConnectionServiceIPC.ts, src/stores/connectionStore.ts |