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

Create service specific FluidStatic instances #5815

Closed
wants to merge 9 commits into from

Conversation

sumedhb1995
Copy link
Contributor

The goal of this PR is to allow each service to create its own independent FluidStatic implementation, so that they can each uniquely handle the creation & loading of containers based on the configuration requirements the service needs.

Changes introduced here and the rationale for them are:

  • The IGetContainerService now provides requires callbacks filled out for createContainer and getContainer. This allows the service to provide their own unique implementation instead of forcing them all down the same path. These callbacks take in a new fileConfig parameter which is unique to each service and is responsible for holding the metadata for the actual file backing the Fluid container. For Tiny/Routerlicious, this is the id, whereas for ODSP, this would hold the driveId, siteUrl, and folderName. An example of the OdspService can be found here
  • Update TinyliciousService and RouterliciousService to implement the new interface
  • Replace the singular FluidStatic with FluidStaticTinylicious and FluidStaticRouterlicious. These two are fairly similar, apart from Tinylicious taking in a port number, whereas Routerlicious takes in a config for its init. However, it sets the stage for different services to provide their own FluidStatic implementations, which will have different method signatures for the init, createContainer, and getContainer calls. An example of FluidStaticOdsp can be found here

I've kept these changes together as the reason for updating the IGetContainerServices is so that we can use them to have unique FluidStatic implementations for each service, and this shows how the updated interface would be consumed.

Copy link
Contributor

@skylerjokiel skylerjokiel left a comment

Choose a reason for hiding this comment

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

Overall I like the direction of this. I've left a bunch of high level direction comments that I want to use this PR to bottom out on.

* Singular global instance that lets the developer define all Container interactions with the Tinylicious service
*/
let globalFluidTinylicious: FluidTinyliciousInstance | undefined;
export const FluidTinylicious = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's give thought naming here from both the package and object perspective. We should have a convention across the Services we provide. For packages I want to propose a 1:1 mapping between the service and the import and avoid grouping multiple services in a single package. Even if they share the same driver or have the same api.

package naming

Tinylicious will need both the client and server bits. I did a bit of research and these are the general paradigms.

I'm leaning towards #4.

  1. tinylicious and have both client and server in the package
  2. tinylicious-client and tinylicious
  3. tinylicious-client and tinylicious-server
  4. 1 & 3 - support both where tinylicious is a re-export of the other two for simplicity

import naming

For the naming nothing is really jumping out. I think I like #2 but am open to more ideas

import { FluidTinylicious } from "tinylicious-client";
import Tinylicious from "tinylicious-client";
import { Fluid } from "tinylicious-client";

Copy link
Contributor

Choose a reason for hiding this comment

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

let's rename get-container to match what we choose above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm working on creating a draft to show how FluidStaticTinylicious and TinyliciousService can be taken out of their existing locations in fluid-static and get-container respectively to be moved to a separate "tinylicious-client" package
However, we may want to stage those changes in two parts, the first where we add in the elements to the existing packages and then where we take them out into its own individual package

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've created the draft PR with the changes to separate out tinylicious-client into its own package here: #5838
It doesn't remove get-container entirely but takes out tinyliciousService from it and move it into the new tinylicious-client package, which also hosts FluidTinylicious.
I was looking into re-exporting out the actual Tinylicious BE server package itself from the same package as well but, as it stands, that package doesn't provide a export yet so I believe that would need to be added first followed by the re-export

@@ -15,6 +13,14 @@ import {
export interface IGetContainerService {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this interface is needed if we consolidate packages.

/**
* FluidTinyliciousInstance provides the ability to have a Fluid object backed by a Tinylicious service
*/
export class FluidTinyliciousInstance {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need two packages here. It should just be one client package for the tinylicious client bits named how we choose. We can then consolidate the logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Consolidated logic into @fluid-experimental/tinylicious-client package here #5838

import { getContainer, IGetContainerService } from "./getContainer";

export interface ITinyliciousFileConfig {
Copy link
Contributor

Choose a reason for hiding this comment

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

I really don't like File here.

So the idea is that we have two configs. Once defines the service specific container properties. The other defines the container itself.

Maybe serviceConfig and objectConfig ? or serviceConfig and schemaConfig?

Also we might want to separate create and get? maybe... That would mess with the generic 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.

Updated to be serviceConfig & objectConfig.
As for separation of create & get, OdspService actually expects two different interfaces for each respectively, where the create takes additional file metadata such as the its drive info and folder name but the get requires the URL to the file. It just so happens that the serviceConfig for Tinylicious is the same for both cases

import Fluid from "@fluid-experimental/fluid-static";
import { TinyliciousService } from "@fluid-experimental/get-container";
import { FluidTinylicious } from "@fluid-experimental/fluid-static";
import { ITinyliciousFileConfig } from "@fluid-experimental/get-container";
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be coming from the same package as the Tinylicious client bits. Let's consolidate the two packages. More comments below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

external-controller only requires an import from @fluid-experimental/tinylicious-client in the follow-up #5838

import { SharedMap } from "@fluidframework/map";
import { DiceRollerController } from "./controller";
import { renderDiceRoller } from "./view";

// Define the server we will be using and initialize Fluid
const service = new TinyliciousService();
Fluid.init(service);
FluidTinylicious.init();
Copy link
Contributor

Choose a reason for hiding this comment

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

If we keep the init I see three configs.

  1. Service specific properties that apply across the application (ex. FRS endpoint, tokens)
  2. Container specific properties that are required for the service (ex. ID)
  3. Container specific properties that define the data schema

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct. There is an initial config to set up the service itself. Then there are two more for the container, one which is service-specific and the other defining the objects within the container

@sumedhb1995
Copy link
Contributor Author

sumedhb1995 commented Apr 16, 2021

@skylerjokiel I've updated this PR to take in the recommended changes to FluidTinylicious and the config naming. All of the changes here are still in the existing packages of get-container and fluid-static.

I agree with the idea of moving the service-specific logic that is spread across those two packages into one. To address that, I've created this follow-up draft PR to show how we could create a "tinylicious-client" package, with default export FluidTinylicious, allowing developers to only require importing from one package per service https://github.com/microsoft/FluidFramework/pull/5838/files

Since creating the new packages results in a number of other changes to set the new package up, update dependencies, etc., I've kept the two separate but please let me know if you'd like me to merge it in here

@skylerjokiel
Copy link
Contributor

I think #5383 replaces this PR. If so can you close this.

@sumedhb1995
Copy link
Contributor Author

Closing this as we have moved to implementing separate client packages for each service with #5383

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants