So this is more complex as initially thought given that multiple protocols have to be supported with the underlying object cache implementation, whereby each has its own framework. Work that I have to do now should as best work in all of them, and not cause any major refactoring in a quarter time span. So lets see what needs to be done...
The object cache is a storage for complex objects that cannot be serialized (JSON) as value and as such not directly transmitted via any of the protocols (Marionette, BiDi, CDP) to the client. As such a strong reference to the object is put into a Map that is keyed by a uuid. This uuid can later be used to uniquely identify the object again and use it for further operations. Given that these objects cannot even be transmitted between different Firefox processes each process requires it's own cache. That also implies that once a content process is gone, all the cached data is gone too.
The objects as cached should hereby only be accessible with a specific session id, which is set by the individual protocol that creates the session. Marionette and WebDriver BiDi share the same session, whereby CDP uses it's own mechanism and has different sessions, each for a given tab. To make the cache shareable our CDP implementation would require this session id. We could consider adding a custom CDP command which can be used by a client to set the BiDi session id, and then share it across CDP sessions (tabs) and modules.
Note: Even with Marionette not requiring such an object cache it's needed because element references also have to be stored in the same cache. This is because in CDP
evalute is used to retrieve DOM nodes, which are then stored inside the cache.
Beside the session id the object cache also has to be tight to a specific window global (browsing context). Trying to access objects as created for other window globals has to be restricted. In Marionette the ContentDOMReference module is used for that. It uses a global singleton to store the DOM node (only) references with an elements uuid and browsing context as key. But currently Marionette has its element store located in the parent process which makes it harder to share with BiDi and CDP. :(
Given the complexity of these three protocols and their completely different implementations (whereby Marionette is way close given that it uses JSWindowActors) makes it hard to properly forecast what's best to use. But here a proposal:
We create a fork of ContentDOMReference that is able to not only handle DOM nodes but also any kind of object. It still uses a
uuid, the browsing context id, and the WebDriver session id as key to reference an object in that cache. All these parts of the key will be known when a command is run in any of the protocols. Further each object cache singleton is bound to a given Firefox (content) process and will be wiped away once the process is gone. No additional clean-up would be necessary.
With BiDi enabled the WindowGlobalMessageHandler class is responsible to load that ContentObjectReference module which will automatically create a global singleton when loaded the very first time for a process. The global window message handler class will get a shortcut method to easily access data via the current session id and browsing context.
2.a) Marionette should also use this forked ContentObjectReference module so that the object cache can be moved back into the appropriate process. This will also work if BiDi is not enabled. Work here is not immediately necessary and can be post-poned until we have the need to handle element references in BiDi in combination with Marionette.
2.b) CDP would have to be updated so it knows about the WebDriver session id. The amount of work here is hard to estimate and should be post-poned for now until we get feedback from the Puppeteer team how their transition strategy looks like.
Connect the object cache with the
Serialize to Remove Value code in BiDi so that serialization steps can check for already known objects and return their uuid instead of always creating a new one. For now session id and browsing context id have to be passed in.
(LATER) Once CDP and Marionette are no longer existent remove the global object cache singleton and allow the window global message handler to hold an instance of the object cache. At this point the key would just become the single
I hope that I covered everything and was able to frame it correctly so it's understandable. At least with Julian I already discussed that but I hope to also get some further feedback from both Julian and James before I'll start the implementation.