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

Handling of the MIP labels update from JoinSession and Fluid Signals from push and exposing them on container #19142

Merged
merged 18 commits into from
Jan 11, 2024

Conversation

jatgarg
Copy link
Contributor

@jatgarg jatgarg commented Jan 8, 2024

Description

ADO Task Link: https://dev.azure.com/fluidframework/internal/_workitems/edit/6640
Handling of the MIP labels update from JoinSession and Fluid Signals from push and exposing them on container so that the apps can listen to the updates and take appropriate action like update their UX etc.

The details about the server side changes etc. are included in the design document.

1.) Add event " metadataUpdate " in IDocumentServiceEvents which are emitted on IDocumentService.
export interface IDocumentServiceEvents extends IEvent {
/

  • This event is used to communicate any metadata related to the container. We might have received metadata from the service.
  • Read more info on this event from here IContainer.containerMetadata.
    /
    (event: "metadataUpdate", listener: (metadata: Record<string, string>) => void);
    }
    *

2.) DeltaConnection will extract the labels from the join session response and will also extract it from the fluid signals in the driver layer and whenever it is updated by either path, it will tell IDocumentService to emit the metadataUpdate event on the service object.

3.) Container will listen to this event and then it will emit this info on itself. For that we will add the same event in IContainerEvents.
export interface IContainerEvents extends IEvent {
/

  • Emitted when the some of the properties related to the container are initialized or updated.
  • This emitted metadata will the props which are updated. If consumer wants to read full set of metadata then they can read it off the container from {@link IContainer.containerMetadata} prop.
    /
    (event: " metadataUpdate ", listener: (metadata: Record<string, string>) => void);
    }
    *
    Also expose containerMetadata: Record<string, string> on IContainer, so that it can read at any time.

We are adding this prop on the container as user should be able to read it on load also, besides getting any update through events when the update happens. The emitted event will only have the props which are updated while the contianerMetadata will have full set of props.

5.) Apps can listen to this event to get the latest policy labels. Apps can also read this on load from the container object once the container is connected. It will be exposed like this on the event or in containerMetadata.

Container.containerMetadata = { sensitivityLabelsInfo: value(string)}

Value will be jsonified string. So, app needs to parse it and it will contain same structure as we received from the service which is:

{ labels: Object, timestamp: string } where labels is of structure:

[
{
"sensitivityLabelId": string,
"tenantId": string,
"assignmentMethod": string,
}
]

@jatgarg jatgarg self-assigned this Jan 8, 2024
@jatgarg jatgarg requested review from msfluid-bot and a team as code owners January 8, 2024 03:37
@jatgarg jatgarg marked this pull request as draft January 8, 2024 03:37
@github-actions github-actions bot added area: driver Driver related issues area: loader Loader related issues area: odsp-driver area: runtime Runtime related issues dependencies Pull requests that update a dependency file public api change Changes to a public API base: main PRs targeted against main branch labels Jan 8, 2024
@github-actions github-actions bot removed the dependencies Pull requests that update a dependency file label Jan 8, 2024
@msfluid-bot
Copy link
Collaborator

msfluid-bot commented Jan 8, 2024

@fluid-example/bundle-size-tests: +1.64 KB
Metric NameBaseline SizeCompare SizeSize Diff
aqueduct.js 505.26 KB 505.31 KB +44 Bytes
connectionState.js 680 Bytes 680 Bytes No change
containerRuntime.js 240.76 KB 240.79 KB +22 Bytes
loader.js 166.08 KB 166.58 KB +516 Bytes
map.js 46.62 KB 46.63 KB +11 Bytes
matrix.js 145.05 KB 145.07 KB +11 Bytes
odspDriver.js 89.31 KB 95.7 KB +6.39 KB
odspPrefetchSnapshot.js 41.58 KB 41.61 KB +22 Bytes
sharedString.js 163.94 KB 163.95 KB +11 Bytes
sharedTree.js 293.74 KB 293.74 KB No change
Total Size 1.8 MB 1.8 MB +1.64 KB

Baseline commit: 084ced9

Generated by 🚫 dangerJS against fe8d67c

