OpenAjax Hub Specification v05 Issues
From MemberWiki
(The most current version of the OpenAjax Hub Specification is at http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification.
(This wiki page holds a portion of the version 0.5 internal editorial draft for the OpenAjax Hub 1.0 Specification. The home wiki page for the version 0.5 draft specification is at http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification_v05. Version 0.5 is preserved for historical reasons and therefore may be out of date. A key point about version 0.5 is that it holds the first stable version after implementing decisions about the Hub made at the March 2007 face-to-face meeting and in the follow-in meetings which resolved detailed issues from March to May 2007.)
ISSUES
This appendix lists some of the open and closed issues relevant to this specification. This appendix will be removed before the specification is finalized and published.
The write-ups on this wiki page for individual issues should not go beyond executive summaries. Detailed write-ups should be posted elsewhere and referenced from this page.
OPEN ISSUES (most recent issues listed at top)
(there are no open issues at this time)
CLOSED ISSUES (most recent issues listed at top)
Issue 14: Should pub/sub callbacks be passed the list of tokens?
Original write-up
Bruce says: Now that #2 is settled (and before we finalize the signature of the event subscriber callback function), I'd like to quickly discuss the idea of passing the tokenized event name (that is, the array of tokens) to the subscriber. When receiving an event via a wildcard subscription, the subscriber could likely dispatch more efficiently by looking at directly individual tokens than having to reparse or match against a sequence of regexs.
Resolution
During the 06June2007 telecon (http://www.openajax.org/member/wiki/Interoperability_Minutes_2007-06-06), we said "no" to this issue.
Rationale
We wanted to keep the parameter list simple, and therefore not add another parameter. In many cases, callbacks would do a string comparison on the full event string, not evaluate the tokens. Also, it is easy and not particularly performance intensive for the callback function to call split() if its needs the list of tokens.
Issue 13: If we say Yes to Issue 12, what event names to use?
Original write-up
If we broadcast an event with each subscribe/unsubscribe, what topic name should we use? Here are some options:
-
org.openajax.hub.(un)subscribe(parallel withorg.openajax.hub.registerLibrary) -
org.openajax.hub.sub.(name)(where (name) presumable is the name of the event that was published) -
(name).sub(where (name) presumable is the name of the event that was published - Howard recommends against this one)
Each event has a payload (the second parameter to OpenAjax.publish(), which is publisherData). The topic name of the event which is being subscribed/unsubscribed could be included in the payload. (In fact, maybe the payload would be the "sub" object that is returned by OpenAjax.publish.)
Proposed Resolution
If we say "no" to issue 12, then this issue is moot.
Resolution and Rationale
During the 16May2007 telecon, we said "no" to issue 12, so this issue is moot.
Issue 12: Should the Hub publish subscribe/unsubscribe announcement events?
Original write-up
It's trivial to have the Hub broadcast all subscribe and unsubscribe events. Here is the single line of code to broadcast a subscribe event:
this.publish(ooh+"subscribe", sub);
where "ooh" was previously set to the string "org.openajax.hub.".
Subsequent email discussion
- Howard: while on-subscribe notification is useful at the app level, it is much better to let applications implement implement it as needed, rather have the OAH implement it. This is because most use cases for subscribe.(name) events require application-level payload of some kind in the subscribe.(name) event, and the OAH has no way to include that app-level payload.
- Howard and Bertrand talked about features that we might add to the Hub to allow querying about subscribers to a topic, such as
hasSubscribers(name),listSubscribers(name), orcountSubscribers(name): I did think about proposing addition of either a count or a list, because it can be useful under some circumstances, but I decided not to propose the addition of a new method. - Howard: Would it be okay to defer this?
- Bertrand: Is there a clear scenario for that? It seems to me like this will introduce some complexity in the specs (issues like what happens when you unsubscribe to unsubscribe, etc.)...I ... am fine with deferring 12. We do not have a use case, I thought you had one actually
Proposed Resolution
Do not publish an event with each subscribe/unsubscribe, but put a note in the spec that says a future version of the Hub might publish such events. (This takes a minor step towards addressing our inconsistency around publishing an org.openajax.hub.registerLibrary event but not an org.openajax.hub.subscribe event.)
Email comments 5/15 and 5/16
- Howard: I agree that we should defer this.
- James: Publishing an event any time someone subs/unsubs seems like a bad idea...I would be fine with a note but we should probably never actually follow through on what the note says.
- Bruce: agreement to postpone. In the vein of COM tear-off interfaces, these sorts of events could actually support increased efficiency in some cases, allowing publishers to lazily activate/deactivate subsystems based on whether or not there are any subscribers. However, it's still a research project at this point. A seemingly more affordable variation of this idea would be to have "firstSubscriberAdded" and "lastSubscriberRemoved" events.
Resolution and Rationale
During the 16May2007 telecon, we decided to not have the first version of the Hub broadcast events for subscribe and unsubscribe actions. See above discussion for rationale.
Issue 11: Do we really need/want a scope parameter to OpenAjax.subscribe()?
Original write-up
We have been exercising a ruthless sword that has cut the feature set within Hub 1.0 to a bare minimum. Should we use the sword once more to remove the scope parameter to OpenAjax.subscribe? Right now we have 5 parameters:
OpenAjax.subscribe(name, scope, callback, subscriberData, filter)
where scope is used to allow for late-binding definition of a callback where a particular classname (defined by the scope object) has an associated function name identified by string, where this function is defined sometime after the call to OpenAjax.subscribe. All of this is possible without a scope parameter without much effort. Maybe we should cut back to 4 parameters by removing scope.
Related sub-issue
If we keep scope, should the parameters be ordered as OpenAjax.subscribe(name, scope, callback, subscriberData, filter) or OpenAjax.subscribe(name, callback, scope, subscriberData, filter)? Howard's implementation has the former (i.e., ...,scope,callback,...), but Alex's original implementation had this reversed (i.e., ...,callback,scope,...). (And Simone's also proposed this order in the archives.) Howard's proposed order is more "logical" because scope is the broader context and callback the more specific, but Alex's proposed order allows scope to be an optional parameter that in many (most?) cases will not be used.
Subsequent email discussion
- Howard: In case anyone reading this conversation isn't sure what we're all talking about, here is what the "scope" parameter in subscribe( ) is doing for us: scope ensures that if the callback or filter function uses the JavaScript keyword "this", then "this" refers to the specified scope -- which is typically an object that uses the callback function as one of its "methods" -- rather than to the OpenAjax Hub itself.
- JamesM: Scope is very handy in Dojo and it does fit into an OO paradigm a lot better than alternative methods. I find myself using it all the time, which seems like a pretty good argument in its favor.
- Howard/Simone: I agree with Simone. It feels as though without the scope, any space savings in the hub itself is lost because it will probably be done many times at the application level instead of once lower down...I initially removed scope from my implementation, Kris, citing simplification, but I received feedback from various developers who are expecting to use the pub-sub mechanism, asking me to put it back in...I agree with minimalism, and I do not believe that leaving out scope would cripple the OAH, but I do think it is worth retaining to keep the OAH friendly to a variety of different application approaches.
- Kris: Keeping scope is not natural to JavaScript when passing functions as first class objects (ie passing in a handler)...I am asserting it is just extraneous. It is quite common for JavaScript functions to receive handlers, and as Bertrand restated there are plenty of ways to maintain scope such as closure or bindings. It is simply not necessary for pub/sub library to recreate scope bindings, since this can be done easily without a scope parameter, as JavaScript provides straightforward means for scope preservation (and OO-ness) that does not require every function argument reciever to handle the scope preservation. Anyway, not that big of deal, just seems like this library should be as a light and simple as possible, not including extra unnecessary code, but I think you all agree with that.
- Bertrand: I'd say cut it...I'm a little uneasy with keeping two pieces of information around where we could have one. To be clear to everybody, what I was referring to earlier is the practice of tying the scope to the function like this:
function createDelegate(scope, f) {
return function() {
f.call(scope);
}
}
The function you give to the subscribe API (if you need to maintain scope, which is not necessarily always the case) is createDelegate(this, callback) instead of just callback.
Getting rid of the scope also makes the api more consistent with similar DOM APIs. It also creates a less confusing experience for users of frameworks where this is common practice (such as ours): if the function pointer that's being handed over to the hub is *already* a delegate as created above, what should go into the scope parameter? Null? The same object even though it will be ultimately ignored?
On the other hand, you could also argue that it makes the calling code a little more complex, but again this is common practice in JavaScript and something to which people are already used.
Jon's proposal for resolving the issue
Probably people will be OK with any of the options listed above. Let's do a straw poll at the next telecon and see how many prefer which option and whether people have strong feelings about one method or another.
Email comments 5/15 and 5/16
- Howard: I am in favor of keeping the scope parameter. On the sub-issue of parameter ordering, I am okay with either order. I generally prefer the current one, but I it's not a strong preference.
- James: This really boils down to personal preference. I prefer scope. I don't think there are any compellnig arguments for or against it other than "this is what I like and am used to."
- Bruce: (no comment implies agreement)
Resolution and Rationale
During the 16May2007 telecon, we held a strawman poll where there were several votes for keeping the scope parameter but placing it after the callback parameter, with everyone else abstaining. Thus, it will be OpenAjax.hub.subscribe(name, callback, scope, subscriberData, filter). The rationale is that having a scope parameter's convenience seemed to be more important than simplifying the list of parameters, but set up the parameter list such that for some common cases the developer would only have to pass 2 parameters, as in OpenAjax.hub.subscribe(name, callback).
Issue 10: How unsubscribe works
Original write-up
Howard has provided an implementation of OpenAjax.unsubscribe() where OpenAjax.subscribe() returns a subscription object(e.g., sub = OpenAjax.subscribe(...)) and where unsubscribing happens by passing back the subscription object (e.g., OpenAjax.subscribe(sub)).
Seems like a solid approach, but we need to review this and make a decision. Observe that in Howard's implementation the returned subscription object is a live pointer into the internal data structures used by the Hub's implementation. This approach was discussed on email. If used, we would need to tell users not to modify or delete this subscription object.
Revised approach from subsequent email discussion
Howard, Bertrand and others exchanged email on this topic and have concluded that:
- OpenAjax.subscribe() returns an opaque handle that somehow contains a unique identifier for that subscription. This handle is what is then passed to OpenAjax.unsubscribe to cancel a particular subscription.
- An implementation of the Hub may choose among many approaches in terms of the underlying JavaScript object (string, integer, associative array, etc.) used to hold the opaque handle.
- Our reference implementation will follow Howard's suggestion and pass back a string that consists of the topic name followed by a "." followed by a unique integer for the given subscription. By including the topic name, we can leverage random access lookup performance. By including the unique integer, we can distinguish between multiple subscriptions to the same topic name. By using a string, we avoid the risk of live data being modified accidentally by the host JavaScript due to the immutability of strings.
Email comments 5/15 and 5/16
- Howard: I agree with the proposed resolution. I have the working reference implementation.
- James: Sounds fine, similar to the way setTimeout() and setInterval() work.
- Bruce: (no comment implies agreement)
Resolution and Rationale
During the 16May2007 telecon, we decided to accept the revised approach shown above. See above for rationale.
Issue 9: OK to remove the bootstrapping and modularization features from Hub 1.0?
Original write-up
Earlier versions of the Hub had more features, including a markup scanner whose footprint was roughly 50% of the Hub. Largely because of the markup scanner, which was both large and not likely to be used by all toolkits, we included a modularization feature in the earlier versions of the Hub which allowed for partial initial download of the Hub and incremental downloads of other Hub components.
The latest open source project is much, much smaller (between 2K and 3K after removing comments and extra white space), versus earlier versions that were between 10K and 20K after compaction. Therefore, it seems that we no longer need the bootstrapping and modularization features in Hub 1.0 and can postpone these features to the future if/when we might need them. (Note: as of 2007-05-07, the open source project only uses EventName, not {prefix,EventName}, but the open source project will change to reflect our decision here.)
Subsequent discussion
- Howard: (new) I am now okay with removing this. I agree with Bertrand's rationale below.
- Bertrand: ...the bootstrapping was mainly shaped by the use that was made of it. As this use is being pulled, I don't see the point in keeping it there. Removing it also adds the ability to redesign/modify it when and if it becomes necessary again. I'd vote for removing it. Actually, in our own internal test implementation we haven't implemented it at all.
- Jon: (Not expressed in any emails) Drop it. It isn't used now. The smaller we make the Hub, the easier it will be for toolkits to just bundle it, therefore accelerating adoption. (In fact, we need to look at ways to get the compacted version under 2K.) We can add it back into future versions if we need it. (Pretty sure Alex and Adam would share this opinion based on discussions with them.)
Proposed resolution
Don't include bootstrapping in Hub 1.0.
Email comments 5/15 and 5/16
- Howard: I have changed my position. I now agree that we should remove registration for now.
- James: Proposed resolution fine.
- Bruce: strong agreement that we should drop it for now. Our experience is that the number of HTTP requests often dominates performance (in some cases, more than absolute # of bytes transferred), so we would be very hesitant to bite off on runtime modularization as part of the baseline spec. Along the same lines, we should double-check that the hub design can always work when inlined within app/toolkit code.
Resolution and Rationale
During the 16May2007 telecon, we decided to not include any modularization and bootstrapping features in Hub 1.0. See above for rationale.
Issue 9: Do we need a mechanism to cancel events, and if so, how should it work?
MS Ajax supports the ability to cancel events. Bertrand says:
So in my example of a cancellable event, if a handler cancels, the other ones are still being called (and can even cancel the cancellation). What is cancelled is what happens after the event, not the other subscribers calls. Let me make the example more precise, say you have a form and you subscribe to the submitting event. This event happens right before the form is submitted. Subscribers can cancel, and in this case, the other remaining subscribers are still being called, but the form submission is cancelled.
W3C's DOM Events spec (DOM3 version is at [1]) allows an event to indicate whether it is "cancelable", where "cancelable" means that the event has an associated "default action" which can be prevented from occurring. In the case of the hyperlink in the browser, canceling the action would have the result of not activating the hyperlink. An event handler achieves "cancel" by calling the preventDefault() method on the Event interface.
Resolution: this is not really an issue.
Rationale: Bertrand initiated this discussion, Jon attempted to write it up, then Bertrand said: "this is not really an issue, it's more an example where having a mutable payload makes sense", so the issue was closed.
Issue 8: Should event listener callbacks be allowed to change event information?
Write-up and discussion (combined)
Can filter callback functions or event listener callback functions change the event? Howard presented three options:
- Filters and callbacks should consider the name and message to be READ-ONLY and must never modify them.
- Filters and callbacks should consider the name and message to be MUTABLE, but you should be aware that if there are several subscribers to a name, then if one filter or callback modifies the message, then all subsequently invoked callbacks MAY OR MAY NOT be given the modified version rather than the original (i.e. side effects may exist between subscribers in some implementations).
- Filters should consider name and message to be MUTABLE, and the hub implementation MUST ensure that if the filter for subscriber N modifies the message/name, then subscribers N+1,... see the original message/name and not the modification.
Howard votes for #1. Bertrand pointed out (and Howard agrees) the possible need for cancelling events (which is Issue #9), but agrees that subscribers should never rely on side effects caused by other subscribers. Also, the publisher should never rely on side effects caused by subscribers. Thus, it seems that the only case in which anyone can count on updates to the message is the case in which a filter modifies the message before handing it on to the corresponding handler callback. But if a filter modifies a message, then other subscribers may or may not be affected; the behavior is unspecified.
But even if we agree on #1, the question is whether we simply trust that subscriber callbacks would follow our guidelines to not change the event information or whether we need to bulletproof the Hub somehow.
Howard adds: I don't believe we can bulletproof the hub in its current implementations without greatly impacting performance and code size, and even then it is possible to break it. I don't want to bloat the hub or slow it down, and since the current OAH code currently in SVN doesn't try to be bulletproof in many more obvious and critical ways (e.g. someone removed all function parameter checking), I hoped to "legislate" the requirement in the standard rather than modify code. Add language like: "application code that is compliant with this API shall behave so and so". The failure of application code to adhere to this requirement would therefore make that app code incompatible with the OAH API spec, and it would thus be up to the application developer to correct that defect just as s/he would any other defect. Comments welcome :-)
Bertrand says: ...the consensus could probably be to issue guidelines and keep open the possibility of mutability as there are scenarios for it. If the payload is a plain JavaScript object it can't technically be made immutable anyway.
Proposed resolution
Payload is mutable but issue guidelines. (Rationale: cannot bulletproof without greatly impacting performance and code size)
Email comments 5/15 and 5/16
- Howard: I agree with using guidelines.
- James: Guidelines are the way to go.
- Bruce: strong agreement with the proposed resolution (vs. trying to actually fake immutability)
Resolution and Rationale
During the 16May2007 telecon, we approved the proposed resolution. See above for rationale. We need to work on the exact wording in the spec to express something to the effect that payloads need to be treated as read-only because publishers will expect that each subscriber will receive the same original payload, with the exception that in some cases a publisher might document particular parts of the payload as being mutable, such as a flag variable within the payload that might be used by the publisher to cancel execution of an event's default action.
Issue 7: Should the Hub's own events be "org.openajax.foo" or "org.openajax.hub.foo"?
Original write-up
Alex's oaa2.js implementation broadcasts "/OpenAjax/onload", "/OpenAjax/onunload", "/OpenAjax/registerLibary", and "/OpenAjax/unregisterLibrary". Should we insert the string "hub." into our event names, as in "org.openajax.hub.registerLibary"? Second issue: would it be "Hub" or "hub"? (Note: as of 2007-05-07, the open source project is using names such as "org.openajax.hub.registerLibary", but the open source project will change to reflect our decision here.)
Subsequent discussion
- Howard: Suggestion: use org.openajax.hub.foo for most hub functionality. Rationale: There are other groups that work in parallel within the OAA. It is much better to allow the different projects to work in parallel without forcing someone to keep an eye out for name collisions. Probably best to set a good example.
- Bertrand: yes, adding ".hub." makes the teams less likely to interfere with each other
- James: In my ideal world your API prefix, your toolkit prefix/identifier and your message prefix are all the same. So they are either all "OpenAjax." or they are all "org.openajax." These are all subject to the same ambiguity issues and having users remember three different but related identifiers could be very annoying. When do I use the library prefix, when do I use the API prefix and when do I use the messaging prefix, and how are these related?
Remembering that they are all exactly the same is certainly a lot easier.
If I'm using dojo expecting an event named "org.dojo.widget.childAdded" is fairly odd considering that dojo APIs are all scoped to the dojo object and not to the org.dojo object. - Jon: (Not expressed in any emails) I agree Howard's arguments above and believe it should be (for example) "org.openajax.hub.registerLibrary".
Related sub-issue brought up by James' comment
- Should we attempt to maintain parallelism between APIs and events? For example, should it be
org.openajax.hub.registerLibrary()? Or maybeOpenAjax.hub.registerLibrary()?
Proposed resolution
- The Hub's own events include the string ".hub", such as "org.openajax.hub.registerLibrary".
- OpenAjax might define different technologies in the future beyond the Hub, and ".hub" is only 4 characters, so let's put all of the Hub's APIs on
OpenAjax.hub(e.g.,OpenAjax.hub.subscribe()) instead of justOpenAjax(e.g.,OpenAjax.subscribe()).
Email comments 5/15 and 5/16
- Howard: I agree with the proposed resolutions.
- James: Still a bit odd to me that the api would be "OpenAjax.hub.*" and the event name would be "org.openajax.hub.*" However "throw an org in front of it to get the event name" is better than "the event and API names are loosely unrelated in an undefined fashion."
- Bruce: (no comment implies agreement)
Resolution and Rationale
During the 16May2007 telecon, we approved the proposed resolutions. We felt that it was important to segment both the topic names and the Hub's APIs into a "hub" area to take into account future modules that might be developed within the Alliance. The one caveat on this was that there is a small chance that we might discover implementation complexities. If any arise, then they would be presented to the group.
Issue 6: Are events specified by a pair {prefix,EventName} or just by an EventName
Original write-up
The version of the Hub used in the InteropFest identified events by two values, a prefix (e.g., "OpenAjax") and an event name (e.g., "registerLibrary"), which thus represents a pair {"OpenAjax","registerLibrary"). Much of the recent email about the pub/sub feature shows examples where only a single string defines the event, as in "/OpenAjax/registerLibrary" or "com.microsoft.chatroom.MyRoom.alerts.friendEntered". (Note: as of 2007-05-07, the open source project only uses EventName, not {prefix,EventName}, but the open source project will change to reflect our decision here.)
Subsequent discussion
- Howard: Suggestion: Let's eliminate the prefix in the pub-sub context. Rationale: No longer any need for it.
- Bertrand: the prefix does seem redundant
Proposed resolution
Don't use prefixes in the pub/sub APIs.
Email comments 5/15 and 5/16
- Howard: I agree with the proposal to drop the prefix.
- James: Proposed resolution fine.
- Bruce: (no comment implies agreement)
Resolution and Rationale
During the 16May2007 telecon, we approved the proposed resolutions. Everyone believed that the prefixes were no longer needed or used.
Issue 5: Event versioning
Suppose Yahoo Finance gets on the OpenAjax bandwagon, defines a standard client-side control for communicating with the Yahoo server, and defines some client-side events which are published to the Hub. Now further suppose that the next release of this client-side control comes out and the client-side events have a revised payload. Logic that supported the old definition for the given event might break if the new version of the control is used.
Should events be required to specify versioning information? Should the event names include version information in the event name? (Jon recommended against this latter approach in the email archives.) Or should we instead simply define some vague, hand-waving best practices that tell developers that they need to take versioning into account?
Some options that come to mind:
- The event name includes versioning information (e.g., /OpenAjax/registerLibrary/1.0)
- Versioning information must be provided as a parameter OpenAjax.publish() (e.g., OpenAjax.publish("MyEventName", "1.0", event_payload))
- We encourage event designers to include a version parameter within the event's payload
Most likely, there are some best practices around event versioning that we will need to define. (This issue focuses on events, but versioning issues probably apply to all aspects of Ajax-related APIs.)
Resolution: At the April 25, 2007 phone call, we decided to go with an approach that is in the general area of option #3 (i.e., version info, if present, is into the payload). There are still details to be worked out. We are thinking that we would lead by example and define our own events to demonstrate best practices, but after seeing how our events are defined, we might also promote our approaches into official best practices. We might explicitly define a best practice that says not to put version info into the event name. We agreed that we need to explore best practices about event construction which emphasize the importance of specification published events completely and ensuring backwards compatibility so that applications which are programmed for version 1.0 of an event will continue to work if they use an updated toolkit that is publishing version 1.1 for the event.
Rationale: People didn't like the idea of coupling the version info with the event name. Some people felt that version information is not required in all cases, so the best approach is to make the version information an optional part of the payload.
Issue 4: What's our recommended best practices and/or standards around how to name events
Here are some alternatives that have been proposed. Note that these alternatives are not necessarily mutually exclusive:
- Java style (e.g., org.openajax.registerLibrary)
- OpenAjax Registry prefix (e.g., /OpenAjax/registerLibrary)
- URIs (e.g., http://openajax.org/registerLibrary or urn:openajax:registerLibrary)
- W3C-style namespace prefixing (e.g., OpenAjax:registerLibrary)
- Any arbitrary string
There appears to be consensus that we want to achieve the following:
- Reasonable understandability, ease of use and compactness, particularly for standard event names defined by OpenAjax Alliance (e.g., /OpenAjax/onload is better than /channels/public/org.openajax/initevents/onload)
- Provide a robust mechanism to avoid event name collisions, probably by leveraging a unique id mechanism (such as internet domains)
- Provide a convenient mechanism for toolkit and application developers to define their own events without having to deal with the OpenAjax Registry
One option to consider to achieve the compactness objective is to have a leading "/" (or other character) as a special indicator to say that the next token represents a prefix defined within the OpenAjax Registry. For example, for the event "/OpenAjax/foo", the leading "/" would indicate that the "OpenAjax" prefix is in the Registry.
A wiki page that shows example event names is at Event Name Examples.
Resolution: At the April 25, 2007 phone call, we decided to only support reverse domain notation using periods as separators (e.g., org.openajax.hub.registerLibrary) and to not support an option that uses toolkit prefixes (registered with the OpenAjax Registry).
Rationale: We felt it was a service to the world to simplify and choose only a single mechanism and only a single option (thus, no prefix support), where the simplicity benefit from a single approach outweighed the compactness benefit from supporting toolkit prefixes. (Also, there was concern about the Registry, which hasn't been defined yet. Would it ever see the light of day and if so whether toolkit prefixes would be part of the Registry.) We felt that it was good to reuse mechanisms that already have adoption and track record elsewhere (i.e., reverse domain notation). We felt it was good to leverage the robustness of the unique ID system due to IANA domain registration that we get from reverse domain notation.
Issue 3: What to do about the 'load' event and initialization management
At our March 2007 face-to-face meeting, we agreed that the Hub would publish an event (such as /OpenAjax/onload) to which toolkits could subscribe. This event tells the toolkits that the Hub's 'load' event handler registered on the BODY element has been invoked.
There has been a question raised about whether this approach will prove useful to the community. Here is an alternate approach that has been proposed:
- Library A calls OpenAjax.registerForLibraryReady(“LibraryA”);
- OpenAjax hub subscribes to the /LibraryA/LibraryReady event as a consequence of the library registering
- Library B calls OpenAjax.registerForLibraryReady(“LibraryB”);
- OpenAjax hub subscribes to the /LibraryB/LibraryReady event as a consequence of the library registering
- Application bootstrapping code subscribes to /OpenAjax/LibrariesReady
- Library A finishes its own bootstrapping and calls OpenAjax.publish with /LibraryA/LibraryReady
- OpenAjax hub unsubscribes to /LibraryA/LibraryReady
- There is still one library in the queue, OpenAjax does nothing yet
- Library B finishes its own bootstrapping and calls OpenAjax.publish with /LibraryB/LibraryReady
- OpenAjax sees that all libraries that registered for library ready sent their message. It publishes /OpenAjax/LibrariesReady
- Application does its stuff.
There is only one additional API here, registerForLibraryReady, and libraries can choose to participate or not.
Resolution: At the April 25, 2007 phone call, we decided to postpone any features in this area out of Hub 1.0.
Rationale: It is clear that we aren't smart enough yet about how to design a useful feature in this area. Instead, for Hub 1.1, we will ask toolkits to post short descriptions of how they initialize and determine if we can define a useful mechanism that fits in with how the various toolkits work.
Issue 2: Pub/sub support for hierarchical event names and wildcards
The current open source reference implementation (i.e., the one used for the InteropFest) supported a "*" wildcard for the prefix or the event name. We didn't say whether there was an official separator character within the event name (aaa/bbb/ccc or aaa.bbb.ccc) and therefore the InteropFest's implementation does not support wildcards at the token level.
The questions are:
- whether the Hub should specify an official separator character, such as "/" or "."
- whether the Hub should offer built-in support for wildcards ("*" and maybe "**") at the token level, such as /OpenAjax/* or /*/OpenAjax or com.yahoo.finance.*.bid
Here are some alternatives:
- No wildcard support (this means taking away the limited wildcard support that was available in the InteropFest distribution)
- Support only the "*" wildcard relative to the entire event name (which pretty much matches what we did in the InteropFest distribution)
- Continue to allow restricted wildcard support, but offer a small amount of additional flexibility versus the previous entry, such as allowing "*" or "**" at the end of the event name to which the subscriber wants to listen
- Allow the "*" wildcard for any of the tokens
Notes:
- The filter mechanism within the pub/sub feature allows an application developer or toolkit developer to implement his own tokenization and wildcard logic.
- JavaScript offers a built-in regular expression facility for pattern matching.
- TIBCO contributed an implemntation (adding about 1K to the 1.5K of the basic OAA Hub) supporting (based on hash tables) use of multiple wildcards that's demonstrably fast (does not diminish performance of the hub) and is probably faster than relying on the slower logic inherent in filters and probably faster than relying on regular expressions -- though there's been no head to head comparison since no implmentations of the alternative approaches have been provided.
There are many emails in the archives on this subject. A wiki page that shows example event names is at Event Name Examples.
Resolution: Accept alternative #4, in particular allow subscription using "*" wildcard for any of the tokens and "**" at the end of any intermediate event name. (Resolved at April 25, 2007 phone call)
Rationale: People agreed with Howard's arguments outlining the benefits from allowing this wildcarding flexibility and people agreed that Howard's implementation was small enough and fast enough.
Issue 1: Cut back on features for Hub 1.0
Proposal: Reduce the feature set for Hub 1.0
- Modules to keep: library registration, publish/subscribe topic management
- Modules to postpone: markup scanner, globals management, load/unload management
- Load/unload manifests itself as events published by the Hub to which toolkits can subscribe if they are interested
Originally discussed at the March 7, 2007 phone call:
At which point there was a tentative agreement to accept the feature cutback proposals from Jon and Alex. We resolved the issue and approved the cutback proposals at the March F2F meeting:
Resolution: Accept proposal to cut back feature set in Hub 1.0 to library management, event bus, new approach to load/unload events via broadcasting events vis event bus, postpone/drop markup scanner, postpone/drop globals. Ship Hub 1.0 only after it is right with sufficient involvement outside the team, but as quickly as possible under those constraints.
Rationale: Lots of reasons behind this decision. People felt that the markup scanner's approach of doing a top/down traversal of the entire DOM did not match the needs of many scenarios and that the industry was concluding that such an approach was not performant. Furthermore, the markup scanner was very large (about half of the JavaScript in the Hub) and it turned out that none of the 12 toolkits that participated in the InteropFest used the markup scanner. Regarding globals, there was considerable debate where some people felt that we needed to establish habits around identifying globals, but the winning arguments were that we weren't sure we had the right approach and should wait for more progress on the OpenAjax Registry, plus the fact that globals collision checking might be better as a design-time or debug-time feature and not a good thing to force into the standard Hub which will downloaded billions of time per (name your time period). Regarding the load/unload manager, we discovered that many toolkits do not initialize in response to document.load. This is too early for some toolkits (e.g., TIBCO) and too late for others (e.g., JQuery). Furthermore, we concluded that the industry could avoid stepping on each other's load handlers (and in fact most toolkits already do this) if we could define some best practices and evangelize them to the industry.
