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

Support for Multiple Application Scopes (Agents) within a single window process #1250

Open
Tracked by #1267
Davidhanson90 opened this issue Jul 4, 2024 · 16 comments
Labels
api FDC3 API Working Group enhancement New feature or request FDC3 for Web Browsers

Comments

@Davidhanson90
Copy link

Davidhanson90 commented Jul 4, 2024

Enhancement Request

This enhancement is looking at the problem from a web perspective but could be extended to other implementing technologies.

Use Case:

As more web applications adopt micro-frontend architecture, users often encounter scenarios where multiple application contexts need to be loaded into a single window process through dynamic code resolution techniques like module federation. Currently, the FDC spec assumes a one-to-one mapping between Window, Agent, and Application, which limits the ability to handle multiple application contexts within a single window. This creates challenges for users who need to interact with different application scopes seamlessly within the same window environment.

Workflow Description

The proposed enhancement involves updating the FDC spec to support the creation of Agents with different application scopes within a single window process. This would allow multiple micro-frontends applications to coexist and interact within the same window, providing a more flexible and efficient user experience. The workflow should enable dynamic resolution and management of multiple Agents, each corresponding to different applications, within a single window context.

Workflow Examples

Multi-tool Dashboard

  • A user accesses a dashboard that integrates multiple tools (e.g., a calendar, email client, and task manager) using micro-frontend architecture.
  • Each tool operates as a separate application deployed remotely from the container however will share the context within the same window.
  • The enhanced FDC spec allows each tool to create and manage its own Agent within the same window, enabling seamless interaction and communication between the tools.

Additional Information

Supporting the creation of Agents with different application scopes within a single window process would significantly enhance the flexibility and usability of applications using micro-frontend architecture. This enhancement would reduce the need for redundant window processes, streamline resource management, and improve the overall user experience by enabling more dynamic and integrated interactions between multiple application contexts.

@Davidhanson90 Davidhanson90 added the enhancement New feature or request label Jul 4, 2024
@kriswest
Copy link
Contributor

kriswest commented Jul 4, 2024

Many thanks for raising the issue @Davidhanson90.

There is a proposal to resolve this use case (in both Electron-style containers and on the web) in the FDC3 for Web Browsers proposal:
https://tick42-my.sharepoint.com/:w:/g/personal/finsemble_datastore_interop_io/EZ0dfTCdRlJCnIF3C_1Oit0BF3fsXyvlMbisXp722DC9Kg?e=dRVqQm
(under the heading 'Sub-application API Proposal (use case 4)').

To give a basic overview, it proposes that the following function is added to the FDC3 API:

/**	 
 * @param {string} params Required parameters object, which must include  
 * at least a fully qualified appId or appD URL for the application to 
 * indicate the app's identity. 
 * @param {string} params.appId The fully qualified appId 
 * (in the form appid@<appd origin> for the application 
 * @param {URL} params.appDUrl The URL to the appD record providing the  
 * app's identity, used as an alternative to a fully qualified appId. 
 *  
 * @return A promise that resolves to a DesktopAgent implementation or  
 * rejects if the app identity could not be validated. 
 */ 

type getSubAgent = ( 
    params: GetSubAgentParams,  
): Promise<DesktopAgent>  

type GetSubAgentParams = { 
  appId?: string, 
  appDUrl?: URL 
} 

and that the window acquires a copy of the API as if it were itself an application, perhaps making it available globally at window.fdc3 if not already present, then the sub-applications call this function to identify themselves with details of an appD record (which might express intents that it can resolve) and then retrieve their own copy.

Please feel free to comment on the proposal or to propose changes - it hasn't had as much attention as the other parts of the proposal, although it builds on some of the same approaches (for example the need for additional identity validation steps).

@kriswest kriswest added api FDC3 API Working Group FDC3 for Web Browsers labels Jul 4, 2024
@Davidhanson90
Copy link
Author

Ok thanks for this, it does indeed look like the solution to the problem stated.

@bingenito
Copy link
Member

bingenito commented Jul 17, 2024

I very much want to also bring this into fdc3-dotnet as I feel it will solve alot of problems with native apps built through composition to address appid/instance at the module or widget level.

