first of all, i'm learning scala and new to the java world. I want to create a console and run this console as a service that you could start and stop. I was able to run a ConsoleReader into an Actor but i don't know how to stop properly the ConsoleReader. Here is the code :
import eu.badmood.util.trace
import scala.actors.Actor._
import tools.jline.console.ConsoleReader
object Main {
def main(args:Array[String]){
//start the console
Console.start(message => {
//handle console inputs
message match {
case "exit" => Console.stop()
case _ => trace(message)
}
})
//try to stop the console after a time delay
Thread.sleep(2000)
Console.stop()
}
}
object Console {
private val consoleReader = new ConsoleReader()
private var running = false
def start(handler:(String)=>Unit){
running = true
actor{
while (running){
handler(consoleReader.readLine("\33[32m> \33[0m"))
}
}
}
def stop(){
//how to cancel an active call to ConsoleReader.readLine ?
running = false
}
}
I'm also looking for any advice concerning this code !
The underlying call to read a characters from the input is blocking. On non-Windows platform, it will use System.in.read()
and on Windows it will use org.fusesource.jansi.internal.WindowsSupport.readByte
.
So your challenge is to cause that blocking call to return when you want to stop your console service. See http://www.javaspecialists.eu/archive/Issue153.html and Is it possible to read from a InputStream with a timeout? for some ideas... Once you figure that out, have read
return -1
when your console service stops, so that ConsoleReader
thinks it's done. You'll need ConsoleReader
to use your version of that call:
tools.jline.AnsiWindowsTerminal
and use the ConsoleReader
constructor that takes a Terminal
(otherwise AnsiWindowsTerminal
will just use WindowsSupport.readByte` directly)ConsoleReader
constructor that takes an InputStream
, you could provide your own wrapper around System.in
A few more thoughts:
scala.Console
object already, so for less confusion name yours differently.System.in
is a unique resource, so you probably need to ensure that only one caller uses Console.readLine
at a time. Right now start
will directly call readLine
and multiple callers can call start
. Probably the console service can readLine
and maintain a list of handlers.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With