-
Notifications
You must be signed in to change notification settings - Fork 106
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
New channel proposition #171
Changes from 6 commits
099930e
a72585a
12142f7
f190362
e793d25
ba3afdf
b4d4b94
6d6999a
3f8e09d
4c21494
2c5c753
ff3cde4
87d9473
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,18 +142,41 @@ Context channels allows a set of apps to share a stateful piece of data between | |
|
||
There are two types of channels, which are functionally identical, but have different visibility and discoverability semantics. | ||
|
||
1. The 'system' ones, which have a well understood identity. One is called 'default'. | ||
1. The 'system' ones, which have a well understood identity. One is called 'global'. | ||
2. The 'app' ones, which have a transient identity and need to be revealed | ||
|
||
The 'system' channels include a 'default' channel which serves as the backwards compatible layer with the 'send/broadcast context' above. There are some reserved channel names for future use. Currently this is just 'global'. | ||
|
||
|
||
### Joining Channels | ||
Apps can join channels. An app can only be joined to one channel at a time. When an app joins a channel it will automatically recieve the current context for that channel, except if the channel joined is the 'default'. | ||
Apps can join channels. An app can only be joined to one channel at a time. When an app joins a channel it will automatically recieve the current context for that channel. | ||
|
||
When an app is joined to a channel, calls to fdc3.broadcast and listeners added through fdc3.addContextListener will be routed to that channel. If an app is not explicitly joined to a channel, it is on the 'default' channel. It is up to the desktop agent to determine the behavior of the 'default' channel, and if context is automaticaly broadcast over it or not. | ||
When an app is joined to a channel, calls to fdc3.broadcast and listeners added through fdc3.addContextListener will be routed to that channel. If an app is not joined to a channel these methods will be no-ops, but apps can still choose to listen and broadcast to specific channels via the methods on the `Channel` class. | ||
|
||
It is possible that a call to join a channel could be rejected. If for example, the desktop agent wanted to implement controls around what data apps can access. | ||
|
||
Joining channels in FDC3 is intended to be a behavior initiated by the end user. For example: by color linking or apps being grouped in the same workspace. Most of the time, it is expected that apps will be joined to a channel by mechanisms outside of the app. Always, there SHOULD be a clear UX indicator of what channel an app is joined to. | ||
|
||
### The 'global' Channel | ||
The 'system' channels include a 'global' channel which serves as the backwards compatible layer with the 'send/broadcast context' behavior in FDC3 1.0. A desktop agent MAY choose to make membership in the 'global' channel the default state for apps on start up. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👏 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What APIs would be used to do this? All proposed, If some external color assignment widget wanted to assign "App A" to channel "red", its not exactly sure how the proposed APIs facilitate this; i.e., there is no API provided modify channel assignment from "outside the app". Whats missing is something like In lieu of addressing this in the API now, I suggest it might be easier to "say less" and remove the sentence "Most of the time..." There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @nicholasgoodman - this raises an excellent point. The API defined here is for apps to interact with FDC3. This does not cover what APIs a desktop agent might use to create default behavior for apps wrt to channels. This omission is purposeful, since this kind of join functionality would be implemented with APIs internal to the desktop agent. |
||
|
||
The 'global' channel should be returned as part of the response from the `fdc3.getSystemChannels` call. Desktop Agents may want to filter out the 'global' option in their UI for system channel pickers. | ||
|
||
|
||
#### Examples | ||
|
||
An app gets the current context of the `global` as a fallback if no other context is set. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure what this means? Can you expand on what you mean by a fallback? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. some platforms may have a tiered approach, where there is a global context (maybe coming from a top-level search) and more localized contexts created with channels. In that case, if an app doesn't have a context coming from a specific channel it is joined to it may want to pull the global context. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am tempted to say this is slightly inconsistent with the rest of the behaviour, and therefore introduces a bit of confusion. I think channels should always work the same way, regardless of what context it is. If you are on no channel, no context will be recorded. If you want context to be recorded, join a channel. In this particular case I would prefer if the spec doesn't mention this behaviour. Someone can still do this if they like, as the standard wouldn't explicitly forbade it, but I don't personally think it makes much sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @rikoe here. I feel we are kind of reintroducing a new special behavior for "global" with this wording. The way I expect - If I join There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rikoe , @vmehtafds - some clarifications:
@rikoe I am not clear on the concerns (I don't see how this is going against channels always working the same) but I am fine changing this example to something else. Do you have any suggestions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nkolba I see what you mean now - adding an explicit listener to global. No other concerns with what you describe. However, The language here indicates special fallback behaviour without having to set up extra explicit listeners, which is unexpected. If you are joined to global, getCurrentContext should get you the context on global, if not, you will get nothing. I think it will be clearer if we just remove the word "fallback" everywhere. Of course you can still directly retrieve the channel itself and listen/retrieve the context on it, but that is a separate workflow from the join channel one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rikoe . Yes, if you are joined to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change If you want to make it even more clear: // retrieve current fdc3 context
const context = await fdc3.getCurrentContext("fdc3.instrument")
// context is null, as not currently joined to a channel
const globalChannel = await fdc3.getSystemChannels.filter(c => c.id === "global")
const globalContext = await fdc3.getCurrentContext("fdc3.instrument")
// context is instrument AAPL on the global channel
fdc3.joinChannel('global')
const context = await fdc3.getCurrentContext('fdc3.instrument')
// top-level context is now instrument AAPL as well because we have joined the global channel There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rikoe just pushed some language cleanup There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rikoe updated example pushed |
||
|
||
```js | ||
let gChan = await fdc3.getOrCreateChannel("global"); | ||
let ctx = await gChan.getCurrentContext("fdc3.instrument"); | ||
nkolba marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
An app wants to respond to all context changes, whether on a joined channel or the `global` channel. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also don't understand what is sentence mean and what feature/behavior the below example demonstrates. Can you just expand a bit? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vmehtafds . This example is showing an app listening to the global channel outside of whatever channel it may be joined to. This example is meant to illustrate context scopes - i.e. I may have a joined channel scope and a global scope. For example, in a multi-windowed application, I may have a top-level search bar that represents global scope and individual windows may be on their own individual context scopes, or joined to a channel-wide context scope. This may or may not be useful for you. I am happy to get other examples in addition to or instead of this one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @vmehtafds here: This is very confusing to me.
I think this idea of scoping etc. is unnecessary complexity at this stage and I don't believe it was something originally in the spec, or proposed before. We should just make channels mutually exclusive. If you do want this type of behaviour (which I think is unnecessary), it should be done by passing an array of channel names to join, and further API support for figuring out how channels are scoped/which "set" of channels you are in. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rikoe @vmehtafds This example seems to be confusing and taking us down a rabbit hole. I'm happy to get other suggestions of how to illustrate the API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rikoe @vmehtafds - just pushed some clarifications to the language on this example. Please keep the feedback coming! |
||
|
||
```js | ||
let gChan = await fdc3.getOrCreateChannel("global"); | ||
let listener = gChan.addContextListener(contextListener); | ||
``` | ||
|
||
### Direct Listening and Broadcast on Channels | ||
While joining channels automates a lot of the channel behavior for an app, it has the limitation in that an app can belong to only one channel at a time. Listening and Broadcasting to channels using the _Channel.addBroadcastListener_ and the _Channel.broadcast_ APIs provides an app with fine-grained controls for specific channels. This is especially useful for working with dynamic _App Channels_. | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is the only difference between
global
anddefault
? Currentlydefault
is not included in System channels.Update: I see below
default
was also supposed to be returned as part of 'system' channels (although OpenFin's current implementation doesnt do that).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vmehtafds The biggest difference between 'global' and 'default' is that you can leave 'global'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vmehtafds another reason for this is I think that the name
default
was part of the problem - the default behaviour is now not to be on a channel (unless you calljoinChannel
). The nameglobal
makes it clearer what this channel does, I think.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rikoe: this is a long thread so i may have missed this somewhere, but how does this change not break implementors who were only utilizing
DesktopAgent.addContextListener(...)
/DesktopAgent.broadcast(...)
?I would question why any change is needed at all. If you never add a context listener, you are de-facto not in any channel, global or otherwise.
The new proposal seems to indicate that using the Channel join APIs are mandatory in order to utilize context; or am I missing something here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nicholasgoodman @rikoe Implementors wishing to maintain backwards compatibility with existing behavior with
desktopAgent.addContextListener
anddesktopAgent.broadcast
can choose to start apps on theglobal
channel by default. The key differences from previous proposals are:global
channelglobal
channelThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would think that maintaining compatibility with the 1.0 spec would imply that auto-joining the global channel would be a SHOULD instead of a MAY; but either way it seems acceptable to me.
Additionally, not sure what "leaving all channels" provides for that can't be handled within the existing add listener or listener callback code; but similarly, I'm not against it either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nicholasdgoodman This is backwards compatible with the 1.0 spec. However, 1.0 was very open ended on this topic and many implementations currently work this way. If you're building an implementation today - especially if your platform leans heavily on color (or other) linking - you may not want apps connected by default. So, I'd rather keep this as a MAY.
The "leaving all channels" pattern is a convenience - but it can be a pretty big one. Apps may have multiple handlers set for context and they may be also broadcasting from multiple points. Also, if some controller for linking is operating on the app's behalf (for example, a preload with a titlebar & color selector) it can turn on/off linking without needing knowledge of how listeners and broadcasters are wired up.