@robmoffat
Copy link
Member

If I'm reading this right, we're basically saying that one application can exist in multiple windows?

What are the implications for delivering intents or broadcast contexts?

@kriswest
Copy link
Contributor

If I'm reading this right, we're basically saying that one application can exist in multiple windows?

@robmoffat No, multiple applications in the same window and allowing them to communicate with each other over FDC3 in the same way as they would with apps running in other windows.

@kriswest kriswest changed the title Enhancement Request: Support for Multiple Application Scopes (Agents) within a single window process Support for Multiple Application Scopes (Agents) within a single window process Sep 3, 2024
@kriswest kriswest added this to the 2.3 candidates milestone Sep 20, 2024
@Roaders
Copy link
Contributor

Roaders commented Nov 21, 2024

Some thoughts on this. Some questions that we will have to answer when we come to implement this:

  • Will a sub agents appear to the other applications as separate instances? In other words will sub agents be listed separately in an app resolver ui?
  • Related to the above will subAgentOne AND subAgentTwo be able to register the same intent listener (to do this they would have to be listed separately in the app resolver UI)

@kriswest
Copy link
Contributor

Hi @Roaders, my 2p below:

  • Will a sub agents appear to the other applications as separate instances? In other words will sub agents be listed separately in an app resolver ui?

I believe this to be one of two key requirements of the proposal:

  • Sub instances should be able to register their own intent listeners (and as only one listener can answer a raised Intent they need to be individually addressable)
  • Messages broadcast by a sub-instance within a window receive broadcasts sent by other sub-instances (but not their own as we do not deliver back to the sender).

If you can't route intents to sub instances-specifically then they could just be using the window's FDC3 instance and would not need their own...

  • Related to the above will subAgentOne AND subAgentTwo be able to register the same intent listener (to do this they would have to be listed separately in the app resolver UI)