@github-actions github-actions bot added the area: tests Tests to add, test infrastructure improvements, etc label Jan 9, 2024
@jatgarg jatgarg requested a review from vladsud January 9, 2024 19:13
/**
* Emitted when the some of the properties related to the container are initialized or updated.
*/
(event: "metadataUpdate", listener: (metadata?: Record<string, unknown> | undefined) => void);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can it be undefined? I'd rather see {} used in such case (if it implies - all properties are empty), not undefined.
Please add comments about semantics how it should be interpreted by consumer. I see two ways:

  1. Merging properties / communicates only what changed: If some property is missing on this payload, but existed before (in containerMetadata state below), then it did not change and stays the same. If property needs to be deleted, it's value will be set to undefined in metadata value on this event.
  2. Overwrite: If some property is missing in metadata, it means it is removed from set.

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 join session will always return the labels and not just the updates even if they are empty. So as far as labels is concerned, we will have the state always. I want to go with this semantic for these updates as you previously mentioned:

Merging properties / communicates only what changed: If some property is missing on this payload, but existed before (in containerMetadata state below), then it did not change and stays the same. If property needs to be deleted, it's value will be set to undefined in metadata value on this event.

As then the update provider does not need to bother about all props and even container can itself add props to the metadata as the service might not know all the props, so complete overwrite semantics does not work. If someone wants to reset a prop, then they need to provide that in update otherwise it will remain same.

@@ -1546,6 +1559,22 @@ export class Container
this._deltaManager.connect(args);
}

private readonly metadataUpdateHandler = (metadata?: Record<string, unknown> | undefined) => {
this._containerMetadata = { ...this._containerMetadata, ...metadata };
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks fishy (in terms of merging old & new).
Assuming that we get data only through joinSession, I see not much difference between first call and second call to joinSession. I'd assume that it returns full set of properties (not just update from previous state), as otherwise we will not have full info (ever) - we have no initial state.
And if it's full set, then property missing in second update should be - it's gone. But if we merge like that, it will stay around.
Let's clarify (through comments and code actions) semantics of these updates.

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 join session will always return the labels and not just the updates even if they are empty. So as far as labels is concerned, we will have the state always. I want to go with this semantic for these updates as you previously mentioned:

Merging properties / communicates only what changed: If some property is missing on this payload, but existed before (in containerMetadata state below), then it did not change and stays the same. If property needs to be deleted, it's value will be set to undefined in metadata value on this event.

As then the update provider does not need to bother about all props and even container can itself add props to the metadata as the service might not know all the props, so complete overwrite semantics does not work. If someone wants to reset a prop, then they need to provide that in update otherwise it will remain same.

@@ -14,6 +14,12 @@ export class DocumentServiceCompressionAdapter extends DocumentServiceProxy {
private readonly _config: ICompressionStorageConfig,
) {
super(service);
// Back-compat Old driver
Copy link
Contributor

Choose a reason for hiding this comment

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

any other adapters that we should care about?
How do we ensure we do not miss any (and have no events flowing)?
It's probably fine, but I wonder, should loader be able to verify that driver is of same or higher version, and if so - assert that ability to subscribe to events is provided? It's rather weak check, and a bit ugly, so not sure if we want to go that route..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does not seem like we have more adapters as the compilation would have failed, I also scanned the code a bit.
I don't want to compare package version, as their format also keeps changing. We could also check that
if (service instanceOf EventEmiter), then listen to event. OR
we could expose some prop on IDocumentServicePolicies and check that and then subscribe to event.

Copy link
Contributor

@vladsud vladsud left a comment

Choose a reason for hiding this comment

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

Please take a look at semantics of updates and how we merge properties. Otherwise looks great!

@jatgarg jatgarg marked this pull request as ready for review January 10, 2024 19:33
@jatgarg jatgarg requested review from a team as code owners January 10, 2024 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: driver Driver related issues area: loader Loader related issues area: odsp-driver area: runtime Runtime related issues area: tests Tests to add, test infrastructure improvements, etc base: main PRs targeted against main branch public api change Changes to a public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants