Open Bug 1400298 Opened 7 years ago Updated 2 years ago

Make Cache API body streams cloneable

Categories

(Core :: Storage: Cache API, enhancement, P2)

57 Branch
enhancement

Tracking

()

Tracking Status
firefox57 --- affected

People

(Reporter: bkelly, Unassigned)

References

(Blocks 2 open bugs)

Details

Response objects created by Cache API contain body streams defined by the dom::cache::ReadStream class (not to be confused with ReadableStream).  The streams wrap an underlying file stream and snappy decompression stream.  Currently they are not cloneable via nsICloneableInputStream because nsFileInputStream cannot be directly cloned itself.

With the changes in bug 1397128, however, we now open the underlying file stream lazily.  Most of the time the Cache API body stream will not even have an inner file stream.

This means we can now make Cache API body streams implement nsICloneableInputStream.  The Clone() would simply involve minting a new stream object with the same body ID, but no file stream.  If the clone is ever read it will lazy open the stream.  The new stream would also have to register itself with the CacheStreamControlChild in order to receive close messages and to hold the body file alive in the parent.

Implementing this would make Cache API Response.clone() operations much cheaper.  Today these clones trigger a pipe creation and off-thread copying into the pipe from the file immediately.  If the Response is never consumed (which happens often) then this is wasted work.
Priority: -- → P2
We could do something similar to what I have implemented for IPCBlobInputStream: nsFileStreams are kept alive (without opening a FileDescriptor) on the parent process. On the content process a nsIAsyncInputStream is exposed. When AsyncWait() is called, the parent process clones the FileStream and sends it to the content side. More documentation can be read here: https://dxr.mozilla.org/mozilla-central/source/dom/file/ipc/IPCBlobUtils.h#12 . IPCBlobInputStream is cloneable and easily IPC-serializable without having pipes involved.

Maybe we can just generalize IPCBlob and make it usable by other components.
While there is overlap, I don't think we want to use the IPCBlob code here.  Cache API has its own actor system for tracking the stream which I implemented a couple years ago.  I added the lazy open strategy on top of this actor last week in bug 1397128.

All that needs to be done in this bug is:

1. Make Cache::ReadStream implement nsICloneableInputStream
2. Make Clone() create a new Cache::ReadStream with its body ID set, but no mStream/mSnappyStream.
3. Tell the CacheStreamControlChild about the new stream.

Trying to replace StreamControl actor here with IPCBlob would probably be a lot of work since it ties into the parent-side Manager/Context life cycle.
Component: DOM → DOM: Core & HTML
Component: DOM: Core & HTML → Storage: Cache API
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.