They would have to be able to in order to achieve the first point. You can only register a single listener for each intent through each instance of the DesktopAgent interface (which this open PR will clarify in the documentation #1394 - this has always been the case, we're just making it clearer in the documentation. We'd be allowing the creation of multiple interfaces in a window but each could only register a single listener per intent type.

@Roaders
Copy link
Contributor

Roaders commented Nov 21, 2024

Ok, that all makes sense. It seems that sub agents are fully self contained agents that have all the features of a normal agent. The only difference is that there can be multiple in one window.

A couple more questions:

  • Does a normal agent have to be created in the window using getAgent() before a sub agent is created - I would guess not.
  • When a new window is opened with desktopAgent.open() and if the window has multiple sub agents registered (with or without a normal agent) which instance id is returned from the window.open()?
  • It is now possible to have one "app" with multiple agents in. This means that one app can be joined to several different user channels. I assume there is nothing proposed to keep all sub agents joined to the same user channel?

@kriswest
Copy link
Contributor

@Roaders if you look further up in this thread theres a proposal to add a function to the DesktopAgent interface above that would create a sub-instance. Hence:

Does a normal agent have to be created in the window using getAgent() before a sub agent is created - I would guess not.

As proposed above, yes you would need to create a window-level instance and then use it to create sub-instances. I don't see a way around that without breaking both types of Desktop Agent interface (Desktop Agent Preload and Desktop Agent Proxy).

That proposal is a little out of date as FDC3 for the web has moved away from apps providing details of their own identity via appId, they now pass a URL and ask the DesktopAgent to assign the appId (a change that I believe was short-sighted). However, for a sub-agent they would either have to pass an appId or appD URL (as per the original fdc3 for web proposal) to connect themselves to a configuration to provide at least metadata on intent/context pairs they listen for.

If they don't work this way (calling a new standard function on the window-level DesktopAgent), a new interface will need to established in the Standard to accomplish this without tieing apps to a particular implementation - and I suspect that this would add significant complexity.

It is now possible to have one "app" with multiple agents in. This means that one app can be joined to several different user channels. I assume there is nothing proposed to keep all sub agents joined to the same user channel?

Again if this were the case you would need sub-agents - you'd just listen at the window level and farm the events out to each sub-application. Looks at @Davidhanson90's terminology above, each sub-agent is relating to a specific app scope and identity. Hence, there is a parent 'app' that owns the main instance and might be joined to a particular channel, and 'sub-apps' each with their 'sub-instance' that could each be joined to a different channel? Perhaps thats an area of the proposal that needs development.

@Roaders
Copy link
Contributor

Roaders commented Nov 21, 2024

I had missed that the getSubAgent function was to be added to DesktopAgent. I had thought that it would be a function at the same level as getAgent()

@kriswest
Copy link
Contributor

That could be an alternative proposal - but its going to add a complexity to the Desktop Agent Proxy interface (as multiple interfaces would be trying to message over the same window.postMessage - not impossible however) and would need a wholesale alternative to the Desktop Agent Preload interface used in containers (as it only injects one interface)... That would necessarily be a much bigger set of changes.

@Roaders
Copy link
Contributor

Roaders commented Nov 21, 2024

I might have missed some discussion on this then. Are there any documents on this?

It sounds like only 1 interface (the desktop agent created by getAgent()) will communicate from a given window. Sub agents will then be created by the DesktopAgentProxy (or root DesktopAgent in the case of the root window) and the communication for those will go through the same channel setup by the DesktopAgentProxy. Is that correct?

This could cause some headaches. We have assumed in our implementation that all messages received over 1 message channel are from a single interface instance. If we now have multiple instances communicating over the same channel we will have to use a different method to determine the source of the message.

@kriswest
Copy link
Contributor

I might have missed some discussion on this then. Are there any documents on this?

There was a small amount of discussion in FDC3 for Web meetings and a proposal for web-based DA's worked up in the shared doc (starting on Page 18): https://tick42-my.sharepoint.com/:w:/g/personal/finsemble_datastore_interop_io/EZ0dfTCdRlJCnIF3C_1Oit0BF3fsXyvlMbisXp722DC9Kg?e=e0e53o

It sounds like only 1 interface (the desktop agent created by getAgent()) will communicate from a given window. Sub agents will then be created by the DesktopAgentProxy (or root DesktopAgent in the case of the root window) and the communication for those will go through the same channel setup by the DesktopAgentProxy. Is that correct?

Not quite, the window-level agent would be created and connected by something. A sub-application (or parent app creating said sub-app) would then request an additional instance via an API call - directly using the the first interface. The DA returns an additional MessagePort in its response, which it then communicates with like it does any other message port. I.e. a second connection gets created through the first connection, thereafter they are independent.

Hopefully, that solved your issue above. However, its just a proposal at this stage - but it did seem the least complex solution at the time!

@Roaders
Copy link
Contributor

Roaders commented Nov 25, 2024

ok, so there is no additional handshake process, just a message to return a new channel. That makes the communication easier...
How does this work if agent => proxy communication is done over an iframe?

@kriswest
Copy link
Contributor

Basically, the WCP connection flow (started by the app calling getAgent) is replaced by an API call - otherwise everything works the same way as it would for a normal app connecting with getAgent.

In both cases (normal connection and subagent connection) the Desktop Agent needs to send over a MessagePort for further communication. That happens in WCP3Handshake for normal connections, it would be in the response to the API call for subagent connections. We'd need to decide if the identity validation step for subagents happens as part of the API call and first message exchange or to have it happen in the same way as the first message exchange on the MessagePort for normal connections - I suspect the latter would make for simpler implementations. From there, the Desktop Agent can communicate with the sub-app via the MessagePort as it would any normal app, it should look no different despite being in the same window as other apps.

Hence, the main app and sub-app never actually share a messaging channel/MessagePort. The window-level app's connection was just used to retrieve a separate MessagePort, which the sub-app uses to communicate thereafter.

Container-based agent (Desktop Agent preload) can implement this however they need to - they'd just have to support the ability to retrieve another instance of the API interface and have it be considered separate to the first one.

Does that answer the question? This is all just based on my own view of how to do this from past meetings and the associated proposal. It seemed the simplest/most elegant approach.

@Roaders
Copy link
Contributor

Roaders commented Nov 25, 2024

yes thanks very much @kriswest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api FDC3 API Working Group enhancement New feature or request FDC3 for Web Browsers
Projects
None yet
Development

No branches or pull requests

5 participants