| [news.eclipse.technology.ecomm] Re: An abstract conferencing model |
Scott:
jfp
Scott Lewis wrote:
I'm wrestling with this one a little bit. The problem is what is listening for an invitation to a new conference. If the factory is implementation independent, then it cannot listen for invitations, since these will be implementation specific. So we have to get some code running that is ready to handle invites for each implementation that we might choose to support. But, I don't think of the container (conference) as existing until after the invite arrives. Perhaps this relates back to the universal container idea. Do you assume that clients connect to the universal container for every implementation that they care to work with? Then, invites to subcontainers (conferences) could be handled through this universal container.Hi John,
Here are my comments about your high-level description. In general, I think what you describe and what I've implemented in the composent work are very similar.
John F. Patterson wrote: <stuff deleted>
OK, here goes. I define four main interfaces:
1) ConferenceService -- This is a machine-based container for all Conferences managed by the machine. It primarily serves as a place to create a new Conference, be invited to join a Conference, and query about joined Conferences. In some cases, it might also act as a way to find out about ongoing Conferences even if they have not been joined. Factories for constructing new conference types and new conference tool types may be plugged into the ConferenceService.
Within my own work, this ConferenceService has been referred to as a 'container factory'. Essentially this is a class within a plugin (the org.composent.api.StageContainerFactory class in the org.composent.api plugin) that provides a service for creating conferences/containers within a given Eclipse platform instance.
An interesting question is whether there is one ConferenceService (a singleton) for all underlying implementations or multiple ConferenceServices, one for each underlying implementation. In the past, I have tended to assume a new ConferenceService per implementation, but the loss of a unified list of ongoing conferences (assuming you are running against mutliple implementations) might be regrettable. On the other hand, managing invites and querying for ongoing conferences can be fairly implementation-specific. I am uncertain on whether to have one ConferenceService per implementation.
I have taken the approach of providing a single distributed container factory, but having that factory be able to construct a variety of types of containers. That is, the factory creates instances that implement an abstract 'container' interface and the static 'make' methods are general enough to create instances whos types are not known at compile time. This also makes for a natural Eclipse extension point...as other plugins can substitute their own new implementations of various types of containers at Eclipse initialization time, and have their type of container be created when a request for new container comes through the factory.
I might not have posed the issue very well. I assume there will be a distinct object for each participant. The question is whether there is a different type for my presence vs. everyone else's presence. For example, one type might be ConferencePresence and another type might be MyConferencePresence, which would be an extension of ConferencePresence. I think I first encountered this approach in the Sametime APIs. At first, I thought it was kind of silly, but later, I started to like the idea. As a general design principle, I like to provide only those methods that can actually be used by an application. Since I can do things to my presence, it needs to provide more methods than other presences. If I use the same type for both presences, then I have to throw an exception when someone tries to manipulate someone else's properties. If I use different types, then the application will not generally have access to the setters that are not permitted.
2) Conference -- This is contained by the ConferenceService. It's primary job is to manage the multi-point relationship of the Conference. It is not the place to actually communicate. If you are familiar with telephony, this is similar to the notion of signalling as distinct from data transport. In any case, the Conference is where one learns about ConferencePresence objects as they join and leave the Conference. This is where one can leave the conference or query the current list of ConferencePresences.
Right. In the model I've worked on so far, your notion of a Conference has been generalized to be a 'distributed container'. As you point out in another post, there are a lot of names for such a thing...e.g. conference, session, space, group, pipe, etc. Essentially such containers are 1) constructed/managed by the above-described service; and 2) are responsible for a) join/leave (aka connect/disconnect) operations...including authentication; b) creating/managing/destroying individual 'components' and c) maintaining group membership (uniquely identified set of participants within the conference) so that each participant can reliably respond to group membership changes (e.g. remote process failures, etc).
The Conference also manages the ConferenceTool objects. ConferenceTools may be created or destroyed and queried for the current list. The Conference will signal an event when a ConferenceTool is created or destroyed by some other ConferencePresence.
Your use of ConferenceTool basically corresponds to my use of 'component'.
3) ConferencePresence -- This identifies a communication endpoint in the multi-point relationship managed by the Conference. These objects are contained by the Conference. They primarily provide attribute information regarding the identified presence. They are not directly used to send information to the presence, i.e., there is no send method. Communication is done via the Conference Tools.
The ConferencePresence object raises three interesting design questions:
a) Should my presence be noted by the same object as other people's presence? Generally, I can act on my presence, but I cannot act on other people's presence, so I have come to think of these as distinct object types.
In my own work, I've implemented it both ways. IMHO it's slightly more natural (for me) to have a distinct component corresponding to each participant's presence info.
I think your notion of primary and non-primary objects is pretty much the same as what I described above. I would just be inclined to provide different interfaces for the two types.b) Should changes to my attributes be signalled through to others in the conference or should my attributes be final? I like the idea of changable attributes, but it is more complicated. (It is like bringing a deeper notion of presence/awareness into the conference.)
For my previous work, I've introduced the notion of allowing peers/clients to create a *primary* copy of an arbitrary object into the container, while other peers/clients have a non-primary copy. For such objects (e.g. presence state and behavior), *the creating peer* is authoritative WRT the state of the object and wrt communication of state updates (how much info, and how frequently). That is, for my presence object (for example), I am the owner/creator of that object, and for the other copies of that presence information the state is considered transient and non-authoritative. So, for example, if I leave the session, the presence information about me being displayed on other people's screens is assumed to be stale, and non-authoritative.
This allows peers to introduce components into a distributed container, replicate (to some degree) the code and state of the component to other participants, and a) keep all the replicated state consistent as various participants access and possibly modify the state of that object; b) remain locally authoritative about who is allowed access to changing that state.Interesting, I understand the idea that Presence objects are just another object, but I am not altogether comfortable with it. This seems a great description of a shared object that I might add into a conference, but it seems too loose for Presence objects. I think this goes back to Presence objects relating to privacy concerns and wanting to ensure that policies about presence can be enforced.
I'm not sure you stated your position, but I am inferring that you provide arrival and departure events on the container.
c) Should one learn about leaving the Conference via the ConferencePresence? I used to prefer this and I have come around to believing that one should listen for leaving in the same place one listens for joining, i.e., on the Conference.
In my current formulation, ConferencePresence are just additional instances of 'components' (conference tools...see below). Such presence components, however, are somewhat special in that they depend heavily upon the group membership notifications that are provided by the distributed container...in order to show in the user interface the 'arrival' and 'departure' of a given participant (uniquely identified upon join/authentication within the container).
Once again, I am uncomfortable with treating presence like other objects.
My approach to components is to provide a base interface, call it BaseTool, that has almost no methods defined. It exists for polymorphism purposes. Only those methods that would be desirable on all subtypes should exist here, e.g., getName, getType. I would not put any important functionality here. That just forces the component designer to support something they might prefer to hide. Then I provide a default interface, call it DefaultTool, that contains most of the raw capabilities you would expect, e.g., send, apply listeners, create subtools, etc. When an application asks the container for a tool of a particular type, the container (conference) finds the appropriate factory, creates a default tool, and passes the default tool to the factory while requesting a new instance of the desired tool. The factory wraps the default tool with an object of the desired type and maps the interface it exposes onto the raw default capabilities of the default tool. This way the calling application only has access to the tool using the methods provided. There are no methods marked "please do not use" and the implementation of the component is completely hidden behind the interface.
4) ConferenceTools -- This is where the communication takes place. ConferenceTools are contained by the Conference. There will be different tools for different types of communication, e.g., chat, voip, app-sharing, etc. Each tool will have a different interface depending on the capabilities one wants to support. They are all sub interfaces of ConferenceTool. Without diving into the details of any particular tool it is hard to say much about the methods that will be available. Presumably, all tools will have some identifying information, such as a name or properties.
Yes. My name for these are 'components' (referred to as 'stages' in the org.composent.api source code). Components/stages have an identity/name, arbitrary properties, arbitrary state, arbitrary method/code, and potentially have their state information distributed or replicated within the current scope of the container (on all the processes that have joined the container). Also provided to the component is a simple messaging api to send/receive arbitrary messages to/from remote replicas...and to receive notifications about group membership changes...e.g. to implement presence changes caused by group arrivals/departures.
I hope that made sense.
This confuses me a little. I think the point was that if tools are not joined by all participants present in the conference, then we will need lists of participants on each tool so that each client can sort out who is using each tool. I'm not sure why this argues for globally unique IDs. The membership list on the container might constrain the membership list on each tool, but it does not eliminate the need for the membership list on each tool.
ConferenceTools raise two interesting design questions:
a) Should ConferenceTools be able to contain their own ConferenceTools? I am inclined to say yes. One might imagine, for example, a ConferenceTool that simply provides an unformatted communication channel among the ConferencePresences.
Yes. In my previous models, components have the ability to contain and/or construct new components at runtime. Allowing for runtime manipulation of the available capabilities/functions within the scope of the container.
Then a tool that
needed two of these could create them and contain them to do whatever it needs to do. Similarly, we might have a chat tool and an app-sharing tool and decide later that we want a tool that always has both chat and app-sharing together. This would just be a new tool containing the original tools.
Yes. This is exactly how my current set of plugins function. If an app share is started, for example, the appropriate component is simply introduced into distributed container (with multiple participants). The person that's doing the application sharing is authoritative WRT the state updates being made (changes to the display of the shared application).
b) How are ConferenceTools different from Conferences? This is an interesting and subtle question. As presented above, I have assumed that the ConferenceTools "inherit" their multi-point relationship from the Conference. In other words, if you are in the Conference you are in all its tools. This is a simple policy, but it is not clear it is the best way to do things. Just because someone is not able to participate in some tool (for example, I might not have voip installed) does that mean others should be precluded from using the tool.
No...and separating components from containers allows this distinction to be made at runtime...that is, I may be able to participate with you in a given conference/container, but there are somethings that we all can do, somethings that only some of us can do, and some things that none of us can do within the scope of this container. Whether by individual or group policy, or by availability of code, or by limitations on local clients (like not having voip installed, or not having a microphone, etc) a separation between the container and components within such a container allows heterogeneous clients to coexist rather easily.
So, for example, within my own composent work, I've created an applet-based client that interoperates just fine with the eclipse-based client. See 'join web collaboration' link for the ecomm project on following page, for example:
http://www.composent.com/eclipse/applet/table.html
Generally, the answer is that not everyone will be involved in every tool. This means that we will need to provide indications of presence on the tools so that we can know who's in and who's out for that tool. So, if ConferenceTools will also have lists of participants and lists of their own tools (as in a) above), how are they different from Conferences?
They can use the container as a common resource to provide consistent access to these lists of participants and lists of components. That way they don't have to reproduce them. So, in addition to basic messaging primitives provided to the components by the container, the container can also provide access to these lists WRT membership information and the existence (or not) of other uniquely identified components. Note that this is where identity being associated with components is critical...as components need to have access to a globally unique identifier for each component.
I think I phrased this poorly. I'm not going to try to recover. I think we agree that the conference (container) keeps track of group membership for the whole conference. When I join an existing conference, I will learn about the existing tools and decide which of them to join. If I choose not to join some, then others will need to learn that the tool membership is less than the conference membership.
While there is something deeply similar about Conferences and ConferenceTools, I still see three fundamental differences that make me inclined to represent the root of the tool hierarchy different from the other nodes.
i) While the ConferenceTools must somehow "track" the comings and goings of membership in the Conference, the Conference has no such requirement.
I would argue that the container is required to track the membership...so that reliable group membership information can be communicated among peers as members drop/fail, etc...so that other entities can keep a consistent view of the group membership. So if the container does it reliably, and the components have an api to access the this information if they need it...then the 'tracking' doesn't have to be duplicated.
ii) I do not think it is wise to allow the membership in the ConferenceTools to exceed the membership of the Conference. I would consider it surprising to discover that there is someone in the chat who is not even a member of the containing conference.
Right. This would be a very confusing state, and also a security risk (as you don't want participants or components able to participate in any way in the context of the container if they are not explicitly authenticated).
OK. At least the issue is clear. I was hoping that we could treat only the top level resources, i.e., conferences (containers), and online presence, as globally identifiable. If the resources from one conference, say a whiteboard, have to be able to be moved (not copied) to another conference, then the world is a more complicated place. Are we willing to identify these as distinguished objects or are all shared objects like this? Are the objects in only one container at a time or can they be in multiple containers at one time. (I hope it is the former.) Can these objects only be moved among the conferences in which I participate or can they be moved to conferences that I know about, but am not involved in?
iii) I do not think
that ConferenceTools will have a URI. The Conference will be identifiable from outside the Conference, but its tools will only be identifiable in the context of the Conference. This has a number of implications, but one of the most interesting is that one does not think of moving a ConferenceTool from one Conference to another.
Although to me there is nothing 'wrong' with having the identity of a component be scoped to be only unique within a container (it has to at least be that, however), it definitely means that a given component can't move from one container to another. This means some kinds of component portability would be impossible, so I would expect that for some kinds of containers the component identifiers would be guaranteed to be globally unique.
OK, but we need to be clear about two different approaches to policy. In one approach the policy is imposed cooperatively by the applications. The underlying infrastructure has not ability to enforce a policy. When this occurs a rogue implementation can violate the policy and complying applications might not be able to tell the difference. In the other approach, the infrastructure takes control of the policy so that it can enforce the policy. Part of the problem of design is to decide when to use either approach. I am inclined to use application-based policy when departures from the policy primarily harm the client that is deviating or departures can be easily detected or departures are fairly inconsequential. Whenever a policy, such as reciprocity of presence, is fundamental to the establishment of trust, I am inclined to manage it via the infrastructure.
I suppose these last two constraints are an imposition of policy, but they are policies that I am fairly comfortable with. I might be persuaded to adopt a looser, more general approach, provided I could impose these policies when desirable. I haven't really thought this through yet.
Right. I think of this as a policy that's appropriately applied on a container instance-by-container-instance level...that is, a given container instance (a given session for communicating among a given set of processes) might apply this policy, while other containers might allow this constraint loosened.
*******
I guess that's enough for now. That should help you understand where I am coming from. I hope you can help me understand the ways in which your proposal is similar or different from the approach outlined above.
I actually think we're very much on the same wavelength. The composent plugins do implement many of the concepts discussed below...e.g. factories to create conferences/containers which hold components/conference tools, with such components coming/going at runtime and updating remote and local state via the communication primitives provided by the container.
Thanks for the thoughts. Please keep them coming. Hopefully this was helpful for you. I've got some docs on my previous work (which ideally will inform but certainly not determine the ecomm work)...so please let me know if you would like to see them.
Scott