Skip to content
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

feat(migration-tools): Include Migrator in container code, make it single use, use callbacks instead of taking a full loader #23274

Merged
merged 58 commits into from
Dec 12, 2024

Conversation

ChumpChief
Copy link
Contributor

@ChumpChief ChumpChief commented Dec 10, 2024

This change centers around moving the Migrator into the container code (whereas today it's expected that the host will bring it and pair it with the migration tool inside the container). This minimizes expectations on the host, who now just needs to provide callbacks to (1) load a copy of the source container for export and (2) do whatever they like with the exported data. With these scoped callbacks, the general result is that both the container code and host get relaxed requirements and more flexibility.

With these scoped callbacks, there doesn't need to be any agreement on loader shape (and so SimpleLoader goes away). They can also be less opinionated on the "future" container, e.g. it'd theoretically be possible to use this even across incompatible breaking changes to the loader layer.

We can also lift the requirement of a specific IMigratableModel-based implementation, as now it's just the container code author communicating with themselves rather than communicating with a part brought by the host. So now the container code author can use any technique they like for exporting data. The IMigratableModel interface is still there (moved to the example package) in this PR but could probably be stripped down a good bit for simplicity.

Since Migrator is now inside the container code, it drops its "load the new container automatically" responsibility, which is left instead for the host to do. Migrator is now single-use similar to MigrationTool, bound to the source container. We can also hide MigrationTool completely and just provide the IMigrator to the container code author directly.

This also removes TaskManager usage from MigrationTool. It could still be used to minimize duplication, but it'd impose additional responsibilities on the host to handle abort signals and restarting their flows. Since we need a container deduping strategy anyway, I figured it's OK to remove for now. We can consider adding it back if we find it necessary.

AB#25114

@github-actions github-actions bot added area: examples Changes that focus on our examples dependencies Pull requests that update a dependency file public api change Changes to a public API base: main PRs targeted against main branch labels Dec 10, 2024
@@ -23,23 +20,15 @@ export class InventoryListAppModel implements IInventoryListAppModel, IMigratabl
// To be used by the consumer of the model to pair with an appropriate view.
public readonly version = "one";

public constructor(
public readonly inventoryList: IInventoryList,
private readonly container: IContainer,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Migrator gets the container back directly from the LoadSourceContainerCallback and can dispose() it directly, the model doesn't need to hold the reference.


const exportDataCallback = async (container: IContainer): Promise<unknown> => {
// TODO: verify IMigratableModel
const exportModel = await getModelFromContainer<IMigratableModel>(container);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the container code provides the ExportDataCallback itself, the model doesn't need to necessarily conform to any specific interface like IMigratableModel, the container code author can grab the data however they like.

Comment on lines +15 to 20
import type { IContainer } from "@fluidframework/container-definitions/internal";
import {
type ILoaderProps,
loadExistingContainer,
} from "@fluidframework/container-loader/internal";
import { RouterliciousDocumentServiceFactory } from "@fluidframework/routerlicious-driver/internal";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid /internal imports in here? (Examples should not use /internal APIs.)
Perhaps update .eslintrc.cjs to have:

		"import/no-internal-modules": [
			"error",
			{
				allow: [
					// Within Fluid Framework allow import of '/alpha' from other FF packages.
					"@fluidframework/*/alpha",

or similar

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, in general our in-repo examples do use /internal - I can give it a shot for some of these though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem seems to be that I need the full exception list to concatenate (otherwise this simply overrides the existing exception list) and everything blows up. I could duplicate that exception list here but that has its own drawbacks.

Might be good to consider a centralized override for examples I suppose

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should probably have an examples config (aka external to platform config). I don't know how composable configs are. I do know that merging settings isn't supported like we'd want for this rule.

),
codeLoader: new DemoCodeLoader(),
generateCreateNewRequest: createTinyliciousCreateNewRequest,
export const setupContainer = async (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: prefer named function (export async function setupContainer()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that? I usually prefer arrow unless I explicitly want this binding.

Copy link
Contributor

@scottn12 scottn12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking pretty good! I mostly left some questions and small nits for now. Love all the deleted code 😋

@ChumpChief ChumpChief enabled auto-merge (squash) December 11, 2024 23:15
Copy link
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output


> fluid-framework-docs-site@0.0.0 ci:check-links /home/runner/work/FluidFramework/FluidFramework/docs
> start-server-and-test "npm run serve -- --no-open" 3000 check-links

1: starting server using command "npm run serve -- --no-open"
and when url "[ 'http://127.0.0.1:3000' ]" is responding with HTTP status code 200
running tests using command "npm run check-links"


> fluid-framework-docs-site@0.0.0 serve
> docusaurus serve --no-open

[SUCCESS] Serving "build" directory at: http://localhost:3000/

> fluid-framework-docs-site@0.0.0 check-links
> linkcheck http://localhost:3000 --skip-file skipped-urls.txt

Crawling...

Stats:
  170098 links
    1596 destination URLs
    1825 URLs ignored
       0 warnings
       0 errors


@ChumpChief ChumpChief merged commit 94d7f5e into microsoft:main Dec 12, 2024
30 checks passed
@ChumpChief ChumpChief deleted the MigratorInEntryPoint branch December 12, 2024 01:45
Josmithr pushed a commit to Josmithr/FluidFramework that referenced this pull request Dec 12, 2024
…ngle use, use callbacks instead of taking a full loader (microsoft#23274)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: examples Changes that focus on our examples base: main PRs targeted against main branch dependencies Pull requests that update a dependency file public api change Changes to a public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants