This version (2017/05/27 13:44) is a draft.
Approvals: 0/1

[11:09:20] <aesteve> hi everyone, hi temporalfox

[11:09:28] <temporalfox> hi aesteve

[11:09:32] <temporalfox> what's up ?

[11:09:49] <aesteve> lot of things !

[11:10:01] <aesteve> but i was reading your PR re. multiple-futures

[11:10:31] <aesteve> and was wondering if there was an `all` and `any` implementation taking a list parameter

[11:10:42] <aesteve> since lists are codegen-friendly

[11:11:55] <aesteve> and also, if there was an iterator like feature involving `compose`

[11:12:09] <aesteve> basically, two things I'm writing all the time :

[11:13:11] <aesteve> “take that list of methods (which all are Handler<Future>) and execute them, no matter how, call me back when everything's done”

[11:13:23] <aesteve> and 2nd use case :

[11:13:54] <aesteve> same thing but it HAS to wait for the previous success

[11:14:31] <aesteve> First use case is `all`with a list as parameter if I'm not mistaking

[11:14:47] <aesteve> Second use case is basically a `compose`with an iterator

[11:26:57] <aesteve> also, I used “completeOrFail()” instead of “completer()” in my own implementation. Not sure it's better though

[11:29:18] <temporalfox> aesteve it's not possible to have LIst<Future<?» in codegen

[11:29:26] <temporalfox> and that's what should be used if any

[11:29:43] <temporalfox> I mean it's better to use T1 → T6 parameters

[11:29:48] <temporalfox> because we don't use generic contravariance

[11:29:57] <temporalfox> so doing something like

[11:30:08] <temporalfox> all(Future<String>, Future<Integer> etc…)

[11:30:17] <temporalfox> would make the compiler not happy

[11:30:30] <temporalfox> because a Future<String> is not a Future<Object>

[11:30:35] <temporalfox> and if we use a single T

[11:30:44] <temporalfox> you have to use the same parameter

[11:31:14] <Narigo> When I use jsonArray.remove(5) and the element at index 5 is a JsonArray, it will return a java.util.ArrayList<?> - is this expected?

[11:32:00] <temporalfox> it is because of an internal impl detail

[11:32:16] <temporalfox> when an object/array is unwrapped by jackson

[11:32:21] <temporalfox> it creates List and Map

[11:32:27] <temporalfox> and sometimes we rewrap them

[11:32:30] <aesteve> ouch ok. It could be a problem. Because often you're gonna deploy a list of verticles, maybe defined in a json file or something

[11:32:40] <aesteve> and you cannot know in advance how many there are

[11:32:46] <temporalfox> but not in the case of remove

[11:33:02] <temporalfox> ok I see aesteve

[11:33:15] <temporalfox> we could have something with a list or array

[11:33:16] <Narigo> temporalfox, shouldn't it check this and return a JsonArray / JsonObject in that case?

[11:33:26] <temporalfox> marked as @GenIgnore

[11:33:56] <temporalfox> I could try List<Future> too to see if codegen likes it or not :)

[11:33:59] <temporalfox> not sure

[11:34:08] <temporalfox> Narigo yes I think it should

[11:34:14] <aesteve> you're the expert ;)

[11:34:57] <aesteve> oh, something I noticed, too

[11:35:09] <temporalfox> I'm not a big fan of “completer”

[11:35:11] <temporalfox> too

[11:35:26] <temporalfox> orignally I wanted “handler()” butit's confusing with setHandler

[11:35:29] <temporalfox> or maybe asHandler() ?

[11:36:09] <aesteve> asHandler is good but doesn't 'tell' what it's actually gonna do

[11:36:19] <temporalfox> indeed

[11:36:24] <aesteve> (i.e. completing or failing)

[11:36:35] <temporalfox> actually failing is completing

[11:36:36] <aesteve> but re. the list, not sure you should implement it

[11:36:44] <temporalfox> it would rather be succeeding or failing

[11:37:10] <aesteve> my use case is a bit different, since I'm passing List<Handler<Future» and not List<Future>

[11:38:43] <temporalfox> so it looks like

[11:38:45] <temporalfox> List<Future> futures

[11:38:48] <temporalfox> pass with codegen

