The CometD Project is happy to announce the availability of CometD 4.0.0.
CometD 4.0.0 builds on top of the CometD 3.1.x series, bringing improvements and new features.
You can find a migration guide at the official CometD documentation site.
What’s new in CometD 4.0.0
The main theme behind CometD 4.0.x is the complete support for asynchronous APIs.
CometD 3.1.x had a number of APIs, in particular server-side extensions and server-side channel listeners that required to return a value from API methods that applications implemented.
A typical example is the support for authentication during a CometD handshake: applications needed to implement SecurityPolicy.canHandshake(...)
:
// CometD 3.1.x public class MyAppAuthenticator extends DefaultSecurityPolicy { @Override public boolean canHandshake(BayeuxServer server, ServerSession session, ServerMessage message) { // Call third party service via HTTP. CompletableFuture future = thirdParty.authenticate(message); return future.get(); // Blocks until the result is available. } }
Because canHandshake(...)
returns a boolean
, authentication using a third party service via HTTP must block (via CompletableFuture.get()
) until the third party service returned a response. Furthermore, it was not possible to call the third party service in a different thread, freeing the CometD thread and allowing it to handle other messages: the CometD thread still had to be blocked until a boolean
response was available. This was severely harming the scalability of CometD if hundreds of threads were blocked waiting for a slow third party authentication system, and it was only due to a CometD API design mistake.
With CometD 4.0.x we took the chance to correct this design mistake and make all CometD APIs completely asynchronous, with the introduction of a CometD Promise
class: a callback that holds a future result or that is failed.
The example above can now be written as:
// CometD 4.0.x public class MyAppAuthenticator extends DefaultSecurityPolicy { @Override public void canHandshake(BayeuxServer server, ServerSession session, ServerMessage message, Promise promise) { // Call third party service via HTTP. CompletableFuture future = thirdParty.authenticate(message); future.whenComplete((result, failure) -> { if (failure == null) { promise.succeed(result); } else { promise.fail(failure); } }); } }
Method canHandshake(...)
can now return immediately and handle other messages; when the CompletableFuture
returned by the third party authentication system is completed (i.e. succeeded or failed), then also the CometD Promise
is completed and the processing of that CometD message can continue.
This apparently simple API change required a massive rewrite of the internals of CometD and few other breaking API changes, in particular, they related to how to obtain a BayeuxContext
instance. In CometD 3.1.x, BayeuxContext
instances could be retrieved via BayeuxServer.getContext()
thanks to the fact that the BayeuxContext
instance was stored in a ThreadLocal
. In CometD 4.0.x, it is not possible to use ThreadLocal
due to the asynchronous nature of the API: the thread that starts an asynchronous operation is not the same thread that finishes the asynchronous operation. In CometD 4.0.x, you can now obtain a BayeuxContext
instance via ServerMessage.getBayeuxContext()
.
A complete list of breaking and removed API can be found in the migration guide.
Another new feature of CometD 4.0.x is the support for JPMS modules. Currently, this is achieved by adding Automatic-Module-Name
entries to the relevant CometD jars. Proper support for JPMS modules via module-info.java
files is scheduled for CometD 5.x.
What’s changed in CometD 4.0.0
CometD 4.0.x now requires JDK 8 and Jetty 9.4.x as detailed in the migration guide.
Conclusions
CometD 4.0.x is now the mainstream CometD release, and will be the primary focus for development and bug fixes. CometD 3.1.x enters a maintenance mode, so that only urgent or sponsored fixes will be applied to it, possibly leading to new CometD 3.1.x releases – although these will be rare.
Work on CometD 5.x will likely require JDK 11 and Jetty 10 and will start as soon as Jetty 10 is released.
0 Comments