The module classloader hierarchy has historically been a source of
complexity and confusion. Removing the classloader hierarchy will mean
that Vert.x applications will run using a simple flat classpath. This
should dramatically simply running, debugging, embedding and sharing
classes between different parts of an application.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
This means the component simply needs to provide a simple rich interface
in Java, and Vert.x will handle creating idiomatic APIs in each language
which can be used remotely from anywhere on the network to access the
component. It should be possible for this to work from client side JS
too, so basically any Vert.x component API would be automatically usable
from there too (subject to security constraints).
Another advantage of this is you won't have to worry about encoding and
decoding stuff manually in JSON in order to send/receive it from a
component.
5) Promises/Future/Rx support
We can use our magical API generator to take any core API and create a
wrapper that exposes the API in terms of RxJava observables or Java 8
CompletableFutures instead.
6) No differentiation between "core" and "platform".
Most of the platform stuff in Vert.x is related to implementing the
module system. If the module system disappears then we basically just
have core and a few methods for deploying/undeploying verticles. All of
these methods can be rolled into the core API.
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
While we can still support the "vertx" command, many Vert.x applications
will be simple Java programs that can be run directly with 'java', e.g.
public class MyVerticle implements Verticle {
public void start() {
System.out.println("My verticle is starting");
vertx.createHttpServer().requestHandler(...).listen(8080);
}
public static void main(String[] args) {
Vertx vertx = VertxFactory.newVertx();
vertx.deployVerticle(new MyVerticle());
}
}
java org.foo.MyVerticle -cp ...
Note that we will allow deployVerticle to take an actual Verticle
*instance* as well as the Verticle *class* which is currently supported.
This will allow verticles to be injected by DI frameworks more easily.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
This means the component simply needs to provide a simple rich interface
in Java, and Vert.x will handle creating idiomatic APIs in each language
which can be used remotely from anywhere on the network to access the
component. It should be possible for this to work from client side JS
too, so basically any Vert.x component API would be automatically usable
from there too (subject to security constraints).
Another advantage of this is you won't have to worry about encoding and
decoding stuff manually in JSON in order to send/receive it from a
component.
5) Promises/Future/Rx support
We can use our magical API generator to take any core API and create a
wrapper that exposes the API in terms of RxJava observables or Java 8
CompletableFutures instead.
Another purpose of the Vert.x module system is to provide isolation of
module classes. This allows different modules to use different versions
of the same jars at the same time in the same JVM instance. This is a
nice feature, but in practice is it really worth it? Especially if we
resolve all dependencies at build time, Maven will catch any such clashes.
The module classloader hierarchy has historically been a source of
complexity and confusion. Removing the classloader hierarchy will mean
that Vert.x applications will run using a simple flat classpath. This
should dramatically simply running, debugging, embedding and sharing
classes between different parts of an application.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
3) Automatic generation of other language APIs
This means the component simply needs to provide a simple rich interface
in Java, and Vert.x will handle creating idiomatic APIs in each language
which can be used remotely from anywhere on the network to access the
component. It should be possible for this to work from client side JS
too, so basically any Vert.x component API would be automatically usable
from there too (subject to security constraints).
Another advantage of this is you won't have to worry about encoding and
decoding stuff manually in JSON in order to send/receive it from a
component.
5) Promises/Future/Rx support
We can use our magical API generator to take any core API and create a
wrapper that exposes the API in terms of RxJava observables or Java 8
CompletableFutures instead.
6) No differentiation between "core" and "platform".
Most of the platform stuff in Vert.x is related to implementing the
module system. If the module system disappears then we basically just
have core and a few methods for deploying/undeploying verticles. All of
these methods can be rolled into the core API.
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
While we can still support the "vertx" command, many Vert.x applications
will be simple Java programs that can be run directly with 'java', e.g.
public class MyVerticle implements Verticle {
public void start() {
System.out.println("My verticle is starting");
vertx.createHttpServer().requestHandler(...).listen(8080);
}
public static void main(String[] args) {
Vertx vertx = VertxFactory.newVertx();
vertx.deployVerticle(new MyVerticle());
}
}
java org.foo.MyVerticle -cp ...
Note that we will allow deployVerticle to take an actual Verticle
*instance* as well as the Verticle *class* which is currently supported.
This will allow verticles to be injected by DI frameworks more easily.
--
On Apr 13, 2014 9:45 AM, "Tim Fox" <timv...@gmail.com> wrote:
> instead of
>
> httpServer.connectHandler(handler);
>
> we do
>
> httpServer.on("connect", handler);
I like that the compiler catches typos in the first (current) version.
> 8) Java 8 only
+1
Frank.
+1 to what Paulo writes below.
Frank.
1) Massively simplify the module system.
2) Refactoring of the core interfaces.
3) Automatic generation of other language APIs
4) Automatic generation of location transparent proxies for services
5) Promises/Future/Rx support
6) No differentiation between "core" and "platform".
7) Reification of different dispatchers
8) Java 8 only
Nice and interesting features to have, except no. 2. Remembering the name would be a pain and would almost become impossible for a big project.No. 1 is the most simple and powerful feature. It will help to avoid lot many confusions as normal java developers are accustomed with a single classloader normally. It will also attract more use of DI frameworks like Spring. It will help debugging a lot.
No. 7 is also powerful. It will provide the developers with a great amount of control over execution.One more idea to improve vertx experience, is to prefer java objects to pass as a message over Json by default. I mean json should be there under the hood, but automatic marshalling and unmarshalling should abstract it away, because java has very poor language support for json unlike javascript. It would be a lot easier that way to write code for vertx in java . Same thing can be done for other languages as well where there is poor native json support.
Introducing message interceptor api would be a great feature to have. Just some interfaces; user will implement their own custom interceptors based on their need.
Our current vertx-based internal project is structured as 10+ vertx modules (plus third-party deps like yoke). It's not the end of the world if it is dropped (even leaving aside the "don't upgrade to vertx 3" option), but I imagine it would probably go something like "hello, osgi. <sigh...>" and a sweeping restructuring, rather than "yay let's juggle classpaths like it's 1999".
1) Massively simplify the module system.
Even though I’m one of those who struggled (struggles) with the class loader / isolation early on I’d still be worried that you’re throwing out the proverbial baby here. The threading model of VertX works in part because a lot of the common ways to subvert it are prevented by the class loader design. Using a traditional shared classloadeder may quickly introduce a lot of equally problematic thread-safety issues.
That said, I do think there’s a lot that could be done to assist debugging issues with class-loaders and conflict resolution.
2) Refactoring of the core interfaces.
I prefer strongly typed interfaces, unless the type of every handler is the same you’ll end with more run-time type conflicts on Handler parameters which are easy to create / hard to debug.
3) Automatic generation of other language APIs
Only concern is the combinatorial explosion if you have other wrappers / non-runnable jars / frameworks. RxJava does this but each API shim has the same classname so you are limited to one lang per class loader (module class loader could help here). This is a little bit more restrictive but makes writing utility code possible with needing to use messy inheritance (where every lang inherits from java e.g.)
4) Automatic generation of location transparent proxies for services
For general module interop there’s lots of existing libs for this already (protocol buffers, thrift, bson, ObjectMapper etc etc) not sure the core needs to introduce a new one. It would be good if the EventBus allowed modules to provide their own encoded message (e.g. json/bson etc) that could be read by other lang modules without them needing a custom codec though.
I do think there is a problem with drivers for third-party services (esp. databases with complex formats) but I’m personally averse to generated stubs as they tend to promote breaking the wire protocol (because its too easy to make inadvertent breaking changes) and create more scope for compatibility conflicts between modules that use the same persistor.
It also maintains the double indirection where the DB module inevitably has to decode the message and re-encode using the DB native protocol using its own client lib. This leads to problems with loss of data typing or structure (issues around dates etc). If the app itself uses Bson on the network then you can have a chain of lossy transformations (network bson -> vertx api -> (event bus) vertx encoding -> (persister) vertx pojo -> db encoding) when it fact the original object could most likely be encapsulated directly into the DB request (subject to suitable schema validation).
As Joern says encouraging an async driver model (esp those written on netty) to separate protocol encoding from the network transport so they could be used independently would provide a lot of potential benefits. Developers can use the native async drivers (with proper typing) but the underlying networking would use VertX scheduler to ensure the threading model is maintained. Obviously its non-trivial to implement but it would be effort shared across all async platforms so more likely to gain support from the DB Vendors / Contributors?
5) Promises/Future/Rx support
Sounds great to me! Obviously the way RxJava does code-gen would become a factor (language class loader isolation etc). There is a whole other set of issues with Future/Promises libs that do their own internal threading that could benefit from platform support. Currently grappling with this for rxvertx.
7) Reification of different dispatchers
Having to size/configure thread pools is one of the problems I was hoping to avoid with an async platform :-)
The module system is one of the things that attracted me to Vertx. That said I don't use it at all except as a sort of single war file type thingy.I just use Verticles.
I like the idea of embracing maven/gradle instead of modules. We still need fat jars. We still need jars that have jars. Don't we?
So at least for the java case we need something like a war file and so far you have been calling that a module. :)
So it seems to me for Java you need something like a module. Nasty classloader junk...
I guess I can just start only using fatJars. :) Wait... you will still have fatJars right?
Other potential issue is "native bindings", for example in Yoke I support JS but I don't code most of the stuff in JS but in Java where I create native Rhino objects for better performance and better integration with the API how does one package such module?
1) Massively simplify the module system.
If this means that we are forced to have a Java database connector, a JS database connector, a Ruby database connector, a Scala database connector, a Python/PHP/yeti/whatever database connector... I won't sign this.
I like to write modules in a non-Java language where I most probably don't have a code generator for other languages. Do I need to update/recompile the module with every single Vert.x update then, so it stays compatible? Maybe the simplified API you propose will simplify this, but I'm not 100% sure about the implications. To get rid of mod.json and all of that would be great, but using the Gradle/Maven template is not too bad either (even though it changes too often ;)).
What will happen if you have one module using Scala for Vert.x 3.0 and another module using Scala for Vert.x 3.1 - if these are incompatible, you won't be able to use them together?
We can something like this with the current module system, can't we?
Generally about the module system: NodeJS is split into two parts: node and npm. node runs all the things and npm tackles the module system around it. There is a lot of stuff that npm does, what vertx doesn't right now. For example when installing modules, it can add this as a dependency into your package.json (the mod.json equivalent). It will also grab and install this into a sub-directory called node_modules/<module_name> where it stores the modules own dependencies again, effectively creating the ClassLoader we should have in Vert.x right now: Every module has its own classes/dependencies and doesn't need to rely on others.
I don't really see the need for Maven or Gradle when the code is structured like this, you could just copy the whole directory and run it like a "vertx fatjar". Yes, this means it results in modules that may have the same dependency included multiple times and there is probably a lot of room for improvement. But it works quite well and is much easier to understand.
Maybe it would be easier for Vert.x to go a similar route and provide a CLI that you can use to download libraries from maven into your module, add other modules as dependencies into mod.json, etc.
2) Refactoring of the core interfaces.
I consider the IDE problem a valid one, but I think using strings here is especially cool if you want to be able to add custom events. Using strings would help here a quite a bit as it lets us reuse a lot of error handling code for example. So +1 on the string proposal, even though I'm an IDE user, too.
3) Automatic generation of other language APIs
Sounds great - not sure whether this will work out well in practice, but in theory +1.
4) Automatic generation of location transparent proxies for services
So all modules need to be written in Java from now on?Or can I at least write the core functionality in Scala and provide a simple "to be translated into other languages"-Java-wrapper? If we don't kick the mod.json completely but add our API in there, this could be easier to maintain a Java wrapper for most. Something like this: https://gist.github.com/Narigo/710226847a7f2f73220d
5) Promises/Future/Rx support
At least for Scala it would be nicer to have the native Scala Future/Promise types. I'm not sure what Rx is adding if Java8 also provides Futures?The magical API generator can hopefully generate into native Future/Promise types, too? If yes, +1.
6) No differentiation between "core" and "platform".
Sounds nice, +1.
7) Reification of different dispatchers
Guess this works better for people in need, so +1. I just hope that the documentation will have a lot of information about this and how to use it, so I can understand it at some point, too. ;)
8) Java 8 only
Yes please.
One additional suggestion:Currently there are a few async drivers popping up relying on either Netty or Akka. I have to admit I really don't understand too much about the underlying threading that needs to be done there, but it would be really really great if Vert.x could somehow provide a way to use these drivers in a simple way. Right now, using Netty drivers is not really simple and modules around them need to use some implementation details that shouldn't be used directly. If Vertx could provide a VertxEventLoopGroup (or whatever Netty drivers need) and a VertxActorSystem (Akka drivers usually want an ActorSystem), so these drivers can be used with a simple event bus wrapper, this would lead to a lot of new async drivers.
I've talked with Norman about this already and for Netty, this won't work currently. He said there might be a chance to get there with Netty 4.1, but he wasn't sure about this. It would be nice to have this on the radar as we could have access to a lot of real async drivers then. Most of the currently available modules really are worker modules or using ugly hacks to get async drivers to work (Normans suggestion for the MySQL/PostgreSQL module is to create a single threaded NioEventLoopGroup now, meaning the module creates a new thread for each instance of it). I'm actually not aware of any 100% async driver written in Vert.x yet...?
In practice though, how many people really do that. IMHO we're adding a lot of pain for a feature that is rarely used.On 14/04/14 23:41, Joern Bernhardt wrote:
What will happen if you have one module using Scala for Vert.x 3.0 and another module using Scala for Vert.x 3.1 - if these are incompatible, you won't be able to use them together?
1) Massively simplify the module system.
I'm at least a little wary of (1) anyway. The vertx platform part and its lightweight (but existent) module system were definitely a reason we went with vertx in particular. It going away is not something I anticipated (though maybe I should have given moving under the eclipse umbrella?).
Our current vertx-based internal project is structured as 10+ vertx modules (plus third-party deps like yoke). It's not the end of the world if it is dropped (even leaving aside the "don't upgrade to vertx 3" option), but I imagine it would probably go something like "hello, osgi. <sigh...>"
and a sweeping restructuring, rather than "yay let's juggle classpaths like it's 1999".
> Another purpose of the Vert.x module system is to provide isolation of module classes. This allows different modules to use different versions
> of the same jars at the same time in the same JVM instance. This is a nice feature, but in practice is it really worth it?
...erm... as it happens we specifically wanted something that worked the way vertx worked...
If the vertx-land answer became "well use eclipse virgo if you want that sort of thing" (or something, I completely stopped looking into it when we found vertx), that's the way it goes I guess, just saying the vertx platform with its module system was a positive for us that just worked, certainly not something we were fighting with particularly.
> I'm therefore proposing that instead of forcing a "one size fits-all" module on Vert.x users, that we drop the idea of a module (i.e. a module zip containing a mod.json)
> altogether and simply embrace whatever module system is in common use by the relevant community.
Hmm. I'm not sure about this either. I was up until now regarding vertx modules as a vertx platform feature, with the language-level stuff like pip (python) or npm (javascript) at a "different level" altogether (except in the case of java itself, sortof, though even a java module of course can have non-module deps bundled into it), with vertx quite agnostic about them.
The way I imagined it working for the python/jython case in conjunction with the existing vertx 2 way of doing things was using pip* during some part of the vertx module build - to install python deps right into the vertx module (yes, pip install takes alternate paths. it looks like npm does too). Or put another way, a vertx module would be acting a bit like a prepopulated intra-jvm python virtualenv (which is after all kinda what it is doing for us for java stuff too).
That's still not a hard argument against abandoning vertx modules as such - just replacing them with osgi bundles doing similar duty is very probably feasible, I imagine a similar strategy would work there for python/jython i.e. install the python dependencies into the bundle.
... Anyway, sorry if that seemed a bit contrary. Losing the vertx platform part and its module system for us definitely means having to replace it with something else, not nothing.
(* or currently more manually, though it looks like pip will soon properly work with jython: http://sourceforge.net/p/jython/mailman/message/32174800/ )
On 15/04/14 19:46, dgo...@squaredfinancial.com wrote:
Our current vertx-based internal project is structured as 10+ vertx modules (plus third-party deps like yoke). It's not the end of the world if it is dropped (even leaving aside the "don't upgrade to vertx 3" option), but I imagine it would probably go something like "hello, osgi. <sigh...>"
I'm not suggesting using another module system, and certainly not OSGI.
--
Hi Tim,
I use vert.x modules system to separate functionality.
No. that is why we OSGI and the rest...
If using jars, how do I undeploy a functionality from a management console.
But I still want a way to mark certain verticles as being in a group(module) and treat them as a unit.
Still on modules. If we drop the idea of module.
How does my Java vertx app deployed in maven depend on a Javascript vertx app deployed npm?
Well not quite, I can today just deploy a module by name and not bother what language it's written in or for. I can't imagine doing that across dependency managers.
S
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/nLXpM5WM9qQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
Throwing some ideas out there...
I've been thinking recently about Vert.x 3.0. One thing that has become
clear to me over the past year or so, is that we have done some things
well in Vert.x, but other things not so well. I think it's been a
learning experience and I think we should take the opportunity with
Vert.x 3.0 to improve things.
Some of the proposals I'm going to make for Vert.x 3.0 are quite
radical. But I think it's necessary that we make some big changes if
we're going to continue to gain popularity, and take Vert.x to the next
level.
So here are my *main* proposals (there are lots of other smaller bits
and pieces, but I'm going to leave those for now)
I'd like to hear your comments on this, and if you have any more
suggestions about other improvements we can make in Vert.x 3.0, please
share them :)
1) Massively simplify the module system.
One of the purposes of the Vert.x module system is to provide a
consistent way for users to encapsulate and reuse Vert.x functionality
across different languages. Another feature of the module system is to
resolve module dependencies at run-time.
I think we have learnt that in practice, Java users want to do things in
the Java way they know (i.e. put jars in Maven and resolve at build
time), JavaScript users want to do things in the server-side JavaScript
way (i.e. use npm / CommonJS modules), Ruby users want to use gems etc.
Forcing all these different users to do things in a different Vert.x way
isn't attractive to these different communities, and has caused some
confusion.
I'm therefore proposing that instead of forcing a "one size fits-all"
module on Vert.x users, that we drop the idea of a module (i.e. a module
zip containing a mod.json) altogether and simply embrace whatever module
system is in common use by the relevant community. That way users from
different language communities can do things in the way they already
know without having to understand a different module format.
For Java users that means simply creating plain jars, and putting them
in Maven. For JavaScript users, putting them in npm. For Ruby users,
putting them in rubygems. etc.
Another purpose of the Vert.x module system is to provide isolation of
module classes. This allows different modules to use different versions
of the same jars at the same time in the same JVM instance. This is a
nice feature, but in practice is it really worth it?
Especially if we
resolve all dependencies at build time, Maven will catch any such clashes.
The module classloader hierarchy has historically been a source of
complexity and confusion. Removing the classloader hierarchy will mean
that Vert.x applications will run using a simple flat classpath. This
should dramatically simply running, debugging, embedding and sharing
classes between different parts of an application.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
3) Automatic generation of other language APIs
As language module maintainers will know, one of the main pain points of
Vert.x is in keeping the other language APIs up to date.
Also, if a member of the community creates a module with a Java API,
it's a PITA to have to manually create wrappers for that API in
different languages. In many cases people don't bother, resulting in the
API being only usable in a single language.
I'm proposing that instead of manually maintaining API shims, we only
maintain the core APIs in Java and we provide a tool which generates API
shims for different languages. That way everything stays up to date with
little effort, and should be a huge win for language module maintainers.
It's not an easy task, but I believe it is possible and it means we
won't constantly be spending our time in the community with the tedious
job of keeping APIs up to date and we can spend our time on fun stuff
like innovating new functionality. We can also generate other language
API documentatiom using the same tool.
4) Automatic generation of location transparent proxies for services
Let's say we have a reusable component such as a database persistor.
Currently with Vert.x this will listen on the event bus and interact
with the rest of the world by receiving and sending messages.
However, it would be much nicer if the client could use a rich API, e.g.
api.store(object, {
// stored
})
instead of:
eventbus.send(address, storeMessage, {
// stored
}
I'm proposing that if a simple Java API is provided by the component,
that we can generate proxies that the client can use, which handle the
marshalling and marshalling of the data over the event bus automatically.
This means the component simply needs to provide a simple rich interface
in Java, and Vert.x will handle creating idiomatic APIs in each language
which can be used remotely from anywhere on the network to access the
component. It should be possible for this to work from client side JS
too, so basically any Vert.x component API would be automatically usable
from there too (subject to security constraints).
Another advantage of this is you won't have to worry about encoding and
decoding stuff manually in JSON in order to send/receive it from a
component.
5) Promises/Future/Rx support
We can use our magical API generator to take any core API and create a
wrapper that exposes the API in terms of RxJava observables or Java 8
CompletableFutures instead.
6) No differentiation between "core" and "platform".
Most of the platform stuff in Vert.x is related to implementing the
module system. If the module system disappears then we basically just
have core and a few methods for deploying/undeploying verticles. All of
these methods can be rolled into the core API.
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
While we can still support the "vertx" command, many Vert.x applications
will be simple Java programs that can be run directly with 'java', e.g.
public class MyVerticle implements Verticle {
public void start() {
System.out.println("My verticle is starting");
vertx.createHttpServer().requestHandler(...).listen(8080);
}
public static void main(String[] args) {
Vertx vertx = VertxFactory.newVertx();
vertx.deployVerticle(new MyVerticle());
}
}
java org.foo.MyVerticle -cp ...
Note that we will allow deployVerticle to take an actual Verticle
*instance* as well as the Verticle *class* which is currently supported.
This will allow verticles to be injected by DI frameworks more easily.
7) Reification of different dispatchers
Currently events in Vert.x are dispatched either on an event loop or a
worker thread depending on what type of verticle it is. It's currently a
bit clunky to configure parameters for the dispatchers, e.g. number of
threads in the pool. Also the worker pool is currently global to each
Vert.x instance.
By re-ifying the dispatchers you will be able to maintain multiple
different worker pools and configure them programmatically and also
configure event loops, e.g.
Dispatcher dispatcher = new EventLoopDispatcher(numberOfEventLoops);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
Dispatcher dispatcher = new WorkerPoolDispatcher(maxThreads, minThreads,
etc);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
you'll be able to provide your own dispatcher implementations that, say,
use a Java executor
Executor myExecutor = ...;
Dispatcher dispatcher = new ExecutorDispatcher(myExecutor);
vertx.deployVerticle(new MyVerticle(), dispatcher);
8) Java 8 only
I propose that we target Java 8 and later for Vert.x 3.0, so we have
access to all the new features (e.g. Lambas, functional stuff,
completablefuture)
Well not quite, I can today just deploy a module by name and not bother what language it's written in or for. I can't imagine doing that across dependency managers.
On 17/04/14 10:04, Mumuney Abdlquadri wrote:
But I still want a way to mark certain verticles as being in a group(module) and treat them as a unit.
Surely, jars accomplish that?
The problem is to FIND and fetch them. Starting is simple, but somebody has to do the resolution. And when you have both npm and maven how will they talk to each other to figure out where it's your module, in the java or in the javascript world?
Throwing some ideas out there...
I've been thinking recently about Vert.x 3.0. One thing that has become
clear to me over the past year or so, is that we have done some things
well in Vert.x, but other things not so well. I think it's been a
learning experience and I think we should take the opportunity with
Vert.x 3.0 to improve things.
Some of the proposals I'm going to make for Vert.x 3.0 are quite
radical. But I think it's necessary that we make some big changes if
we're going to continue to gain popularity, and take Vert.x to the next
level.
So here are my *main* proposals (there are lots of other smaller bits
and pieces, but I'm going to leave those for now)
I'd like to hear your comments on this, and if you have any more
suggestions about other improvements we can make in Vert.x 3.0, please
share them :)
1) Massively simplify the module system.
One of the purposes of the Vert.x module system is to provide a
consistent way for users to encapsulate and reuse Vert.x functionality
across different languages. Another feature of the module system is to
resolve module dependencies at run-time.
I think we have learnt that in practice, Java users want to do things in
the Java way they know (i.e. put jars in Maven and resolve at build
time), JavaScript users want to do things in the server-side JavaScript
way (i.e. use npm / CommonJS modules), Ruby users want to use gems etc.
Forcing all these different users to do things in a different Vert.x way
isn't attractive to these different communities, and has caused some
confusion.
I'm therefore proposing that instead of forcing a "one size fits-all"
module on Vert.x users, that we drop the idea of a module (i.e. a module
zip containing a mod.json) altogether and simply embrace whatever module
system is in common use by the relevant community. That way users from
different language communities can do things in the way they already
know without having to understand a different module format.
For Java users that means simply creating plain jars, and putting them
in Maven. For JavaScript users, putting them in npm. For Ruby users,
putting them in rubygems. etc.
Another purpose of the Vert.x module system is to provide isolation of
module classes. This allows different modules to use different versions
of the same jars at the same time in the same JVM instance. This is a
nice feature, but in practice is it really worth it? Especially if we
resolve all dependencies at build time, Maven will catch any such clashes.
The module classloader hierarchy has historically been a source of
complexity and confusion. Removing the classloader hierarchy will mean
that Vert.x applications will run using a simple flat classpath. This
should dramatically simply running, debugging, embedding and sharing
classes between different parts of an application.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
3) Automatic generation of other language APIs
As language module maintainers will know, one of the main pain points of
Vert.x is in keeping the other language APIs up to date.
Also, if a member of the community creates a module with a Java API,
it's a PITA to have to manually create wrappers for that API in
different languages. In many cases people don't bother, resulting in the
API being only usable in a single language.
I'm proposing that instead of manually maintaining API shims, we only
maintain the core APIs in Java and we provide a tool which generates API
shims for different languages. That way everything stays up to date with
little effort, and should be a huge win for language module maintainers.
It's not an easy task, but I believe it is possible and it means we
won't constantly be spending our time in the community with the tedious
job of keeping APIs up to date and we can spend our time on fun stuff
like innovating new functionality. We can also generate other language
API documentatiom using the same tool.
4) Automatic generation of location transparent proxies for services
Let's say we have a reusable component such as a database persistor.
Currently with Vert.x this will listen on the event bus and interact
with the rest of the world by receiving and sending messages.
However, it would be much nicer if the client could use a rich API, e.g.
api.store(object, {
// stored
})
instead of:
eventbus.send(address, storeMessage, {
// stored
}
I'm proposing that if a simple Java API is provided by the component,
that we can generate proxies that the client can use, which handle the
marshalling and marshalling of the data over the event bus automatically.
This means the component simply needs to provide a simple rich interface
in Java, and Vert.x will handle creating idiomatic APIs in each language
which can be used remotely from anywhere on the network to access the
component. It should be possible for this to work from client side JS
too, so basically any Vert.x component API would be automatically usable
from there too (subject to security constraints).
Another advantage of this is you won't have to worry about encoding and
decoding stuff manually in JSON in order to send/receive it from a
component.
5) Promises/Future/Rx support
We can use our magical API generator to take any core API and create a
wrapper that exposes the API in terms of RxJava observables or Java 8
CompletableFutures instead.
6) No differentiation between "core" and "platform".
Most of the platform stuff in Vert.x is related to implementing the
module system. If the module system disappears then we basically just
have core and a few methods for deploying/undeploying verticles. All of
these methods can be rolled into the core API.
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
While we can still support the "vertx" command, many Vert.x applications
will be simple Java programs that can be run directly with 'java', e.g.
public class MyVerticle implements Verticle {
public void start() {
System.out.println("My verticle is starting");
vertx.createHttpServer().requestHandler(...).listen(8080);
}
public static void main(String[] args) {
Vertx vertx = VertxFactory.newVertx();
vertx.deployVerticle(new MyVerticle());
}
}
java org.foo.MyVerticle -cp ...
Note that we will allow deployVerticle to take an actual Verticle
*instance* as well as the Verticle *class* which is currently supported.
This will allow verticles to be injected by DI frameworks more easily.
7) Reification of different dispatchers
Currently events in Vert.x are dispatched either on an event loop or a
worker thread depending on what type of verticle it is. It's currently a
bit clunky to configure parameters for the dispatchers, e.g. number of
threads in the pool. Also the worker pool is currently global to each
Vert.x instance.
By re-ifying the dispatchers you will be able to maintain multiple
different worker pools and configure them programmatically and also
configure event loops, e.g.
Dispatcher dispatcher = new EventLoopDispatcher(numberOfEventLoops);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
Dispatcher dispatcher = new WorkerPoolDispatcher(maxThreads, minThreads,
etc);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
you'll be able to provide your own dispatcher implementations that, say,
use a Java executor
Executor myExecutor = ...;
Dispatcher dispatcher = new ExecutorDispatcher(myExecutor);
vertx.deployVerticle(new MyVerticle(), dispatcher);
The problem is to FIND and fetch them.
Wait! I get it. So you are saying that vertx will look at the pom.xml file in META-INF of the jar files and then just download everything you need for that jar file so it will run.
So I have my nice java project using maven and I want to pull the nice database driver written in JavaScript available with npm. Using modules - straightforward. Using dependency managers, how?
Throwing some ideas out there...
1) Massively simplify the module system.
I think we have learnt that in practice, Java users want to do things in
the Java way they know (i.e. put jars in Maven and resolve at build
time), JavaScript users want to do things in the server-side JavaScript
way (i.e. use npm / CommonJS modules), Ruby users want to use gems etc.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
3) Automatic generation of other language APIs
As language module maintainers will know, one of the main pain points of
Vert.x is in keeping the other language APIs up to date.
4) Automatic generation of location transparent proxies for services
5) Promises/Future/Rx support
6) No differentiation between "core" and "platform".
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
7) Reification of different dispatchers
8) Java 8 only
So I have my nice java project using maven and I want to pull the nice database driver written in JavaScript available with npm. Using modules - straightforward. Using dependency managers, how?
On 13/04/14 23:42, Paulo Lopes wrote:In a way i do agree with this since it makes users more at home when using other languages than Java but i can also see this as a source of new problems. e.g.: I am a JS developer and have developed some module for node.js and published it on npm, if vert.x advertises that supports npm modules there is a big chance that my module does not work on vert.x because I've native code or use some V8 specific stuff that rhino/nashorm does not support and even the API is not compatible (which forces another hidden dependency in nodyn).
When I suggested NPM I didn't mean that our modules would use the node.js API, just that NPM might be a place where we could put Vert.x JS modules. I'm not sure if that will work though,
RE: No, I'm not suggesting Vert.x does any dependency management.
** Thankfully! (I orginally wrote thank God, but after reading your rants on twitter thought better of it).
RE: I'm just suggesting that dependency resolution happens at build-time not run-time using whatever tools are used as a standard in that community (e.g. Maven).
+1 +100 yes. yes. yes.
** Right. So produce a jar file. But a jar file does not run without dependencies. So... you must mean produce oneJar or some sort of fatJar. Right? jar file will not do shit.
RE: It's really not a strange proposal - I'm simply proposing that we do things in the way that 99% of apps are build anyway.
Sure it is. But strange is good. Think different. Or just.. Think. I like it.
99% of apps do not build giant jar files. 99% of java web apps build war files (ok maybe 90% but still). :) We are inherently the 1% so we are inherently strange. If you want to be bigger than 1%, we probably need a way to build a jar like thing that has all of the dependencies bundled in. You said you were going to continue to support fatJar so fatJar will get used a lot more I imagine because you need a way to bundle libs with the runnable jar.....
I am not arguing. I just want a little clarity. If you get rid of modules, we need a good no-module story, and building a jar file with maven aint it.
Vertx 2Build = build fatJar or mod-zip with maven or gradleRun = deploy mod-zip and run module or java -jar mymodule.fatjar.jar
So you are suggesting this....
Vertx 3Build = jar with maven or gradleRun = ? how do I include all of the jar files that my verticle needs?
Thanks boss. Sounds good. Sorry for the long drawn out banter. Trying to get my head around it.
No no no no no :-) my problem is when all Java developers will publish their stuff in Maven and all JS developers in npm. How on earth will I pull dependencies (jars, whatever) in my project from BOTH of these? Or is this so unlikely to happen once there's no system to rule them all?
No no no no no :-) my problem is when all Java developers will publish their stuff in Maven and all JS developers in npm. How on earth will I pull dependencies (jars, whatever) in my project from BOTH of these? Or is this so unlikely to happen once there's no system to rule them all?
I suppose you would just use Maven for the jars and npm for the JS bits. Although if you prefer to use Maven for everything I don't see why we can't support putting jars containing CommonJS modules in Maven too (although this might be weird for most JavaScript developers).
--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/nLXpM5WM9qQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
<dependencies>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<link rel='stylesheet' href='webjars/bootstrap/3.1.0/css/bootstrap.min.css'>
I am noticing something on this list.JavaScript people are speaking up so I imagine that JS is a common thing in Vertx land.Java people are speaking up.
I have not heard squat from Scala land or Jython land or Groovy land.
I am guessing that if you are in Groovy land you are in Spring land and Reactor land and Grails land, and if you are in Jython land... you are probably not.. you are probably using Python and you are using Django and Tornado.....
So am I guessing... maybe Vertx 3 really just needs to focus on Java and JavaScript. Groovy can run fine in Java land and whatever you do to for Java land also applies to Groovy and making the API nice for JS will make it nice for Java. So maybe the core should just focus on JS and Java, and let 3rd parties do the Jython and Groovy bits. Scala has AKKA, Play and Spudge (ok... I forget the actual name... but is it Spark, Spunk, Spaz, Spot, Spray, something like that)
Just a thought. I have nothing against Python (I love it), and nothing against Ruby (anymore), I love Groovy, I tolerate Scala... but maybe this Polyglot thing aint really much of a thing after all.
Have you done a recent poll of the vertx user-base?
What is the demographics for
RubyGroovyJavaJavaScriptPythonScala
Because from this email exchange it seems like...
Ruby 2%Groovy 2%Java 51%JavaScript 41%Python 2%Scala 2%
It might be good to have awesome JS and Java support, and sacrifice a little bit of polyglot-ness.
I think the 2% is being generous.
More compatibility with Node will bring you more eyeballs than Scala support and who still uses Jython (sure there are people who do, and I wrote a book on Jython so I am no Jython basher, but in the scheme of things, its days of glory never existed and are rapidly declining). Because Scala has all those things I mentioned.
If I had to pick something that would be good for the success of Vertx it would to be to really focus on JS and Java, and allow more and more Node modules to be dropped into Vertx land.
I say this with almost complete ignorance of Node. I personally detest JS. I write it under duress. But vertx is very much Java answer to Node and a damn good answer at that.....
I did mention that if you switched to Boon you would be number 1 on the JSON benchmark by 1% didn't I?
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
RE: I haven't forgotten ;) I promise I'll get around to looking at it soon (spending most of my time travelling at the moment).
I can see why people find the module system complex, but the truth is it's a lot simpler than the alternatives, and being part of the platform makes the whole infrastructure simpler. It's possible that the people using vert.x are not enterprise (because enterprise adoption lags) and this is more of an enterprisey feature.
I want to take another crack at this.Inline.
On Sunday, April 13, 2014 9:45:17 AM UTC-7, Tim Fox wrote:
Throwing some ideas out there...
I've been thinking recently about Vert.x 3.0. One thing that has become
clear to me over the past year or so, is that we have done some things
well in Vert.x, but other things not so well. I think it's been a
learning experience and I think we should take the opportunity with
Vert.x 3.0 to improve things.
Some of the proposals I'm going to make for Vert.x 3.0 are quite
radical. But I think it's necessary that we make some big changes if
we're going to continue to gain popularity, and take Vert.x to the next
level.
So here are my *main* proposals (there are lots of other smaller bits
and pieces, but I'm going to leave those for now)
I'd like to hear your comments on this, and if you have any more
suggestions about other improvements we can make in Vert.x 3.0, please
share them :)
1) Massively simplify the module system.
Not sure. We need something like a war file that has jar files, and Java code. This was the mod-zip.Since OSGi is a pretty much a complete failure, Vertx modules are attractive.In a world of micro-services, you deploy each "module" as its own micro-service.Verticals really are the important concept here, not modules.Java needs a way to ship a unit of app that includes the jar files for that app.fatJar could be that unit.If you can explain more about how you can replace this functionality.What does a vertx world look like without modules.Does this mean that vertx is just geared towards microservices?So each module just deploys its own vertx instance?You communicate by wiring up instances in the same cluster?One concern is speed. What is the cost of every call to another mirco-service if that call (and by call, I mean posting a message on the boss I suppose) has to go over the TCP/IP stack.There seems to be very little difference between UDS and TCP/IP, but mempipe seems to be 2x to 4x.The point being... the cost of micro-service vs. module is the cost of IPC.So with microservice vs. module you have an vertx instance (JVM really) per microsevice.Am I totally off base. I'd love some clarifying comments.
One of the purposes of the Vert.x module system is to provide a
consistent way for users to encapsulate and reuse Vert.x functionality
across different languages. Another feature of the module system is to
resolve module dependencies at run-time.
I think we have learnt that in practice, Java users want to do things in
the Java way they know (i.e. put jars in Maven and resolve at build
time), JavaScript users want to do things in the server-side JavaScript
way (i.e. use npm / CommonJS modules), Ruby users want to use gems etc.
Forcing all these different users to do things in a different Vert.x way
isn't attractive to these different communities, and has caused some
confusion.
I'm therefore proposing that instead of forcing a "one size fits-all"
module on Vert.x users, that we drop the idea of a module (i.e. a module
zip containing a mod.json) altogether and simply embrace whatever module
system is in common use by the relevant community. That way users from
different language communities can do things in the way they already
know without having to understand a different module format.
For Java users that means simply creating plain jars, and putting them
in Maven. For JavaScript users, putting them in npm. For Ruby users,
putting them in rubygems. etc.
Another purpose of the Vert.x module system is to provide isolation of
module classes. This allows different modules to use different versions
of the same jars at the same time in the same JVM instance. This is a
nice feature, but in practice is it really worth it?
Worth it? Can't really live without it? Are you proposing a move from modules to pure microservices?How do you get past this issue?Sorry.. I know I am being a Java grandpa here, but I don't understand.Without modules. I will need a vertx instance per service or I will need to make sure that every jar I deploy is using the same versions of gak.In most Java shops I work with... projects resemble archeology. There was this project developed six years ago that uses Spring 2.x and Hibernate 3, and now the latest versions that use Spring 11, and Hibernate 14. The reason they have war files is so they don't stomp on each other.In reality... they have war files and then each service has its own Tomcat instance so the war files are redundant.So I want to be clear... Are you proposing a microservice approach, in which case modules are redundant since each service gets its own instance anyway.(I hate the terms like microservice since it is just a term for what people mostly/actually do. But giving something a name, NoSQL, Reactive, AJAX seems to help so I will use this name with distaste).
Especially if we
resolve all dependencies at build time, Maven will catch any such clashes.
????To build what... a mod-zip? Maven builds jar files. You have maven build mod-zip. Maven can also build war files.Your comment makes sense in the mod-zip sense and in the fat jar sense, but not in the jar sense.If you don't build modules, what are you building with maven?fatjar?mod-zip?something new?
The module classloader hierarchy has historically been a source of
complexity and confusion. Removing the classloader hierarchy will mean
that Vert.x applications will run using a simple flat classpath. This
should dramatically simply running, debugging, embedding and sharing
classes between different parts of an application.
As long as it is easy to use from gradle and/or maven... I think it is already the Java way.I can't speak to other languages. Java is my home turf.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
Please no. If you have to do that.. Please at least have on take an enum or a string.httpServer.on(CONNECT, handler);
httpServer.on("connect", handler);
3) Automatic generation of other language APIs
As language module maintainers will know, one of the main pain points of
Vert.x is in keeping the other language APIs up to date.
Also, if a member of the community creates a module with a Java API,
it's a PITA to have to manually create wrappers for that API in
different languages. In many cases people don't bother, resulting in the
API being only usable in a single language.
I'm proposing that instead of manually maintaining API shims, we only
maintain the core APIs in Java and we provide a tool which generates API
shims for different languages. That way everything stays up to date with
little effort, and should be a huge win for language module maintainers.
It's not an easy task, but I believe it is possible and it means we
won't constantly be spending our time in the community with the tedious
job of keeping APIs up to date and we can spend our time on fun stuff
like innovating new functionality. We can also generate other language
API documentatiom using the same tool.
No opinion.
4) Automatic generation of location transparent proxies for services
Let's say we have a reusable component such as a database persistor.
Currently with Vert.x this will listen on the event bus and interact
with the rest of the world by receiving and sending messages.
However, it would be much nicer if the client could use a rich API, e.g.
api.store(object, {
// stored
})
instead of:
eventbus.send(address, storeMessage, {
// stored
}
I'm proposing that if a simple Java API is provided by the component,
that we can generate proxies that the client can use, which handle the
marshalling and marshalling of the data over the event bus automatically.
+1 I spent some cycles improving my JSON marshaling code yesterday.:)
This means the component simply needs to provide a simple rich interface
in Java, and Vert.x will handle creating idiomatic APIs in each language
which can be used remotely from anywhere on the network to access the
component. It should be possible for this to work from client side JS
too, so basically any Vert.x component API would be automatically usable
from there too (subject to security constraints).
Another advantage of this is you won't have to worry about encoding and
decoding stuff manually in JSON in order to send/receive it from a
component.
+1This is something I have been thinking about for years and years.
5) Promises/Future/Rx support
We can use our magical API generator to take any core API and create a
wrapper that exposes the API in terms of RxJava observables or Java 8
CompletableFutures instead.
I think you just want a subset that is RX like and then let someone else add/contribute RX modules.Vertx has to be careful not to jump the shark.RxJava is too big.Take the 20% that makes sense and leave the rest on the table. IMHO.
6) No differentiation between "core" and "platform".
Most of the platform stuff in Vert.x is related to implementing the
module system. If the module system disappears then we basically just
have core and a few methods for deploying/undeploying verticles. All of
these methods can be rolled into the core API.
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
While we can still support the "vertx" command, many Vert.x applications
will be simple Java programs that can be run directly with 'java', e.g.
public class MyVerticle implements Verticle {
public void start() {
System.out.println("My verticle is starting");
vertx.createHttpServer().requestHandler(...).listen(8080);
}
public static void main(String[] args) {
Vertx vertx = VertxFactory.newVertx();
vertx.deployVerticle(new MyVerticle());
}
}
java org.foo.MyVerticle -cp ...
Note that we will allow deployVerticle to take an actual Verticle
*instance* as well as the Verticle *class* which is currently supported.
This will allow verticles to be injected by DI frameworks more easily.
+1
7) Reification of different dispatchers
Currently events in Vert.x are dispatched either on an event loop or a
worker thread depending on what type of verticle it is. It's currently a
bit clunky to configure parameters for the dispatchers, e.g. number of
threads in the pool. Also the worker pool is currently global to each
Vert.x instance.
By re-ifying the dispatchers you will be able to maintain multiple
different worker pools and configure them programmatically and also
configure event loops, e.g.
Dispatcher dispatcher = new EventLoopDispatcher(numberOfEventLoops);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
Dispatcher dispatcher = new WorkerPoolDispatcher(maxThreads, minThreads,
etc);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
you'll be able to provide your own dispatcher implementations that, say,
use a Java executor
Executor myExecutor = ...;
Dispatcher dispatcher = new ExecutorDispatcher(myExecutor);
vertx.deployVerticle(new MyVerticle(), dispatcher);
Damn. I wish I understood what you meant.More words.This sounds pretty advanced. Hopefully there will be an easy button.The one thing I love about the vertx model is that the constructs are basic and easy.Push something here and it comes out here.
8) Java 8 only
I propose that we target Java 8 and later for Vert.x 3.0, so we have
access to all the new features (e.g. Lambas, functional stuff,
completablefuture)
And long before that we convert the examples to Java 8. :)Add some things...TOML for config.Boon for JSON parsing (or a Boon merge).As soon as you accept my pull request for Hazelcast 3.2, I am going to work on a pull request for Boon.Then after that I am going to brainstorm some ideas for marshaling.
My wish list for Vertx 3.0.
- Micro-service architecture in - modules out
- With more modules, verticles are the center of the vertx universe
- Embrace Gradle/Maven/RubyGem/NPM (actually that is not really my wish list.. the first two are... the other two are just regurgitating what Tim said)
- High-speed IPC (In a world without modules, processes need to talk to each other very quickly)
- Object marshaling between verticles and micro-services (callbacks, Reification, micro-service to address resolution)
- TOML or TONL for config https://github.com/mojombo/toml
- Embrace JDK 8 API
- RxJava support pulled into core (either 20% pareto of RxJava features or more integration)
- Ability to more easily upgrade switch clustering support (so you can have Vertx 3 but Hazelcast can be upgraded independently, this is mostly there but not quite. Vertx 2 for example could support both 2.x and 3.x Hazelcast)
On Sunday, April 13, 2014 9:45:17 AM UTC-7, Tim Fox wrote:
Throwing some ideas out there...
I've been thinking recently about Vert.x 3.0. One thing that has become
clear to me over the past year or so, is that we have done some things
well in Vert.x, but other things not so well. I think it's been a
learning experience and I think we should take the opportunity with
Vert.x 3.0 to improve things.
Some of the proposals I'm going to make for Vert.x 3.0 are quite
radical. But I think it's necessary that we make some big changes if
we're going to continue to gain popularity, and take Vert.x to the next
level.
So here are my *main* proposals (there are lots of other smaller bits
and pieces, but I'm going to leave those for now)
I'd like to hear your comments on this, and if you have any more
suggestions about other improvements we can make in Vert.x 3.0, please
share them :)
1) Massively simplify the module system.
One of the purposes of the Vert.x module system is to provide a
consistent way for users to encapsulate and reuse Vert.x functionality
across different languages. Another feature of the module system is to
resolve module dependencies at run-time.
I think we have learnt that in practice, Java users want to do things in
the Java way they know (i.e. put jars in Maven and resolve at build
time), JavaScript users want to do things in the server-side JavaScript
way (i.e. use npm / CommonJS modules), Ruby users want to use gems etc.
Forcing all these different users to do things in a different Vert.x way
isn't attractive to these different communities, and has caused some
confusion.
I'm therefore proposing that instead of forcing a "one size fits-all"
module on Vert.x users, that we drop the idea of a module (i.e. a module
zip containing a mod.json) altogether and simply embrace whatever module
system is in common use by the relevant community. That way users from
different language communities can do things in the way they already
know without having to understand a different module format.
For Java users that means simply creating plain jars, and putting them
in Maven. For JavaScript users, putting them in npm. For Ruby users,
putting them in rubygems. etc.
Another purpose of the Vert.x module system is to provide isolation of
module classes. This allows different modules to use different versions
of the same jars at the same time in the same JVM instance. This is a
nice feature, but in practice is it really worth it? Especially if we
resolve all dependencies at build time, Maven will catch any such clashes.
The module classloader hierarchy has historically been a source of
complexity and confusion. Removing the classloader hierarchy will mean
that Vert.x applications will run using a simple flat classpath. This
should dramatically simply running, debugging, embedding and sharing
classes between different parts of an application.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
3) Automatic generation of other language APIs
As language module maintainers will know, one of the main pain points of
Vert.x is in keeping the other language APIs up to date.
Also, if a member of the community creates a module with a Java API,
it's a PITA to have to manually create wrappers for that API in
different languages. In many cases people don't bother, resulting in the
API being only usable in a single language.
I'm proposing that instead of manually maintaining API shims, we only
maintain the core APIs in Java and we provide a tool which generates API
shims for different languages. That way everything stays up to date with
little effort, and should be a huge win for language module maintainers.
It's not an easy task, but I believe it is possible and it means we
won't constantly be spending our time in the community with the tedious
job of keeping APIs up to date and we can spend our time on fun stuff
like innovating new functionality. We can also generate other language
API documentatiom using the same tool.
4) Automatic generation of location transparent proxies for services
Let's say we have a reusable component such as a database persistor.
Currently with Vert.x this will listen on the event bus and interact
with the rest of the world by receiving and sending messages.
However, it would be much nicer if the client could use a rich API, e.g.
api.store(object, {
// stored
})
instead of:
eventbus.send(address, storeMessage, {
// stored
}
I'm proposing that if a simple Java API is provided by the component,
that we can generate proxies that the client can use, which handle the
marshalling and marshalling of the data over the event bus automatically.
This means the component simply needs to provide a simple rich interface
in Java, and Vert.x will handle creating idiomatic APIs in each language
which can be used remotely from anywhere on the network to access the
component. It should be possible for this to work from client side JS
too, so basically any Vert.x component API would be automatically usable
from there too (subject to security constraints).
Another advantage of this is you won't have to worry about encoding and
decoding stuff manually in JSON in order to send/receive it from a
component.
5) Promises/Future/Rx support
We can use our magical API generator to take any core API and create a
wrapper that exposes the API in terms of RxJava observables or Java 8
CompletableFutures instead.
6) No differentiation between "core" and "platform".
Most of the platform stuff in Vert.x is related to implementing the
module system. If the module system disappears then we basically just
have core and a few methods for deploying/undeploying verticles. All of
these methods can be rolled into the core API.
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
While we can still support the "vertx" command, many Vert.x applications
will be simple Java programs that can be run directly with 'java', e.g.
public class MyVerticle implements Verticle {
public void start() {
System.out.println("My verticle is starting");
vertx.createHttpServer().requestHandler(...).listen(8080);
}
public static void main(String[] args) {
Vertx vertx = VertxFactory.newVertx();
vertx.deployVerticle(new MyVerticle());
}
}
java org.foo.MyVerticle -cp ...
Note that we will allow deployVerticle to take an actual Verticle
*instance* as well as the Verticle *class* which is currently supported.
This will allow verticles to be injected by DI frameworks more easily.
7) Reification of different dispatchers
Currently events in Vert.x are dispatched either on an event loop or a
worker thread depending on what type of verticle it is. It's currently a
bit clunky to configure parameters for the dispatchers, e.g. number of
threads in the pool. Also the worker pool is currently global to each
Vert.x instance.
By re-ifying the dispatchers you will be able to maintain multiple
different worker pools and configure them programmatically and also
configure event loops, e.g.
Dispatcher dispatcher = new EventLoopDispatcher(numberOfEventLoops);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
Dispatcher dispatcher = new WorkerPoolDispatcher(maxThreads, minThreads,
etc);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
you'll be able to provide your own dispatcher implementations that, say,
use a Java executor
Executor myExecutor = ...;
Dispatcher dispatcher = new ExecutorDispatcher(myExecutor);
vertx.deployVerticle(new MyVerticle(), dispatcher);
I'm interested in understanding what feature(s) of the Vert.x module system would be missed...
I sent ages ago a pull request fixing mod-unzip but for whatever reasons didn't get through...
So Vert.x becomes less of a platform, and more of a library with a flat classpath that can be trivially embedded into any application.
--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/nLXpM5WM9qQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/nLXpM5WM9qQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hi,
I am not a regular vertx user, I just like to play with it on my free time. Haven't found a way or a place where to put it in the project where I am working on at my current job, but I hope I will soon find it :).
Anyway, here are my thoughts after my short experience until now.
1,3,4,5,6,7,8 -YES, I think this will be a great addition.2- I do not see any benefit from a java developer to do such a thing. If you really want it for easing up integration with JS or closing the gap in the api with Nodejs (why would you want that anyway?) maybe you could keep both approaches.
Also, as for module dependencies, which is the most valuable out of all these points, I would kindly suggest to take a look if you haven't already done it, to the way spring-boot has solved this problem. I was very reluctant to try spring-boot out, but after weeks of pressure from my colleagues and friends, I have finally done, and it seems like a huge step into the future of development. No more hassle with dependencies and all that configurations. Maybe that could be inspirational for the new vertx 3.0 module refactoring feature.I don't want to sound like a spring fan boy, trying to push what I like to other frameworks, but I really feel that setting up a vertx 3.0 project in the manner we could set up a spring boot project would greatly decrease the the time of development for small-medium size projects (what vertx is or could be best at) and add a breeze of fun in starting new projects in this futuristic manner.
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/nLXpM5WM9qQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Spring boot has project templates and it is similar to Roo or Forge or maven archetypes or even play or appfuse. One of its "features" is it can be run from the command line with maven or gradle so no longer will you mvn jetty:run instead you will mvn springboot:run (I kid you not). So this very new and exciting thing has been done about 100 times (I wrote several.. Presto and later Crank).In short it helps people get started.One of the "amazing" features is it supports thyme leaf instead of JSP because JSPs are "deprecated". Having used thymeleaf this makes me sad. Thymeleaf makes me want to stab myself in the eye. What a load of ....That said one thing that vertx is missing is hey mr developer here is how you use this to build a webapp or a service or a Websocket doo hickey which sort of leaves vertx out if the reach of many. Having written 30 or so tech courses over the years the mere thought of this makes me want to ... You guessed it.
--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/nLXpM5WM9qQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
The point Boot is trying to make is right there on their frontpage and applying it to vert.x...
- Create stand-alone Spring applications - Yoke is one, I'm not aware of other options
- Embed Tomcat or Jetty directly (no need to deploy WAR files) - vert.x has vert.x already
- Provide opinionated 'starter' POMs to simplify your Maven configuration - vert.x templates are rather kitchen-sink
- Automatically configure Spring whenever possible - ha.Generally speaking, to start with a new technology you need a STRONG motivation. Boot is trying to ease it for Spring. How about vert.x?
- Provide production-ready features such as metrics, health checks and externalized configuration - quite far from it
- Absolutely no code generation and no requirement for XML configuration - well the price of being opinionated...
PS: indeed, this post is not about the platform 3.0. But a better platform management interface would be very welcome (statistics, metrics without killing performance, reconfigure, remote control, restarts...)
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
On Sunday, April 13, 2014 12:45:17 PM UTC-4, Tim Fox wrote:
Throwing some ideas out there...
1) Massively simplify the module system.
Yes, this sounds like a welcome change.
I think we have learnt that in practice, Java users want to do things in
the Java way they know (i.e. put jars in Maven and resolve at build
time), JavaScript users want to do things in the server-side JavaScript
way (i.e. use npm / CommonJS modules), Ruby users want to use gems etc.
Most definitely. From the point of view of JS developers, npm is definitely the way to go. For the nodyn project I wrote dynjs-npm[0], an npm module loader that conforms to node.js' API [1]. It was written with DynJS as the target Javascript runtime, but I think it should work just fine with Nashorn and Rhino as well - as long as there is an existing require() function in the global scope - which it falls back to if nothing is found in the typical npm locations. With Nodyn, I just load the npm require() function in the global scope when a verticle starts up [2]. It should be pretty simple to adapt this or something similar to the existing JS language modules.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
Speaking as someone who writes a lot of javascript, I prefer the .on('some_event') style. The strongly typed handler API in Java bothered me a lot while I was shepherding the lang-js module. However, I can understand the Java developer's point of view regarding type checking. It's somewhat idiomatic to the language in many ways. An alternate approach may be to have untyped event handling in languages where that is the norm.
Especially if those languages can support a dynamically dispatched style. For example, the SockJS bridge hooks I implemented in lang-js for vert.x 2.1 features take advantage of Javascript's fast and loose typing to provide SockJSServer.on() already [3]. Maybe the answer is that more dynamically typed languages could be encouraged to implement the API's handler styles in ways that are more idiomatic to the language itself.
3) Automatic generation of other language APIs
As language module maintainers will know, one of the main pain points of
Vert.x is in keeping the other language APIs up to date.
Boy do we ever. :)
I think this is an ambitious goal. Especially given the other goals above. For language modules to truly reflect the coding style of a given community, they really need to be tailored to the target language's current usage idioms and styles.
I think it will be difficult to do that with a language generation tool. A generator may be good and useful for a fledgling language implementation, but I think it may not be the final step in a language module's production. If you can pull it off, though, more power to you.
4) Automatic generation of location transparent proxies for services
I don't have strong feelings on this, but it's an interesting idea. I wonder if it's maybe the first step in the creation of the code generating tool in 3). It kind of sounds like the same idea but with the initial source being 3rd party modules instead of vertx core.
5) Promises/Future/Rx support
I have reservations about the magical API generator, so not much to add here.
6) No differentiation between "core" and "platform".
Speaking from a limited point of view, this would be nice for nodyn. With vertx being an embedded component, the platform bits just kind of get in the way. I want the nodyn experience to be as much like a node.js experience as possible for the end user, and the platform tends to change all of that.
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
This is my usage scenario, so yes this would be an improvement for me. That said, I realize this isn't _everyone's_ usage scenario. I think there is a place for the vert.x platform, because not everyone is going to use its services simply as an embedded component.
I guess I'm on both sides of this debate. Personally, I don't want or need the vert.x module system in nodyn and that's a big part of why I'm keeping vertx-platform.jar out of it for the time being. That said, if the module system is gone and platform is nothing more than deploy/undeploy then maybe it makes sense to smush them together.
7) Reification of different dispatchers
I'm curious to see where you go with this. It could be a very interesting feature that may really open up potential interoperability with 3rd party libraries/systems/whathaveyou.8) Java 8 only
Yes.
And, one more thing...
9) Published system stats/usage data.
That's probably not the right title for it, but what I mean is, it would be nice to have an API that allowed me to query vertx and find out things like how many verticles are running and some information about them.
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Not sure what you mean here... Yoke is a Spring application?On 19/04/14 23:12, S C wrote:
The point Boot is trying to make is right there on their frontpage and applying it to vert.x...
- Create stand-alone Spring applications - Yoke is one, I'm not aware of other options
Can you add some more detail to this point?- Provide opinionated 'starter' POMs to simplify your Maven configuration - vert.x templates are rather kitchen-sink
Reading the above, we already have everything there other than metrics and templates could be improved (?). Is that basically what is missing?
- Automatically configure Spring whenever possible - ha.Generally speaking, to start with a new technology you need a STRONG motivation. Boot is trying to ease it for Spring. How about vert.x?
- Provide production-ready features such as metrics, health checks and externalized configuration - quite far from it
- Absolutely no code generation and no requirement for XML configuration - well the price of being opinionated...
1) Massively simplify the module system.
One of the purposes of the Vert.x module system is to provide a
consistent way for users to encapsulate and reuse Vert.x functionality
across different languages. Another feature of the module system is to
resolve module dependencies at run-time.
I think we have learnt that in practice, Java users want to do things in
the Java way they know (i.e. put jars in Maven and resolve at build
time), JavaScript users want to do things in the server-side JavaScript
way (i.e. use npm / CommonJS modules), Ruby users want to use gems etc.
Forcing all these different users to do things in a different Vert.x way
isn't attractive to these different communities, and has caused some
confusion.
I'm therefore proposing that instead of forcing a "one size fits-all"
module on Vert.x users, that we drop the idea of a module (i.e. a module
zip containing a mod.json) altogether and simply embrace whatever module
system is in common use by the relevant community. That way users from
different language communities can do things in the way they already
know without having to understand a different module format.
For Java users that means simply creating plain jars, and putting them
in Maven. For JavaScript users, putting them in npm. For Ruby users,
putting them in rubygems. etc.
Another purpose of the Vert.x module system is to provide isolation of
module classes. This allows different modules to use different versions
of the same jars at the same time in the same JVM instance. This is a
nice feature, but in practice is it really worth it? Especially if we
resolve all dependencies at build time, Maven will catch any such clashes.
The module classloader hierarchy has historically been a source of
complexity and confusion. Removing the classloader hierarchy will mean
that Vert.x applications will run using a simple flat classpath. This
should dramatically simply running, debugging, embedding and sharing
classes between different parts of an application.
2) Refactoring of the core interfaces.
This might be controversial.... Vert.x objects such as HttpServer have
different handler methods for different events, e.g. connectHandler,
webSocketHandler.
Instead of that I suggest we refactor to use something more like the
Node.js style, e.g.
instead of
httpServer.connectHandler(handler);
we do
httpServer.on("connect", handler);
This should provide a cleaner API, and allow different events to be
handled in a more consistent way.
3) Automatic generation of other language APIs
As language module maintainers will know, one of the main pain points of
Vert.x is in keeping the other language APIs up to date.
Also, if a member of the community creates a module with a Java API,
it's a PITA to have to manually create wrappers for that API in
different languages. In many cases people don't bother, resulting in the
API being only usable in a single language.
I'm proposing that instead of manually maintaining API shims, we only
maintain the core APIs in Java and we provide a tool which generates API
shims for different languages. That way everything stays up to date with
little effort, and should be a huge win for language module maintainers.
It's not an easy task, but I believe it is possible and it means we
won't constantly be spending our time in the community with the tedious
job of keeping APIs up to date and we can spend our time on fun stuff
like innovating new functionality. We can also generate other language
API documentatiom using the same tool.
4) Automatic generation of location transparent proxies for services
Let's say we have a reusable component such as a database persistor.
Currently with Vert.x this will listen on the event bus and interact
with the rest of the world by receiving and sending messages.
However, it would be much nicer if the client could use a rich API, e.g.
api.store(object, {
// stored
})
instead of:
eventbus.send(address, storeMessage, {
// stored
}
I'm proposing that if a simple Java API is provided by the component,
that we can generate proxies that the client can use, which handle the
marshalling and marshalling of the data over the event bus automatically.
This means the component simply needs to provide a simple rich interface
in Java, and Vert.x will handle creating idiomatic APIs in each language
which can be used remotely from anywhere on the network to access the
component. It should be possible for this to work from client side JS
too, so basically any Vert.x component API would be automatically usable
from there too (subject to security constraints).
Another advantage of this is you won't have to worry about encoding and
decoding stuff manually in JSON in order to send/receive it from a
component.
5) Promises/Future/Rx support
We can use our magical API generator to take any core API and create a
wrapper that exposes the API in terms of RxJava observables or Java 8
CompletableFutures instead.
6) No differentiation between "core" and "platform".
Most of the platform stuff in Vert.x is related to implementing the
module system. If the module system disappears then we basically just
have core and a few methods for deploying/undeploying verticles. All of
these methods can be rolled into the core API.
So Vert.x becomes less of a platform, and more of a library with a flat
classpath that can be trivially embedded into any application.
While we can still support the "vertx" command, many Vert.x applications
will be simple Java programs that can be run directly with 'java', e.g.
public class MyVerticle implements Verticle {
public void start() {
System.out.println("My verticle is starting");
vertx.createHttpServer().requestHandler(...).listen(8080);
}
public static void main(String[] args) {
Vertx vertx = VertxFactory.newVertx();
vertx.deployVerticle(new MyVerticle());
}
}
java org.foo.MyVerticle -cp ...
Note that we will allow deployVerticle to take an actual Verticle
*instance* as well as the Verticle *class* which is currently supported.
This will allow verticles to be injected by DI frameworks more easily.
7) Reification of different dispatchers
Currently events in Vert.x are dispatched either on an event loop or a
worker thread depending on what type of verticle it is. It's currently a
bit clunky to configure parameters for the dispatchers, e.g. number of
threads in the pool. Also the worker pool is currently global to each
Vert.x instance.
By re-ifying the dispatchers you will be able to maintain multiple
different worker pools and configure them programmatically and also
configure event loops, e.g.
Dispatcher dispatcher = new EventLoopDispatcher(numberOfEventLoops);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
Dispatcher dispatcher = new WorkerPoolDispatcher(maxThreads, minThreads,
etc);
vertx.deployVerticle(new MyVerticle(), dispatcher);
or
you'll be able to provide your own dispatcher implementations that, say,
use a Java executor
Executor myExecutor = ...;
Dispatcher dispatcher = new ExecutorDispatcher(myExecutor);
vertx.deployVerticle(new MyVerticle(), dispatcher);
8) Java 8 only
I propose that we target Java 8 and later for Vert.x 3.0, so we have
access to all the new features (e.g. Lambas, functional stuff,
completablefuture)
Another way of tackling this issue is to refactor your app into a set of loosely coupled services each running in their own JVM and talking over the event bus instead of a single blob. This should reduce the chances of any particular Vert.x instance requiring multiple versions of the same jar at the same time.
it's concise it forces you to use and build reusable modules, this could be taken further as node.js does in reducing their core by separating by moving the file system, timers, http client/server, dns client and sockets into their own modules. Even the modules or package manager could be moved out a la NPM.
It's got good performance, by reducing the core size this could be a further focus would using chronicle or LMAX disruptor for the local eventbus help, in a similar vain as Rick suggested would switching to boon or protostuff or bson help.
It's a platform, I especially like how vertigo is evolving as an equivalent to noflo.js (based on node.js) perhaps embracing Vertx as a platform more we could see our own express.js and http-proxy and passport etc...
It's polyglot, I've started using it as javascript platform that would allow me to hook into existing java libraries. And I've seen interesting work use groovy and clojure.
Over all I believe that Vertx is mature but it could grow on the community side (bigger following), refocusing on multiple package managers (maven for Java, NPM for js, leigning for clojure, gems for ruby, etc...) while logical for the developers seems at odds with creating a polyglot platform - on the other hand the zipped module is unifying for Vert.x and it really says KISS.
--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/nLXpM5WM9qQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
It's a double edged sword. Yes, having classloader isolation allows problems like this to be solved, but it also introduces other problems, e.g. in your example if you then passed different versions of the same class from one module to another you would get ClassCastExceptions.
I'd say having two versions of the same jar in an app often causes more problems than it solves.
It's a double edged sword. Yes, having classloader isolation allows problems like this to be solved, but it also introduces other problems, e.g. in your example if you then passed different versions of the same class from one module to another you would get ClassCastExceptions.
I'd say having two versions of the same jar in an app often causes more problems than it solves.
I'd say having two versions of the same jar in an app often causes more problems than it solves.