Digamos que estoy ejecutando un servicio donde los usuarios pueden enviar una expresión regular para buscar a través de una gran cantidad de datos. Si el usuario envía una expresión regular que es muy lenta (es decir, demora minutos para que Matcher.find() regrese), quiero una manera de cancelar esa coincidencia. La única forma en que puedo pensar en hacer esto es hacer que otro subproceso controle cuánto tiempo lleva una coincidencia y use Thread.stop() para cancelarlo si es necesario.¿Cancela una coincidencia de expresiones regulares de larga ejecución?
las variables de miembro: hilo
long REGEX_TIMEOUT = 30000L;
Object lock = new Object();
boolean finished = false;
Thread matcherThread;
Matcher: Hilo de
try {
matcherThread = Thread.currentThread();
// imagine code to start monitor thread is here
try {
matched = matcher.find();
} finally {
synchronized (lock) {
finished = true;
lock.notifyAll();
}
}
} catch (ThreadDeath td) {
// send angry message to client
// handle error without rethrowing td
}
Monitor:
synchronized (lock) {
while (! finished) {
try {
lock.wait(REGEX_TIMEOUT);
if (! finished) {
matcherThread.stop();
}
} catch (InterruptedException ex) {
// ignore, top level method in dedicated thread, etc..
}
}
}
He leído java.sun.com/j2se/1.4.2/ docs/guide/misc/threadPrimitiveDeprecation.html y creo que este uso es seguro ya que estoy controlando dónde se lanza ThreadDeath a través de la sincronización y ha ndle y los únicos objetos dañados podrían ser mis instancias de Pattern y Matcher que se descartarán de todos modos. Creo que esto rompe Thread.stop() porque no estoy volviendo a lanzar el error, pero realmente no quiero que el hilo muera, solo aborte el método find().
He logrado evitar el uso de estos componentes de API obsoletos hasta el momento, pero Matcher.find() no parece ser interrumpible y puede demorar mucho tiempo en regresar. ¿Hay alguna forma mejor de hacer esto?
Personalmente, creo que permitir que los usuarios envíen un regex como criterio de búsqueda es una mala idea. Los programadores tal vez, pero no los usuarios finales ... –
Sin duda, debería esperar obtener DoSed si acepta expresiones regulares arbitrarias. –
No todo el código está expuesto a una red pública en la que debe preocuparse por DoS. – Jared