[11:39:07] <temporalfox> (but not List<Future<?» which is expected

[11:39:28] <temporalfox> and we cannot use a <T> parameter too othewise it has to be the same type

[11:39:48] <aesteve> ok

[11:39:59] <aesteve> the main idea behind this is :

[11:40:03] <tsegismont> temporalfox, I like asHandler

[11:40:10] <tsegismont> or asAsyncResultHandler

[11:40:21] <temporalfox> as asResultHandler ?

[11:40:28] <aesteve> (that's an example but that's the kind of code I'm writing quite often)

[11:40:48] <temporalfox> aesteve yes when you need a dynamic list

[11:41:08] <temporalfox> yes the idea is to remove what you do and what everbyody does all over the place :-)

[11:41:24] <aesteve> yes but the noticeable difference is List<Handler<Future»

[11:41:28] <aesteve> not List<Future>

[11:41:36] <temporalfox> ah

[11:41:36] <aesteve> notice the “start” method

[11:42:17] <aesteve> so my use case is different I think, so not sure that my advices are really accurate

[11:42:57] <temporalfox> in the CompositeFuture case such list would be too specific

[11:43:32] <aesteve> makes sense

[11:44:12] <temporalfox> thanks for the feedback on Liist

[11:44:17] <aesteve> at least my implementation would use CompletableFuture behind the hood, which is still an improvement

[11:44:22] <temporalfox> I think it's someting doable

[11:44:29] <aesteve> CompositeFuture, sry

[11:45:35] <aesteve> tsegismont: I'm using 'voidz' generally when I'm facing the naming issue with a Void lambda parameter

[11:48:44] <aesteve> temporalfox: do you know who's in charge with the scala implementation ?

[11:49:04] <temporalfox> aesteve martin I think

[11:49:26] <temporalfox> ah no

[11:49:28] <temporalfox> Lars Timm

[11:49:30] <temporalfox> Timm / martin (close for me)

[11:49:44] <temporalfox> are you interested in taking over :) ?

[11:50:11] <aesteve> absolutely not I'm a Scala beginner

[11:50:26] <aesteve> but it's easier learning a language through an API you already know :P

[12:00:06] <temporalfox> aesteve I just push a commit with all/any list

[12:00:17] <aesteve> thanks :)

[12:02:27] <aesteve> but if you need a scala lead, maybe asking on twitter or scala's user list would do it ?

[12:12:28] <temporalfox> we need someone that finishes the work

[12:12:32] <temporalfox> indeed good idea

[12:35:04] <Narigo> I guess most of the scala users are using Akka instead of Vert.x… :S

[13:28:43] <temporalfox> aesteve now the TestContext#asyncAssert* are not @GenIgnore anymore

[13:28:53] <temporalfox> (due to improvmements in codegen)

[13:28:58] <aesteve> cool !

[13:29:37] <aesteve> can vanish, then !

[13:29:48] <temporalfox> yes

[13:30:03] <temporalfox> the new codegen feature allows Handler<> as return type

[13:30:10] <temporalfox> maybe it can be useful to you as well

[13:30:23] <aesteve> actually no, there's still : async { } which is useful

[13:30:28] <temporalfox> ok

[13:30:30] <temporalfox> ah yes

[13:30:35] <temporalfox> this one is good

[13:31:29] <aesteve> context.async { assertNotNull(someVar);it.complete() }

[13:31:45] <aesteve> where assertNotNull is actually context.assertNotNull

[13:33:29] <temporalfox> I think it would be more or less like

[13:33:43] <temporalfox> context.async(Handler<Async> v → { … })

[13:34:04] <aesteve> yes, you'll still miss the delegate, but yes

[13:34:06] <temporalfox> it is similar except that groovy syntax makes it look like a block

[13:35:07] <aesteve> that's something I was wondering, too

[13:35:27] <aesteve> if thanks to codegen we could'nt do what C[unknown:eacute]dric sometimes talks about

[13:35:35] <aesteve> atomatically delegating

[13:35:48] <temporalfox> ah ok

[13:35:50] <aesteve> since Handler always has one parameter

[13:35:59] <temporalfox> having the “this” changed

[13:36:04] <aesteve> the parameter could be a delegate

[13:36:06] <temporalfox> like bind in js

[13:36:21] <temporalfox> but that's not something that would work everywhere

[13:36:23] <aesteve> so C[unknown:eacute]dric talks about many things :D

[13:36:38] <aesteve> I was thinking about removing the 'it'

[13:36:59] <temporalfox> ah, having the it becoming “this”

[13:37:08] <aesteve> not necesserily

[13:37:15] <temporalfox> what does it become then ?

[13:37:17] <temporalfox> implicit

[13:37:18] <temporalfox> ?

[13:37:20] <aesteve> yes

[13:37:28] <temporalfox> so

[13:37:33] <temporalfox> it would need some naming like

[13:37:50] <temporalfox> Handler<@Named(“request”) HttpServerRequest> handler

[13:37:51] <temporalfox> or

[13:37:59] <temporalfox> Handler<HttpServerRequest> requestHandler

[13:38:05] <aesteve> that's what I did in the DSL for exemple

[13:38:10] <temporalfox> and requestHandler → handler of request

[13:38:15] <temporalfox> and the parameter is named “request”

[13:38:37] <temporalfox> perhaps that some meta programming could do that

[13:38:46] <temporalfox> if it dispatches to a closure with no arguments

[13:38:49] <aesteve>

[13:38:56] <temporalfox> then the argument is made available with the name

[13:39:07] <temporalfox> but I think it's too much magic

[13:39:10] <aesteve> response is directly 'getResponse' without me having to do anything

[13:39:19] <aesteve> because the delegate is RoutingContext

[13:39:20] <temporalfox> but also pehraps groovy guys feel very natural wit hthat

[13:39:46] <temporalfox> ok in this case it is because you are doing special crafting to the api

[13:40:04] <aesteve> cool thing is if you annotate the method with @DelegatesTo

