ICEpush can be configured for queued notification (this is an optional feature;
you may not need it if you know your server-side framework is thread-safe).
With queued notification on (set queued = true):
ice.push.register(pushID, callback, queued)
If you receive a notification callback, you have exclusivity: no other pending
notifications will be sent to queued=true push clients until you call
ice.push.releaseNotifications()
Also:
ice.push.lockNotifications()
ice.push.lockNotifications(callback)
Note that these may be difficult to use depending on the framework. (The internals
of this locking callback are handled for you if queued=true.)
We cannot actually block the calling thread in JavaScript, so the way to implement
this appears to be through a callback that is invoked when the lock is acquired.
This can be implemented similarly to the master election mechanism for connection
ownership, but one difference is that the notification lock is often unheld (so spin locks
on a cookie may work).
As an example of the difficulty in applying this for JSF, we would need to suspend the
XMLHttpRequest triggered by client-side event processing and resume it in a callback.
One option is to also allow the no-arg call that indicates that the caller will accept the lock
if it can be provided immediately:
ice.push.lockNotifications()
This does not protect a currently active notification, but does protect the caller
against subsequent well-behaved notifications (those using the callback).
Push-driven updates and user-driven updates in the same window will be automatically queued by JSF, the conflict occurs between push-driven or user-driven updates in distinct windows.
Another way to implement this is to provide a token-passing API that provides exclusivity to the caller.