Scala version: How to use and override stopFuture() of a ScalaVerticle?

49 views
Skip to first unread message

Philippe Charrière

unread,
Jan 16, 2018, 2:17:37 AM1/16/18
to vert.x
Hello people

This is my baby steps with Scala and Vert.x

I'm trying to create a microservice sample scala project "from scratch" with the Redis backend

Almost all is ok:

I deploy the ScalaVerticle with a companion object:

object BeeSlack extends App {

val vertx = Vertx.vertx

// do some stuff, initialize discovery backend, etc...

vertx
.deployVerticleFuture(ScalaVerticle.nameForVerticle[brain.BeeSlack])
.onComplete {
case Success(verticleId) => println(s"Successfully deployed verticle: $verticleId")
case Failure(error) => println(s"Failed to deploy verticle: $error")
}

}

this is my verticle:

class BeeSlack extends ScalaVerticle {

override def startFuture(): Future[_] = {

val server = vertx.createHttpServer()
val router = Router.router(vertx)
val httpPort = sys.env.getOrElse("PORT", "8080").toInt

// publish the microservice record
BeeSlack.discovery.publishFuture(BeeSlack.record).onComplete{
case Success(result) => println(s"😃 publication OK")
case Failure(cause) => println(s"😡 publication KO: $cause")
}

router.route().handler(BodyHandler.create)

router.get("/hey").handler(context =>
context
.response
.putHeader("content-type", "application/json;charset=UTF-8")
.end(new JsonObject().put("message", "👋 hey!").encodePrettily)
)

router.route("/*").handler(StaticHandler.create)

println(s"🌍 Listening on $httpPort - Enjoy 😄")
server.requestHandler(router.accept _).listenFuture(httpPort)
}

}

I would like to unpublish the record verticle from the Redis backend when I quit
with Java I do like that

public void stop(Future<Void> stopFuture) {
System.out.println("Unregistration process is started ("+record.getRegistration()+")...");

discovery.unpublish(record.getRegistration(), asyncResult -> {
if(asyncResult.succeeded()) {
System.out.println("👋 bye bye " + record.getRegistration());
} else {
System.out.println("😡 Not able to unpublish the microservice: " + asyncResult.cause().getMessage());
//asyncResult.cause().printStackTrace();
}
stopFuture.complete();
});
}

and stop method is triggered when I quit
but I can't do the same thing with Scala and with the 

I try something like that with override def stopFuture(): Future[_] = {...}
but I can't trigger anything (again: this is my baby steps 😉)

override def stopFuture(): Future[_] = {
var unpublishRecordFuture = BeeSlack.discovery.unpublishFuture(BeeSlack.record.getRegistration)

unpublishRecordFuture.onComplete {
case Success(result) => {
println(s"😃 removing publication OK")
}
case Failure(cause) => {
println(s"😡 removing publication KO: $cause")
}
}
unpublishRecordFuture
}

It's probably easy, but I don't find a solution.

Does anybody know an example about this or has an idea?

Regards
Philippe

Thomas SEGISMONT

unread,
Jan 16, 2018, 4:09:36 AM1/16/18
to ve...@googlegroups.com
Hi,

What do you mean by "can't trigger anything"? The stop method of your Scala verticle is not invoked?

Looking at the doc (http://vertx.io/docs/vertx-core/scala/#_asynchronous_verticle_start_and_stop) it seems your impl is right, except you need to complete (or fail the future) when done with unpublishing the record.

--
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+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/f1296f16-7257-4f23-a45b-ad36e6b1ac1d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Philippe Charrière

unread,
Jan 16, 2018, 5:09:52 AM1/16/18
to vert.x
Yes the stop method is never invoked
I try with
unpublishRecordFuture.onComplete {
 
case Success(result) => {
   
println(s"😃 removing publication OK")

   
Future.successful(())

 
}
 
case Failure(cause) => {
   
println(s"😡 removing publication KO: $cause")

   
Future.failed(new Throwable())
 
}
}

but nothing and the unpublishRecordFuture future has no complete or fail method

;) I'm better with JavaScript
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.

Thomas SEGISMONT

unread,
Jan 16, 2018, 5:50:00 AM1/16/18
to ve...@googlegroups.com
I didn't expect the Future#complete and Future#failed calls to change your observations. Just pointed this out for correctness.

I would not expect a bug in the Scala module in this area. A stop method may not get invoked if the KILL signal is not correctly transferred to the JVM (so the shutdown hook is not invoked).
What's your environment? How's your program tested?

To unsubscribe from this group and stop receiving emails from it, send an email to vertx+unsubscribe@googlegroups.com.

Jochen Mader

unread,
Jan 17, 2018, 2:06:11 PM1/17/18
to ve...@googlegroups.com
Could you please provide your whole project so I can take a look at it?
I tested various combinations of the stopFuture-method and Futures and everything seems to work correctly.
I won't be able to see your problem without the full example.


For more options, visit https://groups.google.com/d/optout.



--
Jochen Mader | Principal IT Consultant

codecentric AG | Elsenheimerstr. 55a | 80687 München | Deutschland
tel: +49 89 215486633 | fax: +49 89 215486699 | mobil: +49 152 51862390
www.codecentric.de | blog.codecentric.de | www.meettheexperts.de

Sitz der Gesellschaft: Düsseldorf | HRB 63043 | Amtsgericht Düsseldorf
Vorstand: Michael Hochgürtel . Rainer Vehns
Aufsichtsrat: Patric Fedlmeier (Vorsitzender) . Klaus Jäger . Jürgen Schütz

Thomas SEGISMONT

unread,
Jan 17, 2018, 4:20:51 PM1/17/18
to ve...@googlegroups.com

Jochen Mader

unread,
Jan 22, 2018, 4:17:51 AM1/22/18
to ve...@googlegroups.com
I finally got some time yesterday to look at the issue.
First: It's not a Vert.x-Bug.
The problem lies within the way you use the Vertx-instance.
But first about the solution, add the following lines to the end BeeSlack (the part that extends App):
Runtime.getRuntime.addShutdownHook(new Thread() {
override def run(): Unit = {
Await.result(vertx.closeFuture(), 1000 millis)
}
})
Now for the reason:
You are using a Vertx-instance you created yourself, those don't register a shutdown-hook (something io.vertx.core.Launcher takes ccare of) and have no chance of executing the stop-code if the JVM exits.
we provide a Vertx-quickstart that does all the required bootstrapping for you to avoid this (run sbt new vert-x3/vertx-scala.g8 to get fully configured project).

Why did it run with Java?
Well, you most likely used one of the provided startes (Maven/Gradle/...) or something else that didn't use Vertx directly but instead relied on the Launcher.

Some further comments on your code:
Vert.x is all about isolation so please don't share anything by reference. Service-discovery/registration should be done inside a verticle to avoid contention and/or threading problems :)

I will add this answer to the issue and resolve it.




For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages