Estoy buscando reemplazar una gran cantidad de mi perl con scala. Una de las cosas que tiendo a hacer mucho es llamar binarios (generalmente C++ compilado, pero podría ser java, otros scripts Perl, scripts q, etc.) proporcionados por otros equipos de mi empresa.Scala - obteniendo una devolución de llamada cuando sale un proceso externo
Por ejemplo, para hacer algunos cálculos matemáticos complejos, comenzaría uno de los binarios externos y luego canalizaría mis entradas. Luego escucharía su stream stdout
para obtener resultados, y stderr
transmisión para mensajes de diagnóstico. En Perl, haría esto usando un widget POE::Wheel::Run
. He encontrado algo análogo (y mucho mejor) en scala, pero me gustaría hacerlo más robusto. Es una pequeña envoltura alrededor de un objeto ProcessIO
. Se ve así:
class Exe(command: String, out: String => Unit, err: String => Unit) {
import scala.sys.process._
import scala.io._
import java.io._
import scala.concurrent._
val inputStream = new SyncVar[OutputStream];
val process = Process(command).run(
new ProcessIO(
stdin => inputStream.put(stdin),
stdout => Source.fromInputStream(stdout).getLines.foreach(out),
stderr => Source.fromInputStream(stderr).getLines.foreach(err)));
def write(s: String): Unit = synchronized {
inputStream.get.write((s + "\n").getBytes)
}
def close(): Unit = {
inputStream.get.close
}
}
me gustaría a continuación, utilizar de esta manera:
val exe = new Exe("tr [a-z] [A-Z]",
out => println("o: " + out),
err => println("e: " + err))
exe.write("lower")
exe.close()
que imprime:
o: LOWER
Esto me obtiene el 90%, pero lo que sería bueno sería obtener una devolución de llamada cuando el proceso finalice. Puede salir porque he cerrado la secuencia de entrada y su ciclo interno se detiene, puede salir solo o puede salir porque lo he matado. En la devolución de llamada, sería bueno saber por qué se detuvo y el código de salida.
Estoy un poco perdido en cuanto a cómo hacer esto, cualquier ayuda sería apreciada (y cualquier edición del código anterior es, por supuesto, bienvenido, soy un poco novato) .
estoy usando 2.9.0.1
Personalmente, creo que apesta que 'Process' no tenga algún tipo de método de votación' isFinished'. Eso es una cosa que cambiaría, aunque la solución provista por didierd parece más como lo que quieres. –