[13:40:18] <aesteve> your IDE will understand that response is the response from the routingContext

[13:40:42] <aesteve> I'm not sure it's good for every handler

[13:40:51] <aesteve> but for the RoutingContext it makes a lot of sense

[13:41:18] <aesteve> think about it : request, response, params, user, etc. all are context attributes

[13:42:36] <aesteve> bodyAsString, bodyAsJson

[13:42:46] <aesteve> these don't need any special crafting

[13:42:58] <aesteve> they are already getters

[13:43:38] <temporalfox> so in this case it become the “this”

[13:50:10] <aesteve> not exactly

[13:50:11] <aesteve>

[13:52:22] <aesteve> it's implicit as you said

[13:53:55] <aesteve> but anyway, I'm not sure it works in all Vert.x cases, but for writing DSL it makes sense. Gradle does this, I think (didn't check) ratpack does too

[13:58:55] <temporalfox> I remember I used delegates in crashub

[13:59:03] <temporalfox> with the shell session

[13:59:04] <temporalfox> so doing

[13:59:11] <temporalfox> def a = foo;

[13:59:17] <temporalfox> was doing a foo lookup in session

[13:59:28] <temporalfox> I think it was a bad idea after all

[13:59:33] <temporalfox> too magic

[13:59:45] <temporalfox> (in this context)

[14:40:45] <aesteve> temporalfox: tell me if you're making an annoucement re. Scala I'll try to support you ;)

[14:41:49] <aesteve> even though Akka is great and scala developpers probably use it, I think diversity can't be something bad for scala users

[15:09:38] <robal> hi guys, I've been writing a reverse proxy built on Vertx. Works almost perfect, except for websockets. I understand I need to upgrade the connection.. any idea on how to do this? can I just add it to response.headers()?

[15:10:01] <robal> the repo can be found here, if you're interested:

[15:13:27] <aesteve> robal: if(clientResponse.getHeader('Connection') == 'Upgrade') { serverRequest.upgrade() }

[15:13:31] <aesteve> something like that ?

[15:14:33] <robal> aesteve: that easy? sounds like it could be. I'm going to try it! :D thanks!

[15:14:51] <aesteve> that's pseudo-code but I would write it this way I think

[15:15:03] <aesteve> just give it a try :)

[15:16:15] <robal> yeah, I understand, I'm going to try and make it work. Thanks! I'm really happy with the reverse proxy, hopefully I can make it work with websockets :D

[15:17:37] <aesteve>

[15:18:28] <aesteve> but once the websocket handshake has ended I'm not sure how you will forward the frames

[15:19:17] <aesteve> since you don't have any websocketHandler on your server

[15:19:55] <tsegismont> temporalfox, with the new function capability in codegen, it means we could remove @genignore on io.vertx.ext.unit.TestContext#asyncAssertSuccess(io.vertx.core.Handler<T>) ?

[15:20:01] <tsegismont> correct?

[15:20:05] <temporalfox> yes

[15:20:09] <tsegismont> issue?

[15:20:19] <temporalfox>

[15:20:28] <temporalfox> I have the commit locally :-)

[15:20:33] <aesteve> so maybe robal it's not that easy after all, don't hesitate to ask our question on the Google group

[15:21:09] <tsegismont> temporalfox, change your nickname to boosterfox :)

[15:29:48] <robal> aesteve: oh right, thanks for taking a look at my code and thinking along :D if I can't get it to work I'll also approach the Google group

[15:31:21] <aesteve> temporalfox: if I was asking about Scala that's because I'd like to write something very functional-oriented with Vert.x. I think maybe that's one of the fields where improvements could be made

[15:31:44] <aesteve> “composing” handlers is maybe what I'm missing the most

[15:31:48] <temporalfox> Clojure!!! :-)

[15:31:59] <aesteve> too many parenthesis :p

[15:33:43] <aesteve> joke aside, a way to express that : GET('/api/friends') = (checkBearerToken » checKUserRegistered » getFriends).mapToResponse

[15:33:46] <aesteve> would be fantastic

[15:34:40] <aesteve> where every function is a Handler<RoutingContext> and has a piece of logic

[15:41:26] <mcw> Hi there, is it possible to mix vert.x versions. Let's say my vert.x app runs with version 2.1.2 but I deploy a module which is written in v3.2.0. Does this work or do all modules have to be written in the same version? thank you

[16:12:38] <mcw> Hi there, is it possible to mix vert.x versions. Let's say my vert.x app runs with version 2.1.2 but I deploy a module which is written in v3.2.0. Does this work or do all modules have to be written in the same version? thank you

[16:34:28] <robal> mcw: I think most modules are dependent on io.vertx.core, so they need to be the same version. It shouldn't be a lot of work to switch versions though

[16:40:23] <mcw> robal: thank you, but do you think a switch from vert.x 2x to 3x isn't much work too?

[17:05:14] <robal> mcw: well, depending on how much code you've written you might see a few errors. If you're using maven you can simply change the version number for all of your vertx dependencies. I think I only had to change 4 lines of code to make it work in one of my projects, but that was for a simple vertx-web project.