FluidFramework icon indicating copy to clipboard operation
FluidFramework copied to clipboard

DDS Migration Shim

Open CraigMacomber opened this issue 9 months ago • 1 comments

Description

Proof of concept Work in Progress.

Introduce "SharedObjectKernel" and "SharedKernelFactory" abstraction as internal types to use to build SharedObjects.

These abstractions separate the DDS specific policy logic from the state and actual SharedObject instance, as well as avoid using subclassesing as an API to reduce coupling.

For compatibility with the existing runtime logic using SharedObjects, a generic SharedObjectFromKernelFull implementation is included which wraps the kernel based policies, though the API to use it is just the makeSharedObjectKind function, avoiding leaking the class even as an internal API.

SharedObjectFromKernelFull uses a proxy to graft the user facing API surface onto the same object that the runtime talks to (which provides op application and such). Ideally these would remain separate objects to avoid exposing the APIs the runtime uses to customers. If all DDSs used this implementation, modifying the runtime to provide this separation would be practical (user facing API could be behind a property on the SharedObject of the runtime facing one could be behind a symbol or map from the user facing one)

This approach is intended to be as similar as possible the migration adapter will have a single shared object that can delegate to a kernel which gets replaces when the migration occurs.

Breaking Changes

This POC currently breaks some legacy APIs and tests.

Reviewer Guidance

The review process is outlined on this wiki page.

This code is not ready for review, however feedback on the high level approach of using kernels and the use of the proxy would be helpful.

It's possible to avoid the proxy leaving several options for how to setup the APIs:

  1. Manually subclass and forward all the APIs to the view/adapter for each shared object kind.
  2. Generate inherited (or own) getters to put on the SharedObject's prototype which forward to each property (inherited or own) on the adapter. Possibly include a way to filter these.
  3. Use a proxy (what the current code does)
  4. Modify the runtime/shared object API so that the user facing object (what you get from create and handle.get can be a separate object provided by the shared object (ex: from a property). Existing SharedObjects can just return this to avoid any behavioral changes for now.

Option 4 seems like the best choice: feedback on if that is practical and how to do it would be useful.

CraigMacomber avatar Jan 31 '25 19:01 CraigMacomber