Currently, when you save a draft with attachments in the e-mail app, the
attached files will be duplicated from wherever they came from (probably
DeviceStorage) into the IndexedDB blob store. It's my understanding
that we model the internal storage where IndexedDB lives as very
limited, so this is a bad idea.
The nice things are that:
- IndexedDB does all the book-keeping so that when the Blobs are no
longer referenced by the DB or the app the Blobs go away.
- We don't run into the horrible problem where the user swaps their SD
card out with another one because they want to listen to a different set
of music and now the e-mail app is missing all kinds of important data
it needs.
There is the begged question of whether the e-mail app should try and
avoid creating duplicate copies of blobs when the Blob is actually a
File from DeviceStorage and we are able to detect this. (Do Files
express the DeviceStorage storage areas they came from? Would we just
try and reverse map based on mime-type or hope sdcard and the storage
name line up exactly?) If we did this, there is the potential UX
problem of the user deleting the attachment after attaching it to a
message, but either way, the issues below still hold.
I am currently overhauling some aspects of mail sending so that we can
stream the contents of the composed message over the network rather than
generating a single in-memory string that potentially kills the app
without the message getting sent, so I would like to choose the
correct/best option.
My planned changes call for storing the attachment portions of messages
as pre-base64-encoded rfc2822 MIME body (sub-)parts. This is primarily
driven by the fact that ActiveSync uses XHR to communicate with the
server and so we need to provide it with a Blob since we can't generate
the data on demand as our network buffers empty out. If we were
chrome-space, we could apparently implement nsIInputStream and pass that
in, but we aren't. For IMAP and SMTP we use mozTCPSocket which does
allow us to generate data on demand by virtue of providing flow control
signalling via return values and 'drain' events. We could, of course,
re-implement XHR on top of mozTCPSocket to try and get around that
problem, but that's pretty undesirable. By storing the attachments as
pre-encoded on-disk blobs, this lets us stitch together a single
super-Blob from the less memory-intensive MIME parts and the
living-on-disk attachments when we go to SMTP send, IMAP APPEND, or
ActiveSync send. It's notable that the SMTP and IMAP operations may
potentially vary in representation if there are any bcc recipients.
So the question is then whether to use IndexedDB or DeviceStorage. For
DeviceStorage, we presumably would use 'sdcard' under a directory we
create for e-mail, using an "x-" mime-type we make up. We would manually
handle Blob life-cycle issues by deleting the Blobs when the draft is
either completely purged or the message is completely sent. When
initially generating the mail database, we would trigger a scan of
DeviceStorage to purge any attachments left over from a previous install
of the app. And I guess if the user uninstalls the e-mail app, we just
leave our detritus lying around.
Since the number of drafts is currently unbounded and we will soon
support background mail-sending for e-mail which will then also allow
for unbounded growth in data, DeviceStorage seems like the right place.
Or at least the least-bad place.
Does this sound right?
Andrew
_______________________________________________
dev-b2g mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-b2g