-
Notifications
You must be signed in to change notification settings - Fork 535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Almost any interface change in the Fluid repo results in IFluidObject typing incompatibility #2566
Comments
We chatted about this issue today, and I wanted to jot down some notes. We discussed the approach of removing The bulletproof way to deal with this is to never change any interface. Instead of modifying But this is pretty onerous, so we're hopeful to find a more elegant solution. |
Update to my previous comment - even if we neutralize the type in API signatures, there's still a compile-time trap when a particular bit of code (e.g. a Container specification) imports two different module (e.g. 2 data stores) built/published against different versions of the runtime, with different definitions of I wonder if we can't just put a stake in the ground to say that when authoring a Container all included Data Stores and DDS's must be targeting the same version of the runtime? Is this just kicking the can until we get to dynamic loading? Does it even solve this issue? |
Also, I think this issue would benefit from a concrete repro case and description of what specific errors come up. @leeviana if you can point to a PR or something that fixed this issue before, or any other collateral that would be great. On our side, @anthony-murphy and I discussed just crafting a toy example where some code imports two different modules, each with their own differing definitions of IFluidObject. Then we can not only see the errors but play around with different scenarios/tactics. Speaking of tactics, a few we've discussed:
|
@curtisman, @anthony-murphy - These notes all came from discussions we had, anything else to add or clarify? |
I don't think we have a specific PR because this particular issues prevents us from checking in any code :) I believe I created this issue during one of Kenneth's particularly convoluted FFX bumps where I suggested that in order to reduce regressions/catch them more quickly, we check in the component/container version bump first and then the host version updates second. However, all the contracts around IComponent were broken/unable to be reused around really random things ten layers deep into each interface and ending in something very much unrelated like an interface change in containerRuntime etc. For example, scriptor is both a host and a component. So its component dependencies needed to be updated. However it could not use the IComponent output of the Loader.resolve() because the Loader's version of IComponent was incompatible with the component's version of IComponent because of aforementioned really random changes that had nothing to do with IComponent interfaces that were used. |
You can probably repro this issue quite easily in the bohemia repo by picking any version bump and updating some dependencies in components/containers and not host/Loader code and seeing how it fails. |
Ah of course, that makes sense. Thanks for spelling it out for me :) |
Found an example of 'IFluidDataStoreFactory' being incompatible with 'IFluidDataStoreFactory', where both packages are pulling v0.26.1 from npmjs:
Fixed by casting to 'any' here: export const GraphContainerRuntimeFactory = new ContainerRuntimeFactoryWithDefaultDataStore(
GraphInstantiationFactory.type,
new Map([
GraphInstantiationFactory.registryEntry as any, // <-- Fixed by 'as any'
]),
); |
@DLehenbauer what are the versions of @fluidframework/runtime-definitions in |
Yeah, unfortunately things like this have led to a lot of similar 'any' casting where we test different versions of host/loader etc. :( |
@curtisman - It's '0.26.1' in both cases. I did a recursive diff of all the fluidframework packages like this:
...and they are 100% identical (except for the "_where:" field generated by 'npm i' in package.json... which differs as expected). Seems to be WebPack related ('client' compiles successfully w/tsc.) |
Remove the unused interfaces on FluidObject ISharedString ISharedObject IChannel In addition to being unused these interfaces represent bad practices. A DataStore shouldn't externally expose it's dds for others to access directly. It should instead expose and API and control the data model of the dds. While gernerally unused there is a coupling between our scribe tool and our shared text examples that leverages the ISharedString interface. To remove this interface from IFluidObject, which broadly exposes this bad practice, I've move it to using the request pattern. While still not ideal, this localizes the contract between the two rather than leaking this across the system. Related #3264 Related #2566
This issue has been automatically marked as stale because it has had no activity for 180 days. It will be closed if no further activity occurs within 8 days of this comment. Thank you for your contributions to Fluid Framework! |
This is still an issue, what is the standard here, just to leave a comment to prevent if from being closed? |
Still interested in this but about to go on leave so removing my assignment. |
FYI... We ran into a similar issue with the Bot Framework SDK's. The lesson we learned is that you should always try to favor classes over interfaces as interfaces are essentially immutable and can almost never be updated. The advantage of classes is that you can easily extend them in future releases and provide default behaviors so that you don't break compatibility with previous versions. |
@Stevenic Thanks for this! curious if you had cases where consumer would be the implementor? did you end up going with abstract classes is these cases? |
will be fixed by #7613 |
Describe the bug
Anything that references an IFluidObject type from different versions are pretty much always guaranteed to be typescript incompatible in a "major version" sort of way because of the number of "provides" contracts on IFluidObject . This means we can pretty much never have two different versions of packages on either side of an IFluidObject exchange, regardless of whether you're even using any interfaces that have actually changed. For instance, if somebody makes a random change to IFluidDataStoreContext, through a really deep dependency chain involving views and IHostRuntime, this essentially means a major bump in IFluidObject/core-interfaces.
To Reproduce
Make a change to almost any interface in the Fluid repo. Likely the IFluidObject interface in the version of the code published is not compatible with the version of code right before.
Expected behavior
IFluidObject interfaces should be somewhat durable across Framework changes, especially in interfaces that aren't being immediately used.
The text was updated successfully, but these errors were encountered: