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

FDC3 for Web Browsers Discussion group 18th July 2024 #1267

Closed
11 of 17 tasks
kriswest opened this issue Jul 17, 2024 · 21 comments
Closed
11 of 17 tasks

FDC3 for Web Browsers Discussion group 18th July 2024 #1267

kriswest opened this issue Jul 17, 2024 · 21 comments
Labels

Comments

@kriswest
Copy link
Contributor

kriswest commented Jul 17, 2024

Group overview

Group convened to discuss how to enable FDC3 use in a web browser, without the use of a browser extension (such as fdc3-desktop-agent or a container).

Issue: #896
Mailing list discussion: https://groups.google.com/a/finos.org/g/fdc3/c/jCvlLjokBLs

In a recent email on the FDC3 mailing list, @kriswest wrote:

... I also want to add that there is clearly significant interest in the community in enabling FDC3 use on the web. There is a strong use case in that it would enable better onboarding journeys with less drop-off (where you use an app on the web with others before adopting a desktop container or similar).

and:

But there are also additional challenges such as how to make the API available reliably without importing a proprietary module from a particular vendor into every app, how to deal with more than one implementation of API/Desktop Agent in the browser at once, how to do this reliably and securely within the browser sandbox etc.. Work needs to be done in the Standard to solve these issues and to make web browser use possible in a future FDC3 Standard version - which I believe is possible (and likely to involve using a vendor-agnostic FDC3 NPM module to detect and connect to API implementation(s)). However, we're going to need to do that work to enable the aforementioned API implementations to be compliant and if we fail to hold the line now on compliance with the current version of the FDC3 Standard, that may never happen.

Shared doc with current draft: https://tick42-my.sharepoint.com/:w:/g/personal/finsemble_datastore_interop_io/EZ0dfTCdRlJCnIF3C_1Oit0BF3fsXyvlMbisXp722DC9Kg?e=H2y7fn

Relevant issue tags

Current open issues that relate to the above concepts with the label:
image

Meeting Date

Thursday 18 July 2024 - 11am (US eastern timezone EST) / 4pm (London, BST)

Zoom info

  • Join Zoom Meeting
  • Meeting ID: 969 4029 4948
  • Passcode: 636931
  • Dial-in:
    Country International Dial-in Toll-free Dial-in
    US +1 929 205 6099 (New York) 877 853 5247
    UK +44 330 088 5830 0800 031 5717
    France +33 1 8699 5831 0 800 940 415
    Find your local number https://zoom.us/u/ad2WVnBzb8

Meeting notices

  • FINOS Project leads are responsible for observing the FINOS guidelines for running project meetings. Project maintainers can find additional resources in the FINOS Maintainers Cheatsheet.

  • All participants in FINOS project meetings are subject to the LF Antitrust Policy, the FINOS Community Code of Conduct and all other FINOS policies.

  • FINOS meetings involve participation by industry competitors, and it is the intention of FINOS and the Linux Foundation to conduct all of its activities in accordance with applicable antitrust and competition laws. It is therefore extremely important that attendees adhere to meeting agendas, and be aware of, and not participate in, any activities that are prohibited under applicable US state, federal or foreign antitrust and competition laws. Please contact [email protected] with any questions.

  • FINOS project meetings may be recorded for use solely by the FINOS team for administration purposes. In very limited instances, and with explicit approval, recordings may be made more widely available.

  • A Discussion Group has no direct decision-making power regarding the FDC3 standard - rather it is intended that anything they propose or work on will result in proposals (via Github issues and PRs) for the Standards Working Group participants to consider and vote on for inclusion in the standard.

Participation Requirements

Note: Meeting participants are expected to accept the terms of the FDC3 license (Community Specification License), understand the governance process and have a CLA in place.

Please click the following links at the start of the meeting if you have not done so previously.

Tracking Attendance

Note: Meeting participants are expected to add a comment to this GitHub issue in order that we can track attendance of FDC3 project meetings. Please do this at the start of the meeting.

Agenda

Minutes

  • Enhancements to messages defined in BrowserTypes #1268
    • @Roaders introduced the issue which suggests that we provide type that is a union of all messages and a set of type predicates that can differentiate the different messages
    • @kriswest provided some detail on the code generation from schemas used to generate BrowserTypes.ts, the base message types which are structurally compatible with all derived message types and generated enumerations of the message type values.
      • @kriswest to deal with type generation script generating a commandline command that is too long.
      • @Roaders to explore generating type predicates automatically etc. using TSMorph
    • @openfin-johans requested clarification on whether any of the proposed changes are breaking or would be required for confromance with FDC3 (for an existing container product, rather than a browser-absed product)
  • Support for Multiple Application Scopes (Agents) within a single window process #1250
    • @kriswest provided an introduction to the Multiple app scopes in one window issue (Micro-frontend Containers) and the existing proposal to resolve it, which is based on the same techniques as the main FDC3 for Web Browsers proposal (passing some Id details)
      • non-breaking, but may be an additional requirement for containers to implement in 2.2
      • @Lecss asked if a parent-child relationship is implied by the name of the proposed function getSubAgent, which mirrors getAgent used in the main proposal.
        • @kriswest answered that to a certain extent that is true as you need to establish an FDC3 connection/API instance for the window first (fdc3) and then use that to retrieve a sub-agent
          const anotherFdc3 = await fdc3.getSubAgent(...) however once retrieved there is no implied functional link between them (in a browser it would likely communicate with the same 'parent' as the window-level agent, while container implementations can implement however they prefer.
    • Tear down patterns (Question: Disposal/Teardown patterns in FDC3 #1263)
      • @Davidhanson90 introduced this additional issue - cleaning up FDC3 connections when a widget or window has gone away
      • @kriswest explained how this is handled in containers at the window level - they are able to track and observe the status of windows and clean-up automatically on close, hence, FDC3 currently contians very little in this area. Thought on this topic will be more necessary in web-based agents as the HTML Standard APIs do not provide an event (As far as we know) that you can listen to to catch the window closing - we believe the best you can do is poll a particular value on a MessagePort that tells you if the other end is still active...
      • With sub-agents something explicit would also be needed (as the scope/DOM may remain without the widget). In both cases, widgets or apps that have closed need to be cleaned up or they will turn up in intent resolvers and APIs that return instance details such as findIntent and findInstances
      • @robmoffat said he was using websockets in the POC and could detect when these went away - but this is not relevant to the MessagePorts approach used to interface with frames/windows proposed for standardisation.
      • @novavi mentioned finalisation registries in javascript as perhaps relevant to this problem
      • @robmoffat took an action item to look at cleaning up resources for windows and iframes that have gone away under the main proposal.
      • @Davidhanson90 took an action item to look into the issue with tear-down of subagents.
      • @kriswest summarized the fact that there are two separate proposals for the group to be raised to the SWG for consideration: FDC3 for Web and SubAgents and there was consensus that they could / should be raised separately and may end up in different FDC3 versions. The group has a goal of trying to get the first proposal raised an adopted in time for OSFF 24 in NY.
  • @robmoffat's questions about the GetAgentParams
    • @robmoffat @kriswest and @novavi provided details of some discussion they'd had since the last meeting about the arguments to the getAgent function and deviations from them in the POC work.
    • Identity of apps: As proposed apps would point to a appD record providing their identity and metadata via a fully0qualified appId or appDUrl
      • @robmoffat Proposed to switch to sending the app's URL instead, which the DA would then need to look up in its own DA.
        • @kriswest gave an overview of how appD's have been used (hosted by adoptors putting apps into their own desktops) vs. how they were intended (to be published by vendors and then linked to by adoptors) - and how they were proposed for use in FDC3 for the Web: apps provide details of a record that their identity would be validated against (by comparing message origin to allowed origins in the appD record) - optional for DAs to compare to their own records. Essentially relying on the DNS system to validate app identity via domain ownership.
        • It is further proposed that deeper identity validation is adopted later, based on recommendations of the Identity & Security group, which is likely to propose the addition of asymmetric encryption keys (public key) to appD records for other purposes and could be used to create a cryptographic identity validation system (which would be easier to apply to other languages in which FDC3 maybe implemented). Hence, we do want appD records involved in identity validation.
        • We also propose to support use cases where users independently enter URLs in a browsers - which might result in an an FDC3 enabled app being present that the DA is not aware of in advance - if the app identifies an appD record its possible to know something about it... This is supported by the 'failover' function specified in getAgent.
          • This was not explicitly decided in the meeting - but there was consensus that we should switch to using the URL for identity with the DA looking up the record, which implies that the DA must know about the application in advance.
        • @Roaders asked whether URL validation would include the has and search parameters... These can make the URL represent a different logical application.
          • Others had assumed that these would be ignored, but there was consensus that this would not work in all cases. There were also concerns that it would be hard to identify what parameters matters and what did not.
          • @kriswest proposed that what is in the appD record could decide what is required. If the appD record contains only the origin and path then the search and hash are ignored in the comparison. If either parameters or a hash are present then they must be present in the URL being validated to match. The JavaScript URL class can be used to implement the comparison easily enough based on its parsing of URLs. There was consensus that this would work.
            • It was agreed to defer to later any additions to the appD record for multiple possible app URLs (different environments or deployments) - this would be a premature optimisation.
            • It was further clarified that connection to an appD by a DA is recommend but not required. Hence, DAs that don't use an appD will need to have an equivalent form of configuration that they can compare to.
          • @kriswest to update the proposal doc and PR to base identity arguments on URLs as described, with responsibility for the DA to look up the appD record (or equivalent config).
      • There was consensus that we can switch the proposal to use URLs for identity management
        • @robmoffat to update the POC to work on URLs for identity - if not specified the current window.location.href should be used by default

Action Items

  • @kriswest to deal with type generation script generating a command line command that is too long
  • @Roaders to explore generating type predicates automatically etc. using TSMorph
  • @robmoffat to look at cleaning up resources for windows and iframes that have gone away under the main proposal.
  • @Davidhanson90 to look into tear-down patterns for subagents.
  • @kriswest to update the proposal doc and PR to base identity arguments on URLs as described with a defined comparison procedure.
  • @robmoffat to update the POC to work on URLs for identity - if not specified the current window.location.href should be used by default, and window.location.href should always have a matching origin to the specified URL.

Rolled over and/or still in progress:

  • @kriswest to apply changes to deal with as many of the comments on the docs PR (FDC3 for Web specification #1191) as possible.
  • @kriswest to ensure that a README and screencast video is provided on maintaining schemas and code generation.
  • @robmoffat to seek out and recruit other potential POC collaborators
  • @robmoffat to continue work on getting the conformance framework to run over the POC codebase and to connect with @kriswest to confirm race conditions and resolutions needed in the framework.

Untracked attendees

Full name Affiliation GitHub username
@kriswest kriswest added help wanted Extra attention is needed meeting labels Jul 17, 2024
@kriswest kriswest changed the title <topic> Discussion group FDC3 for Web Browsers Discussion group 17th July 2024 Jul 17, 2024
@Roaders
Copy link
Contributor

Roaders commented Jul 17, 2024

Giles Roadnight / Morgan Stanley

@robmoffat robmoffat changed the title FDC3 for Web Browsers Discussion group 17th July 2024 FDC3 for Web Browsers Discussion group 18th July 2024 Jul 18, 2024
@robmoffat
Copy link
Member

Rob Moffat / FINOS 💯

@paulgoldsmith
Copy link

Paul Goldsmith / Morgan Stanley

@kriswest
Copy link
Contributor Author

Kris West / interop.io 🚀

@novavi
Copy link

novavi commented Jul 18, 2024

Derek Novavi / S&P Global

@Davidhanson90
Copy link

David Hanson / Morgan Stanley

@openfin-johans
Copy link
Contributor

Johan Sandersson / Here (formerly OpenFin) 🎁

@pvoznyuk
Copy link

Pavlo Vozniuk @ RBC CM

@Lecss
Copy link

Lecss commented Jul 18, 2024

Alex Dumitru / Citi

@robmoffat
Copy link
Member

There wasn't time for discussion of this in the meeting:

Please jump on the comments and make your thoughts known!

@kriswest
Copy link
Contributor Author

@Roaders @Davidhanson90 @robmoffat @Lecss I've just noticed that the messages are missing the new addEventListener API call that was added to 2.2 in issue #1136. I've added that to the set in 77f0023

@Roaders
Copy link
Contributor

Roaders commented Jul 30, 2024

thanks for the heads up

@kriswest
Copy link
Contributor Author

@Roaders @Davidhanson90 @robmoffat @Lecss @novavi
@robmoffat pointed out an interesting issue with addContextListener and joinChannel. In the Desktop Agent API. Some background:

(User Channels) When you add a context listener and are already joined to a channel, or when you've added a context listener and then join a channel/switch channel you immediately receive the current context of that channel (this is important as the user can often change the channel with a channel selector, the app is not necessarily involved in that change and needs to be given the new context automatically).

(App Channels) This differs from the Channel API where you retrieve a channel object (fdc3.getOrCreateChannel) then add a context listener to it - you do NOT receive any automatic copies of the current context - instead you may call channel.getCurrentContext to manually retrieve it.

For the former case, I had been thinking that the Desktop Agent needs to send you a BroadcastEvent to give you the context for the newly added listener or newly joined channel - but that won't work as you can add multiple listeners to a channel (with the same or different types) and in some cases only the listener you just added should receive the message.

One suggestion to resolve the issue is to have joinUserChannelResponse and addContextListenerResponse contain the data when it needs to be sent over. However, as we use addContextListenerRequest/Response for both user and app channel request and it matters whether you are already joined to a channel or not I don't think this is ideal.

Instead, I think we should have the client code handle the situation by calling getCurrentContext itself on the current channel after a join or addContextListener (with null channelId - i.e. current user channel) so that it can send the auto-broadcast to the appropriate listener. For a joinUserChannel call it will already know the channel id, for addContextListener it will either need to query the current channel or be tracking that (which it needs to do for the channel selector anyway).

Thoughts? I think the second approach is going to be simpler to understand and will solve the issue for all DA implementations using getAgent, which will reduce (accidental/non-conformant) variation between implementations.

@kriswest
Copy link
Contributor Author

Note that if the Desktop agent handles the channel selector - i.e. the channel changes for any reason other than a call to joinUserChannel by the app, then the Desktop Agent should sen broadcast events OR we ensure that the client code finds out and makes getCurrentContext requests itself... Either way, we will needed a documented approach that all DAs conform to...

@Roaders
Copy link
Contributor

Roaders commented Jul 31, 2024

I see that there are a few possible solutions to this (if I understand the problem correctly)

  • When we join a user channel the current context is sent in the Response message. This context property should be optional so that when used for app channels it is not populated
  • When we join a user channel the root agent (in the context of a root agent with many proxy agents communicating with it) sends a broadcast event message only to the agent that has just joined the channel. Depending on the messaging implementation this may or may not be possible. I can also see possible race conditions where the broadcast event is sent before the proxy agent has finished setting up the listener
  • The proxy agent resolves the current context itself by calling getCurrentContext

I think that options 2 and 3 are implementation details and agent implementors can choose to go down either of these routes. I think that I would probably prefer option 1 - adding an optional currentContext property to the response message payload. This would cut down the number of messages and async awaits that we need in our code.

@kriswest
Copy link
Contributor Author

Re: option 1 - its more awkward in that the context can be sent either when joining OR when adding a context listener, which ever comes second and after a context has been broadcast to the channel. Hence, two different messages to add a response to, one of which has multiple modes already.

Re: option 2 - we'd have to modify the broadcast message in some way so its clear which listener its intended for. With any normal broadcast it should be passed to all matching listeners. However, here you might have one listener already, a second is added and only the second should receive the broadcast.

We do need to decide on this in the Standard as the client code is standardized meaning that DAs need to work in the same way.

Hence, my preference for option 3 as it doesn't have multiple modes or make other exchanges more complex to understand (by introducing optional properties that are only used in certain cases). The additional complexity is light and implemented in the client code, so it doesn't have to be implemented by every DA (reducing the likelihood of variation and reducing the amount of docs required to explain it).

@Roaders
Copy link
Contributor

Roaders commented Jul 31, 2024

yup, I am happy with option 3.

@robmoffat
Copy link
Member

One slight nit is that getCurrentContext only returns a single item of context currently. We would need to change it so it returns the complete channel state.

@kriswest
Copy link
Contributor Author

@robmoffat You don't need it to return the whole channel state in most cases, only the state for the listener you are adding (on addContextListener calls and if already joined to a channel) or listeners that have been added (on a joinUserChannel call). It's rare (in my experience) that there are more than one or two and there is no defined order so you can simply call getCurrentContext for each listener thats reelvant then fire the appropriate handler when/if you get the response with context in it. Code should be pretty clean and simple for that.

@robmoffat
Copy link
Member

OK, so thinking this through:

  • I join a user channel and add a listener with the null/any type.
  • I change channel to a new user channel.
  • Does the listener only receive the most recent item of context? Or the most recent one of each type?

I thought it was the latter but if the former that works fine

@kriswest
Copy link
Contributor Author

kriswest commented Jul 31, 2024

Each listener only has one type filter which can be null (the most recent context of any type) or a specific type (most recent context of that type). The type argument and behaviour are an exact match between addContextListener and getCurrentContext - basically the auto-broadcast of the most recent context in user channels is an automated call to getCurrentContext which passes the result to the content handler.

i.e. its the former @robmoffat (filtered by the type of the listener)

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

No branches or pull requests

9 participants