Mailbox upload worker
The upload worker implementation is shared between the client for our own mailbox (#2290 (closed)) and the client for a contact's mailbox (#2289 (closed)). The worker's lifecycle is managed by the mailbox client, which in turn is managed by the mailbox client manager (#2228 (closed)).
Each upload worker is associated with a contact that has been assigned to a mailbox for upload. When a contact is reassigned to a different mailbox for upload, the old worker is destroyed and a new worker is created.
The worker can be in the following states:
- Checking for data to send
- Waiting for data to send
- Waiting for connectivity check
- Writing and uploading
- Destroyed
When the worker is created:
- Set the current state to "checking for data to send"
- Check for data to send
When the worker is destroyed:
- Set the current state to "destroyed"
- Cancel the current upload task, if any
To check for data to send:
- Load the time when data will next be ready to send to the contact
- If data is ready to send now:
- Set the current state to "waiting for connectivity check"
- Call the client's connectivity check method
- Else:
- Set the current state to "waiting for data to send"
- Schedule a wakeup task for the time when data will next be ready to send
When an event indicates that new data may be ready to send:
- If the current state is "waiting for data to send":
- Cancel the wakeup task
- Set the current state to "checking for data to send"
- Check for data to upload
When a wakeup task runs:
- If the current state is "waiting for data to send":
- Set the current state to "checking for data to send"
- Check for data to upload
When a connectivity check succeeds:
- If the current state is "waiting for connectivity check":
- Set the current state to "writing and uploading"
- Write and upload a file
To write and upload a file:
- Create a temporary file in the upload directory
- Pass the file's path to the mailbox plugin to get a transport connection writer
- Decorate the transport connection writer to handle disposal
- Create a deferred send handler
- Pass the decorated transport connection writer and the deferred send handler to the connection manager
- Data will be written to the file asynchronously
- The IDs of any sent/acked messages will be recorded by the deferred send handler
When the transport connection writer is disposed of:
- If the write succeeded:
- Start an upload task to upload the file to the mailbox (#2231 (closed))
- Else:
- Delete the file
- Set the current state to "checking for data to send"
- Check for data to send
When an upload task succeeds:
- Retrieve the sent/acked message IDs from the deferred send handler
- Mark the messages as sent/acked
- Delete the file
- Set the current state to "checking for data to send"
- Check for data to send
When an upload task is cancelled:
- Delete the file