2011-01-14 7 views
5

Estoy tratando de entender cómo cake implementa su enfoque JVM múltiple. En un nivel alto, pensé que la torta funcionaba de manera similar a la pistola de clavos, donde hay una única instancia de JVM (un proceso de JVM) y las nuevas "JVM" para diferentes proyectos fueron simplemente clojure/jar evaluadas en un nuevo cargador de clases (junto con diferentes dependencias de jar), que en mi opinión no es una nueva instancia de JVM. Sin embargo, desde What's the difference between Cake and Leiningen?, existe la implicación de que hay varias JVM (una para cake y * para los proyectos), no solo una instancia de JVM.¿Cómo se implementa la función de JVM persistentes en cake?

Si hay nuevos casos de JVM creados, ¿de dónde viene el aumento de velocidad viene? Según tengo entendido, razonaría que comenzar una nueva JVM implica crear un nuevo proceso de JVM que incurre en la misma sobrecarga de inicio que de costumbre.

Si no los hay, cómo son las dependencias nativos añadido el? Por lo que entiendo, la JVM solo conoce las dependencias nativas de los argumentos de línea de comando aprobados antes del tiempo de ejecución. La única forma en que sé cómo eludir esto es con un hack específico de implementación JVM de Sun/Oracle que se detalla a continuación.

(let [clazz java.lang.ClassLoader 
     field (.getDeclaredField clazz "sys_paths")] 
    (.setAccessible field true) 
    (.set field clazz nil) 
    (System/setProperty "java.library.path" (apply str (interpose ";" native-paths)))) 

Respuesta

4

Cake tiene un script de Ruby que inicia y administra las JVM. Ruby no tiene la sobrecarga de JVM, por lo que la secuencia de comandos de Ruby podría crear las JVM y luego, cuando ejecutas los comandos, la secuencia de comandos de Ruby delegaría esos comandos en las JVM.

La razón dos JVM era necesario era tan dependencias de ese pastel (torta de la JVM) fueron separados de las dependencias del proyecto (la JVM hornear). Algunos comandos como cake repl se ejecutan en la JVM de cocción para aprovechar el classpath del proyecto.

Sin embargo, en la versión más reciente, sólo hay una única JVM por proyecto. Esto es posible usando diferentes clasificadores en la misma JVM. La biblioteca relevante utilizada es classlojure.

Incluso con las dos versiones de JVM, las JVM fueron persistentes, lo que significa que sólo se les engendraron una vez y luego se reinicia sólo cuando sea absolutamente necesario, como en el caso de una ruta de clase cambiada (cuando se agrega una nueva dependencia o algo similar). No estoy seguro de por qué piensas que esto significaría incurrir en la sobrecarga JVM cada vez que se ejecuta un comando. La idea es que muchos comandos suceden al instante en lugar de que cada comando comience una JVM.

+1

Gracias. OK, con la versión anterior, se creó una nueva JVM por proyecto, tenía la impresión equivocada de que, de nuevo, era más parecido a una pistola de clavos, donde solo hay una instancia de JVM. El método del método de pistola de clavos era ideal en lo que respecta al tiempo de arranque de JVM e ignorar los problemas de seguridad, que ahora me doy cuenta de que no es la forma en que se implementa el pastel. Estaba tratando de determinar el beneficio con respecto al tiempo de inicio de JVM en situaciones en las que era necesario reiniciar o crear la JVM, no por cada comando de tortas. – bmillare

+0

¿classlojure soporta la carga de dependencia nativa en tiempo de ejecución? – bmillare

2

Raynes es correcta. A partir del pastel 0.6.0, hay una JVM por proyecto. Cake se ejecuta en el cargador de clases principal y utiliza classlojure para cargar el proyecto en un cargador de clases separado y volver a cargarlo cuando cambie la ruta de clase. Hemos discutido una opción global ~/.cake/config para compartir una sola JVM entre todos los proyectos. No debería ser demasiado difícil agregar esto usando classlojure. El principal problema con este enfoque es cómo mantener separados los complementos de tarta. Quizás el proyecto global de tortas podría ejecutarse en el cargador de clases principal y cada proyecto podría obtener dos cargadores de clases (uno para torta y otro para el proyecto).

En cuanto a las dependencias nativos, classlojure no admite la adición de ellos después de la JVM se inicia. Un parche para agregar esta funcionalidad sería bienvenido siempre que la ruta de la biblioteca nativa sea local para un cargador de clases específico y no se comparta entre todos los cargadores de clases en la misma JVM.

+0

Esos dos últimos requisitos que mencionas, desafortunadamente, son básicamente imposibles de cumplir (que yo sepa). Además, el código que proporcioné arriba se rompería si se ejecutara con diferentes implementaciones de JVM. – bmillare

Cuestiones relacionadas