https://kotlinlang.org logo
Title
p

paulex

01/28/2020, 9:26 AM
How do i keep the JVM alive to receive connections.... e.g
fun main(args:Array<String>) = runBlocking<Unit>{
   InternalLoggerFactory.setDefaultFactory(Log4JLoggerFactory.INSTANCE)
   val server = AppServer(this)
   server.run()
}
I want to main thread to stay alive until a shutdown...
e

Erik

01/28/2020, 10:01 AM
You could for example
launch
your coroutine from a
CoroutineScope
and
join()
the
Job
that
launch
returns before the JVM exits.
e

elizarov

01/28/2020, 10:14 AM
What is
AppServer
? You should check it out to see what facilities it provides to wait until shutdown.
p

paulex

01/28/2020, 10:21 AM
@elizarov AppServer has this method...
@Throws(InterruptedException::class)
fun blockUntilShutdown(){
    this.server.awaitTermination()
}
This is the implementation of awaitTermination
@Override
public void awaitTermination() throws InterruptedException {
    synchronized (lock) {
      while (!terminated) {
        lock.wait();
      }
    }
  }
e

elizarov

01/28/2020, 10:23 AM
Then you don’t need coroutines (
runBlocking
) here. Just use this
awaitTermination
to block.
p

paulex

01/28/2020, 10:23 AM
But for reason, when i use the awaitTermination provided by the grpcServer... i can receive request on my grpcServer but for some reasons,
launch {}
blocks are not triggered.
e

elizarov

01/28/2020, 10:24 AM
You should
launch { … }
in some other dispatcher, because you’ve blocked your main thread by waiting, or block some other thread to wait for termination, and then you’ll be able to launch in your main thread.
The former:
launch(Dispatchers.Default) { … }
The latter:
withContext(<http://Dispatchers.IO|Dispatchers.IO>) { server.blockUntilShutdown() }
Either way it should work.
p

paulex

01/28/2020, 10:26 AM
Alright, thanks @elizarov, I'm going to try this out... Thanks very much..
@elizarov So I did something like this, and it seems to work fine...
Class ServiceA (val scope: CoroutineScope){
   @Inject
   private val repo: Repository

   fun getFoo(id, callback){
      scope.launch {
		repo.getFooFromDatabase() //suspend function
      }//end of scope
	}//end of function
}//end of class

//Main Function
fun main(){
  val serviceA = ServiceA(CoroutineScope(Dispatchers.Default));
  …
  appServer.awaitTermination();
}
I'm guessing this is not a bad practice, the way i have initialized CoroutineScope.. Thanks in advance