-
Notifications
You must be signed in to change notification settings - Fork 0
Concurrency Cancellation and Errors
The project enables Swift 6 with complete strict-concurrency checking.
| Boundary | Isolation |
|---|---|
| Observable application and setup state | @MainActor |
| TDLib requests and pending continuations |
TDLibClient actor |
| Telegram session lifecycle |
TelegramSessionController actor |
| Chat normalization |
ChatRepository actor |
| History scanning |
AttachmentHistoryService actor |
| Download scheduling |
DownloadCoordinator actor |
| Destination bookmark and placement |
DestinationAccess actor |
| JSON persistence | One actor per store |
| Cross-boundary domain data | Value types conforming to Sendable
|
TDLibReceiveLoop is marked @unchecked Sendable because it wraps the
blocking native receive boundary. Its surface is deliberately small and feeds
ordered values into actor-isolated Swift state.
Every scan receives a unique scan ID and an AttachmentScanKey. Progress is
accepted only if:
- the scan ID is still active;
- the cache's active key matches;
- the currently requested chat and range still match.
Leaving Browse, changing chat, changing range, refreshing, or pressing Cancel stops the active task. Late updates cannot activate themselves in another context.
The coordinator uses a task group and a small loop state:
-
nextIndexidentifies unscheduled work; -
runningCounttracks child tasks; - records contain completed outcomes;
- scheduling fills available concurrency slots;
- pause prevents new scheduling;
- cancel stops scheduling and cancels active Telegram file IDs.
Progress callbacks cross back to AppModel on the main actor. The batch state
can be Preparing, Downloading, Pausing, Paused, or Cancelling.
Infrastructure uses typed errors for conditions the UI can recover from:
- TDLib invalid envelope, transport failure, remote error, closure;
- destination unavailable, stale bookmark, not writable, unsafe filename, size mismatch, insufficient space;
- Keychain status and invalid stored data;
- chat-store unavailable, unreadable, or unwritable.
The presentation layer maps these errors to product copy. It does not expose raw authorization JSON, paths, or private Telegram payloads.
- A chat-cache write failure does not authorize cross-chat state.
- An attachment snapshot write failure does not discard the in-memory scan.
- A history write failure keeps current records visible and presents a history error.
- A pending-batch write failure reports that recovery could not be saved.
- Placement failure removes the temporary file when possible.
- A single file failure becomes a record and does not erase successful files.
Production code avoids force unwraps and try!. Optional runtime resources are
resolved through guarded paths, and dependency injection makes failure cases
testable without a live account.
Unspool is an independent project and is not affiliated with Telegram. Repository · Privacy · Security · MIT License
- Getting Started
- Detailed Telegram Setup
- Feature Overview
- Chats and History
- Attachments and Filenames
- Search and Selection
- Download Workflow
- Conflicts and Recovery
- Download History
- Settings
- Accessibility
- Troubleshooting
- Detailed Troubleshooting and FAQ
- Privacy and Security
- Detailed Security Model
- TDLib Integration
- Persistence
- Concurrency and Errors
- Glossary