He publicado la primera versión pública de ItsNat.
ItsNat es un framework Web en Java de código abierto. Sí "otro framework". sin embargo el enfoque es radicalmente diferente a lo que ya existe.
ItsNat significa "es natural" porque la forma de programar aplicaciones web es como debería haber sido siempre: plantillas en puro (X)HTML, lógica de la vista en puro DOM y usando exclusivamente Java sin custom tags, sin JSP, sin lenguajes de expresión, sin lógica mezclada con la vista es decir partiendo de (X)HTML sin lógica y no formando la vista sólo a base de código, sin XMLs de configuración, sin metaprogramación en XML, con AJAX desde cero no como un añadido forzado, basado en el servidor con mínimo JavaScript en el cliente, orientado al programador no a herramientas específicas, y con un enfoque en el que el programador es el absoluto protagonista en donde tiene el control práticamente total de su aplicación web 2.0.
El enfoque es el siguiente, ItsNat simula un navegador universal W3C en el servidor, el servidor contiene un árbol W3C DOM que manipula con Java W3C DOM y que recibe eventos desde el cliente via AJAX convertidos en eventos W3C DOM Events y cuyas modificaciones al DOM servidor son enviadas automáticamente al cliente actualizando el DOM del mismo.
No hay problema con la memoria, ItsNat tiene una caché "inteligente" que detecta y guarda como texto plano en memoria, una sola instancia, aquellas partes del árbol DOM que son estáticas.
Aparte de "continuaciones", timers, COMET sin servidores especiales, visor/control remoto de las páginas de otros usuarios, soporte de SVG, generación de XML, pretty URLs, detección de botones back y forward, testeo funcional de la web desde el servidor, modos sin AJAX y sin JavaScript etc ItsNat define también un modelo de componentes similar a Swing de hecho reutiliza cuanto puede tal y como los data models y selection models (y respectivos listeners) incluidos trees, en donde cualquier elemento o grupo de elementos HTML (incluso SVG) puede ser un componente.
La licencia es GNU Affero General Public License v3 con opción de licencia para código cerrado.
Web (descarga, manuales...): www.itsnat.org o itsnat.sourceforge.net
Demo online (con código y explicaciones): http://www.innowhere.com:8080/itsnat
Si el host de la demo online estuviera caido, la demo está incluida en la propia distribución de ItsNat. Sourceforge está dando extraños problemas con el PHP (arg) haz reload cuando la página falle.
Se presentará en un stand en el SIMO TCI del Ifema de Madrid del 6 al 11 de noviembre en el pabellón 1 en el área Vivero stand 1B239.
Por eso tengo un montón de entradas para profesionales (valen también para el fin de semana según pone la entrada).
Ofrezco un par de opciones compatibles: quedar quienes querais el viernes o el sábado los de Madrid, y los de la península podeis escribirme un e-mail y os puedo enviar algunas entradas por correo tradicional. Para los que estais fuera de Madrid, también puedo enviar vales descuento de Renfe (25-30%) para desplazamientos a Madrid en esas fechas (aves, regionales, larga distancia etc).
Por experiencia, en las entradas profesionales teneis que acreditar de alguna manera (nómina + DNI o similar) que sois de la empresa que poneis en la entrada, tratan de evitar que vaya el sobrino del que recibe la invitación.
Mi mail no corporativo es: jmarranz@eresmas.com (está muy machacado ya por el spam no hay problema).
Espero vuestros comentarios, críticas, consejos etc y por último oficialmente abandono mis vacaciones de javaHispano de estos meses, espero participar más
Etiquetas: j2ee, itsnat, ajax, java, dom, w3c, html, xhtml, svg, web, 20
Que curradas te pegas madre mia!, si entiendo bien la idea principal es que en el lado servidor tengo una representación del DOM de la pagina y las manipulaciones que hago en ese DOM desde el servidor luego se envian a la pagina y en la pagina supongo habrá un js que se encargue de traducir esos mensajes y propagar esas operaciones al DOM cliente. Luego por otro lado los eventos que se produzcan en el DOM cleinte se envian para ser procesados en los "listeners" que coloque en el lado servidor, ¿voy bien?
La idea de tener un "proxy" del DOM en el lado servidor desde luego me parece original y atrevida (sólo de pensar en tener que implementarlo se me ponen los pelos de punta, que tio más monstruo...), pero me surjen ciertas dudas:
- Para manener sincronizados los DOM cliente y servidor como lo haces?, la primera vez que te comuniques desde el cliente al servidor envias el DOM completo y luego ya supones que todas las operaciones sobre e DOM se realizan en servidor? (de modo que sólo vas enviando la modificaciones del servidor al cliente)
Esto lo digo pensando en si algunas operaciones sobre el DOM decido hacerlas directamente sobre el cliente, en este supuesto se mantedrían los DOM sincronizados de algún modo?, no se podría hacer?, me estoy liando mucho y digo tontunas?
Por ejemplo te planteo un problema, estoy haciendo un editor de UML AJAX (su terminación esta prevista más o menos para las mismas fechas que la sagrada familia...), necesito claro esta que las cajitas UML se muevan por pantalla, esto lo hago respondiendo a los eventos DOM "onmouseXXX" directamente desde cliente, si tuviera que proceare estos eventos en servidor y cambiar las posiciones de la caja manipulando el DOM en servidor sería del todo impracticable. (en realidad todas las operaciones excepto "guardar diagrama" se ejecutan siempre en javascript en el lado cliente)
La idea del framework me gusta desde el punto de vista de que las comunicaciones cliente-servidor se hacen del todo transparentes, pero y si quiero hacer algo que no requiere de ir al servidor?, puedo elegir que eventos del DOM se procesan en cliente y cuales en servidor?, puedo confiar siempre que la representación del DOM que tengo en servidor coincide con lo que hay realmente en cliente? (aunque algunas operaciones las ejecute en código js cliente directamente).
Me recuerda un poco a la arquitectura de ICEFaces , aunque en este caso hablemos de JSF. Lo que no me termina de gustar es la licencia ;)
Hola José María,
tu marco de trabajo me parece interesante,
incluso podría ser una opción para hacer un generador de UI para OpenXava.
Pero tengo algunas preguntas iniciales:
¿Se pueden crear portlets JSR-168?
En ese caso ¿en qué portales está testeado?
¿La licencia que usas permite incluirlo en un producto LGPL?
Las estadisticas de descargas no funcionan para tu proyecto en sourceforge.
Esto es importante, porque es una de las cosas a considerar a la hora de escoger un producto de código abierto.
Y una última pregunta, ¿es posible testear desde el cliente usando HttpUnit o HtmlUnit?
Gracias de antemano
Hola,
El primer detalle es que algo le ocurre al servidor (itsnat.sourceforge.net) por que de vez en cuando al acceder a una pagina el navegador me dice que si quiero descargarme la pagina en forma de (PHP Script) en vez de mostrarmela... (y si me la descargo es un fichero vacio) asi que algo tiene :).
En cuanto al framework en si, algunas cosas no las acabo de ver. No usas XML en la configuracion, bien, ni que fuera el diablo, pero la configuración propones ponerla escrita en Java "a pelo" en un singleton? (al menos eso parece mostrar el ejemplo) o por otro lado dices que usen Spring o lo que quieran. Es decir, ¿no usa XML por que no usa nada y tu te lo has de montar?. Y se usa "puro" Java y "puro" DOM etc., bien, pero ¿la manipulación de la interfaz es toda en Java "hardcoded" y compilada en clases?
Suerte con el proyecto!
Remoh: la idea principal es que en el lado servidor tengo una representación del DOM de la pagina y las manipulaciones que hago en ese DOM desde el servidor luego se envian a la pagina y en la pagina supongo habrá un js que se encargue de traducir esos mensajes y propagar esas operaciones al DOM cliente. Luego por otro lado los eventos que se produzcan en el DOM cleinte se envian para ser procesados en los "listeners" que coloque en el lado servidor, ¿voy bien?
Vas bien. La mayor parte de la cocina del código JavaScript generado para sincronizar el cliente se hace en el servidor para solucionar los típicos problemas de incompatibilidad, pero sí hay una pequeña librería en el cliente de unos 50Kb (con muchos espacios, la chicha es menos) para ese fin y para transportar los eventos elegidos al servidor.
Remoh: La idea de tener un "proxy" del DOM en el lado servidor desde luego me parece original y atrevida (sólo de pensar en tener que implementarlo se me ponen los pelos de punta ... Para manener sincronizados los DOM cliente y servidor como lo haces?, la primera vez que te comuniques desde el cliente al servidor envias el DOM completo y luego ya supones que todas las operaciones sobre e DOM se realizan en servidor? (de modo que sólo vas enviando la modificaciones del servidor al cliente)
ItsNat usa una técnica DOM muy ignorada por culpa del Internet Explorer que son los "mutation events", estos te informan de los cambios en el DOM, la idea es sencilla, eso sí, el infierno está en los detalles.
La primera vez se envía como HTML normal, de hecho en fase de carga las manipulaciones del DOM no se envían como JavaScript sino como HTML con las modificaciones incorporadas respecto a la plantilla original (esto es configurable), es en la respuesta a los eventos en donde se envían los cambios como JavaScript.
Ciertamente se supone que los cambios del DOM se han de hacer en el servidor.
Remoh: Esto lo digo pensando en si algunas operaciones sobre el DOM decido hacerlas directamente sobre el cliente, en este supuesto se mantedrían los DOM sincronizados de algún modo?, no se podría hacer?, me estoy liando mucho y digo tontunas?
Je je te veía venir, no no tú nunca dices tontunas, en el caso de librerías cliente el framework tiene utilidades para sincronizar "manualmente" el estado de un subárbol del cliente en el servidor precisamente para resolver ese problema. Pero no es imprescindible, puede haber subárboles del cliente que no estén sincronizados con el servidor y puede no pasar nada, simplemente añades un como elemento padre (si es necesario) y ya está, obviamente en el servidor no deberías tocar esa zona. Este caso ya se da en el Syntax Highlighter, que no es mio, del Feature Showcase, éste añade nodos en el cliente, yo simplemente recubro las zonas con un y a vivir. Es más podría sincronizar desde el cliente como contaba antes, o mejor, emular el estado del cliente en el servidor usando DOM y desactivando la sincronización automática en el cliente temporalmente (se puede), de esa manera podría manipular o añadir funcionalidad al Syntax Highlighter desde el servidor (aunque no para procesar eventos en el servidor, se puede también inyectar nueva funcionalidad a base de handlers onclick desde el servidor). Quise hacer el añadir un link "collapse" para que se cerrara de nuevo el código fuente pero he acabado tan cansado que para cuando tenga ganas, pero técnicamente es viable.
Remoh: si tuviera que proceare estos eventos en servidor y cambiar las posiciones de la caja manipulando el DOM en servidor sería del todo impracticable. (en realidad todas las operaciones excepto "guardar diagrama" se ejecutan siempre en javascript en el lado cliente)
Cierto, ItsNat no busca ser todo para todos, ItsNat es céntrico en el servidor y hay tareas intensivas en eventos cuya finalidad es puramente visual que obviamente es absurdo enviar al servidor. Funcionaría quizás en intranets (o localmente) y en casos en donde hay toneladas JavaScript y el proceso fuera complejo porque el JavaScript es leeeeento de narices (Java es más rápido en órdenes de magnitud) pero incluso en ese caso no me atrevería a defender esa estrategia hasta que un prototipo lo confirmara. Te pongo un ejemplo: cuando hay necesidad de cálculos matemáticos de cientos de miles de iteraciones, pero tu ejemplo no es de ese tipo.
Para tu problema ItsNat tiene lo que se llaman eventos definidos por el usuario, en través de una función JS en el cliente se puede enviar un evento transportando los datos que se desean que será recibido por aquellos listeners registrados en el servidor para ese tipo de evento (dado por un nombre y opcionalmente un nodo), vendría a ser la funcionalidad un DWR pero dentro de la arquitectura ItsNat.
javier.rj: Me recuerda un poco a la arquitectura de ICEFaces , aunque en este caso hablemos de JSF. Lo que no me termina de gustar es la licencia ;)
Umm puede, aunque no tengo absolutamente ni idea de como lo hacen, para obtener el código fuente hay que registrarse y no he caído en la tentación, la "gran" diferencia es que ICEFaces oculta totalmente la posible técnica DOM que use por abajo de su JSF. Lo único que les he "robado" es el icono de la rueda dentada XD
Hace meses cuando ya tenía un prototipo hecho busqué y busqué por internet para ver si estaba perdiendo el tiempo y lo más parecido que encontré fue un proyecto muerto llamado BZByte, pero el enfoque es muy diferente.
Respecto a la licencia: ItsNat no es un "pet project" on un "Sunday project" como dice Geertjan de NetBeans. El código abierto aporta confianza, transparencia pero no necesariamente debe suponer llevar a la industria del software a una especie de "industria indigente", o una especia de "industria ONG". Cuando una ONG de desarrollo financia una infraestructura civil en una región pobre no creo que la misma ONG te instale la calefacción de tu casa "by the face".
Si tu web no tiene afan de lucro obviamente no tendrás problema alguno en publicar tu código fuente que es lo que pide la AGPL. La web meneame.net funciona así y eso que existe afan de lucro (que Varsavsky no regala el dinero aunque sea consciente de que lo puede perder).
Yo creo que en el juego justo: si tu software (una tienda online lo que sea) sirve para ganar dinero no creo que te preocupe asumir un pequeño porcentaje del coste final por usar la tecnología que hace vivir tu negocio, más aun cuando las corbatas de los consultores que has necesitado pueden valer mucho más.
Por no hablar de lo que yo llamaría el "éxito paradójico", librerías de gran éxito que curiosamente de vez en cuando se oye "está abandonado", "se han peleado y la mitad se han ido" y cosas así. Lo siento pero a mi me suena como muy amateur. Bien para el que lo implanta y se va corriendo pero no es serio para el se lo queda cuando necesita resolver fallos y se encuentra con un proyecto muerto. Hay dinosaurios en COBOL y bases de datos ancestrales que tienen mucha más garantía de soporte y de futuro que algunos productos de moda de licencia muy liberal.
Esto no quita que si algun primo de ZumoSol (frase broma española tomada un anuncio) exponsoriza el proyecto pueda cambiar la licencia, todo es negociable.
Dejando a un lado un momento otros detalles (aún no he podido verlo mucho), decir que me sorprende un poco que lo distribuyas como un proyecto de NetBeans. Quizá es porque justo ayer leí esto ;)
Como no, venkman, me toca "defender" a Netbeans.
Estoy totalmente de acuerdo con el post que citas, de hecho la mayoría de mis proyectos tenían su propio build de ant (no el generado por Netbeans), excepto en el que estoy ahora (ya que se trata de un proyecto NB RCP, y no tiene mucho sentido si no hay ciertas cosas de NB ya cargadas). Pero pese a todo, NB no es que soporte ant, sino que todos los proyectos, e incluso el IDE se basan en ant para todo el proceso de build, y más recientemente con el plugin de maven, cualquier proyecto maven se reconoce como si fuera un proyecto de NB directamente (sin tener que abrirlo primero como proyecto NB). Sé que otros IDE's también soportan ant, pero desde luego no creo que haya ninguno en el que tener un build script sea tan importante como en NB... te "obliga" aunque no quieras (con algunas taskdef de NB eso sí).
Yo encantado de que lo distribuya como proyecto NB :-D
Salu2
jmarranz, enhorabuena por sacar un framework en un tiempo en el que lo desable parece ser usar el que hacen otros. ¡Con un par! Y ademas estoy absolutamente de acuerdo con lo que dices de las licencias, aunque esto es un tema que deberia ir en otro hilo.
Mas iniciativas de estas deberia haber...
javierpaniza: ¿Se pueden crear portlets JSR-168?
No, es algo que tengo que estudiar, aunque tengo la impresión que la era AJAX y los mashups hará que los portles pierdan interés, daré prioridad a los mashups porque a día de hoy sólo se pueden hacer mashups con ItsNat usando iframe que no es la forma más elegante.
javierpaniza: En ese caso ¿en qué portales está testeado?
Acabo de parir :) el niño sólo tiene un día de vida, aunque ya sabe mucho todavía no ha hecho curriculum.
javierpaniza: ¿La licencia que usas permite incluirlo en un producto LGPL?
No, la licencia tendría que cambiar a AGPL, lo que si permite es usar código o librerías LGPL pero la resultado global sería AGPL. La AGPL v3 es la GPL v3 + un addendum que cubre el caso de aplicaciones web usadas como ASP (Application Software Provider) que obliga a publicar el código fuente.
Este caso es complicado porque la opción de licencia de código cerrado yo creo que tampoco valdría.
Llevado al caso de OpenXava, podría ser un "añadido" a OpenXava, no cambiaría la licencia de OpenXava pues es compatible con LGPL pero el resultado tendría que ser AGPL, alguien que hiciera una aplicación con el híbrido OpenXava/ItsNat tendría que liberarla como AGPL salvo que tuviera una licencia de código cerrado.
javierpaniza: Las estadisticas de descargas no funcionan para tu proyecto en sourceforge.
Por ahora no uso el sistema de SourceForge (tengo mi propio sistema de estadísticas de descargas), aunque no se si el número de descargas es un buen indicador de la calidad de un software, es un indicador de popularidad (aunque a veces coinciden).
javierpaniza: Esto es importante, porque es una de las cosas a considerar a la hora de escoger un producto de código abierto.
Yo creo (opinión no imparcial claro) que lo mejor es evaluarlo conceptualmente (co.o esto es lo que yo quiero) y evaluar su calidad con prototipos. Algo enormemente interesante del mundo de los frameworks web es que hay varios estilos, ItsNat es un nuevo estilo, estar agusto con un estilo de programación es enormemente importante. ItsNat es el resultado de lo que yo llamo "síndrome Jonathan Locke" este señor es el padre de Wicket y fue uno de los programadores de Swing, vivió alejado del mundo del desarrollo web hasta que cuando se enfrentó al mismo y vio lo que existía pensó algo así como "pero qué esto debe haber otra forma de hacer las cosas" y de ahí nació Wicket, mi sensación ha sido la misma.
javierpaniza: Y una última pregunta, ¿es posible testear desde el cliente usando HttpUnit o HtmlUnit?
Yo creo que no, y no es problema de ItsNat es un problema del soporte pobre de estos frameworks respecto a JavaScript y AJAX usa JavaScript, Selenium es una mejor alternativa porque usa el navegador de verdad. Sin embargo no necesitas ninguno de estos, ItsNat tiene su propio sistema de test funcional que puedes ejecutar desde el propio servidor y programado en Java, echa un vistazo al "Feature Showcase" opción "Server-Driven Test" abajo del todo.
Ibon, no recordaba eso, mea culpa. Acabo de poder bajarlo y he visto que, efectivamente hay un build.xml. Sin embargo, ¿por qué no decir que basta ejecutar Ant (o que se puede) para compilarlo en lugar de decir que es necesario usar NetBeans? O por lo menos comentar que los proyectos de NB son scripts de Ant y decir que hace falta cambiar las rutas absolutas que mete NetBeans a saco en el ...\nbproject\private\private.properties ya que estamos.
Una pregunta, José María. "mi sensación ha sido la misma"... ¿Incluyendo a Wicket en lo que viste cuando pensaste "pero qué es esto"? (Es mera curiosidad)
Hombre venkman, no me pongo a hablar de todo eso porque el hilo de jmarranz es sobre otra cosa... Ya he dicho algo: que NB mete sus taskdef propios, lo cual no lo hace agnóstico del todo (con maven si :-)). Y no he dicho otra cosa, que el usuario puede sobreescribir los targets en build.xml, y en teoría hacerlo independiente de NB (si no usa ningún task de ant de NB). Pero vamos, que esta discusión no va de eso.
Salu2
Después de echarle un vistazo, escribo solamente para... felicitarte y agradecer el trabajo y el esfuerzo en comunicar correctamente el resultado del mismo. Tendré que probarlo (si es posible sacar tiempo para ello) pero a simple vista parece que este famework apunta de forma certera en una buena dirección. Me ha hecho mucha gracia lo del "síndrome Jonathan Locke" :-) Yo llevo sólo 2-3 años de experiencia laborla como programador y _ya_ estoy algo cansado de aplicaciones web que usan tecnologías que parecen un salto atrás y que me hacen, para mi propia sorpresa, proclamar las bondades del Swing y de Java Web Start (quién me hubiera dicho esto hace pocos años !).
Lo dicho, ánimo con este proyecto. Intentaré contribuir. Un saludo
greeneyed: El primer detalle es que algo le ocurre al servidor (itsnat.sourceforge.net)
No tengo ni idea, no se si es porque es XHTML (el W3C me dice que es correcto salvo un par de chorradas), no se si es porque usa un miniframework propio que se basa en required, si hay algún problema de buffers, soy novato en PHP, el caso es que en local funciona perfectamente. El problema se resuelve haciendo "reload" y al segundo intento carga bien.
greeneyed: En cuanto al framework en si, algunas cosas no las acabo de ver. No usas XML en la configuracion, bien, ni que fuera el diablo, pero la configuración propones ponerla escrita en Java "a pelo" en un singleton? (al menos eso parece mostrar el ejemplo) o por otro lado dices que usen Spring o lo que quieran. Es decir, ¿no usa XML por que no usa nada y tu te lo has de montar?.
No, XML no es el diablo, XML es estupendo para declarar aquellas cosas que *con seguridad* podemos necesitar cambiar de una forma elegante y bien estructurada, JNIEasy la usa extensivamente y no hay alternativa salvo las anotaciones. Si a la hora de verdad necesitamos cambiar cualquier cosa lo mejor es sencillamente tener el entorno de desarrollo muy cerquita del de explotación y cambiar lo que sea o bien usar un lenguaje de script. Lo que no me gusta es la flexibilidad absurdamente forzada o la configuración declarativa innecesaria.
Por ejemplo ItsNat tiene una serie de flags, dichos flags se pueden definir llamando a métodos en varios niveles: nivel servlet (global), por template y algunos por instancia de documento (página) concreto. Se me pasaba por la cabeza hacer un sistema de XMLs ¿pero por qué? ¿qué problema hay con el hardcoded de flags que con absoluta seguridad NO van a cambiar en tiempo de explotación? ¿por qué meter un complejo sistema de XMLs obligatorios al programador cuando es posible que sólo necesite un par de flags optativos que puede poner en un .properties?
Respecto a los singleton instanciados a pelo, si te fijas en esos singleton sus constructores están vacíos, es decir no tienen nada de configuración ¿por qué voy a declararlos en un XML para que un framework Ioc me haga un simple new?. Hay otros, internos del mini-framework del Feature Showcase (no estamos hablando de ItsNat) cuyas dependencias son inyectadas llamando a métodos por el mini-framework, ¿por qué usar un framework externo IoC cuando el mini-framework ya actúa como un mini IoC?.Lo que he querido mostrar en ItsNat es que se puede evitar la programación declarativa no deseada ya sea a lo Spring a lo Struts etc, no me opongo a Spring me opongo a que sea un requisito para usar ItsNat. Parte del éxito de Wicket es esa liberación de la programación declarativa.
Hay gente como mi caso que nos apasiona la programación orientada a objetos de una forma brutal y las bondades de un simple compilador, ItsNat tiene 683 archivos java, muchos son interfaces, otros muchos clases con funcionalidades muy pequeñas, si esas 683 clases (caso extremo) estuvieran enlazadas via programación declarativa ahora mismo no estaría escribiendo esto porque las pastillas no me dejarían escribir :) , entiendo Spring como una capa para configuración y para servicios inherentemente muy flexibles pero tengo la impresión de que hay un abuso brutal del mismo como contaba William Louth padre de JXInsight en TheServerSide.
El caso del Feature Showcase, como ejemplo de aplicación relativamente complicada construida sobre ItsNat, es diferente, simplemente muestro que no es estrictamente necesario usar programación declarativa, no que no se deba usar.
Pero entiendo que haya gente que le guste la programación declarativa y podría meterla en el Feature Showcase por ejemplo para definir los ejemplos (features) y registrarlos en el núcleo del F.S. Y si metemos bases de datos, por ejemplo, pues seguramente Spring encaja bien porque ya tiene ya precocinadas plantillas de acceso a base de datos, aunque yo personalmente como motor IoC usaría Guice pero no puedo porque necesita Java 1.5.
greeneyed: Y se usa "puro" Java y "puro" DOM etc., bien, pero ¿la manipulación de la interfaz es toda en Java "hardcoded" y compilada en clases?
La manipulación de la vista es hardcoded en Java y para mi es una absoluta bendición porque permite toneladas y toneladas de rehuso, permite herencia de vistas, polimorfismo, especialización, delegación etc. Ojo si lees las DOM utilities y el funcionamiento de los componentes verás que hay mucho uso de patrones ya declarados en las vistas que son puro HTML, dichos patrones te dan ya precocinada la vista, el DOM viene a darle el toque: meter este texto en este nodo, cambiar este style a color rojo etc y usando los ItsNatVariableResolver y el sistema de variables ${} en las plantillas (lo único que hay de "lenguajes de expresión" en la vista) el DOM puede ser mínimo y muy independiente de la vista, es más si me apuras hasta puedes usar el lenguaje de expresión sólo necesitas el motor del mismo en Java y hacer un recorrido por los nodos del subárbol que quieras.
venkman: una pregunta, José María. "mi sensación ha sido la misma"... ¿Incluyendo a Wicket en lo que viste cuando pensaste "pero qué es esto"? (Es mera curiosidad)
Umm si y no, a Wicket le tengo mucho respeto porque el "estilo" a groso modo de programación es similar al de ItsNat y es un directo "competidor", pero en cierto modo cuando la idea me rondaba la cabeza pensaba "bien vale pero hay otra forma".
El problema de los frameworks web es que tienen que utilizar técnicas extrañas porque la naturaleza de lo que se manipula en el servidor es diferente a lo que ocurre en el cliente, por eso ItsNat significa "es natural" porque viene a ser un "coño si la vista del cliente quieres manipularla desde el servidor pues la replicas y ya está, ¡naturalmente!", el coño no está en la documentación oficial XD.
Respecto al uso de NetBeans
Una cosa estupenda del standard Servlet es que al final lo que vale es el .war. Si quieres hechar un vistazo en local con tu Tomcat, GlassFish o similar integrado o sin integrar en IDEs basta que hagas deploy del archivo dist/itsnat.war
Si lo que quieres es cambiar ejemplos, depurar etc fuera del NetBeans, te costará algo más porque ya estamos hablando de desarrollo, tendrás que crearte un proyecto web nuevo, en la web (sección download) y en el manual se cuenta qué es cada directorio de la distribución, no te costará mucho.
Conste que no soy usuario de Spring y lo del XML lo he mencionado por que en la documentacion esta como una de las cosas que no usa. Es una cuestión de gustos, no digo que no, pero hay cosas que prefiero poderlas manipular fuera de mis .class sin tener que recompilar y tener dos versiones. Y no digo que no se pueda en este caso, solo que te lo has de montar tú :). Que repito no digo que está mal, solo que me ha picado la curiosidad al leer que no usaba XML para la configuracion por ver que usaba y me ha sorprendido la respuesta "te lo montas tu".
En cuanto a la vista, bueno, yo ahi tambien prefiero que no este compilada y no depender de Java ni tener que reiniciar el contexto para cambiar un comportamiento o un color, pero ahi si que va a gustos y forma de trabajar.
Pero viendo que el framework esta dirigido a que todo lo controle un programador Java, pues tiene su sentido en ese contexto, aunque fuera de ahi no lo veo.
La documentación quizá algo sensacionalista, pero ahi se ve el entusiasmo :).
Lo dicho, suerte.
Jmarranz te felicito, excelente trabajo.
Tienes pensado incluir documentacion en español?
greeneyed: Que repito no digo que está mal, solo que me ha picado la curiosidad al leer que no usaba XML para la configuracion por ver que usaba y me ha sorprendido la respuesta "te lo montas tu".
Sí fue una elección consciente, por ejemplo el Feature Showcase usa varios archivos .properties para independizar donde están los archivos de los "fragmentos" del nombre usado en el registro y como forma de hacer carga de configuración en "batch" a través de un bucle en Java, todos esos fragmentos tienen la misma configuración, sería absurdo un sistema de configuración que obligara a repetir uno a uno siempre los mismos parámetros de configuración. Si algun día ofrezco un sistema de configuración será una alternativa a la forma programática que admite el estilo "batch".
greeneyed: En cuanto a la vista, bueno, yo ahi tambien prefiero que no este compilada y no depender de Java ni tener que reiniciar el contexto para cambiar un comportamiento o un color, pero ahi si que va a gustos y forma de trabajar.
No exactamente, las verdaderas vistas son las plantillas de las páginas que son archivos (X)HTML o las plantillas de fragmentos que también son archivos (los plantillas fragmento son trozos de (X)HTML que pueden ser insertados cuando se quiera y donde se quiera para evitar construir markup básicamente estático a base de DOM). Estos archivos pueden cambiarse en runtime, cuando hay una nueva carga de la página cambiada en disco el framework detecta ese cambio y carga la nueva versión, esto es aplicable también a fragmentos.
El DOM Java es más bien la lógica de la vista, la lógica de la vista es algo que no cambia frecuentemente es algo más que estética forma parte de la funcionalidad misma. Te ponía el ejemplo del color como ejemplo de respuesta a un evento que supone un cambio en la vista, pero si es simplemente un cambio de estética "estático" se puede hacer directamente en el archivo de la plantilla HTML incluso en runtime.
Por otra parte el DOM ofrece técnicas que permiten que el código DOM sea bastante independiente de la vista (de la estética), aparte del uso del ItsNatVariableResolver, con métodos tal y como un simple getElementById permite que los nodos cambien de sitio o con un cloneNode puedes conseguir hacer copias de trozos de DOM que ni siquiera sabes como son. Si la "estructura" de la vista (parte dinámica) no cambia es posible que no cambie la lógica DOM, muchas vistas diferentes pueden tener una misma "estructura", la manipulación DOM puede ser la misma si no cambia, por eso hablaba antes de rehuso de la lógica de la vista. En el F.S. por ejemplo el mismo código Java sirve para construir un tree con ul y con table, los componentes admiten incluso elementos SVG (para formar listas, tablas, árboles de círculos por ejemplo).
Hola José María,
tengo la impresión que la era AJAX y los mashups hará que los portles pierdan interés
Yo creo que no. Liferay tiene ya más de un millón de descargas, y su popularidad ha subido sobre todo en este útlimo año.
Por otra parte IBM vende WebSphere Portal Server, tus clientes lo compran y a tí te tocará hacer que tus aplicaciones corran ahí dentro, no puedes elegir.
Además si tienes que hacer una aplicación web y usas un portal como punto de partida tienes hecha la gestión de usuarios, la navegación por los módulos, integración con otras aplicaciones, estilo visual, etc. El punto de partida es mucho mejor que si no utilizas portales, o si no necesitarás un programador para hacer una gestión de usuarios, otro para hacer una estructura de navegación, un diseñador web para el estilo, etc.
Lo siento no he podido evitar el comentario sobre los portlets.
Sin embargo, en mi caso, es la licencia lo que hace que ni siquiera pueda considerar evaluar tu marco de trabajo.
Pero ¿quién sabe ? puede que tu producto evolucione, soporte portlets y cambies la licencia, y entonces ...
ok, leyendo tus respuestas a mis preguntas y a otras ya creo que me queda claro el funcionamiento (conceptuamente y a grandes rasgos claro) del framework. Me gusta la idea para aplicaciones web "clasicas" que incorporen funcionalidades ajax sencillas, por ejemplo el tipico combo relacionado con otro que se carga por XHR, campos con autocompletado, validación de formularios via XHR, mantenimientos CRUD etc,etc. Para estos usos si me parece un enfoque muy bueno y que facilita las cosas en gran medida. (por ejemplo validación de formularios con XHR es trivial con este framework y no lo es tanto si hay que hacerlo a manubrio).
Eso si, para aplicaciones donde quiera una UI cliente muy compleja me sigue gustando más hacer cada cosa en su sitio, programar el cliente en el cliente (en js) y el servidor en el servidor (en lo que sea), y como maximo usar alguna librería que me facilite las comunicaciones (gwt-rpc o dwr si hablamos de java en el servidor), por este motivo no me gustan nada cosas como icefaces, echo2 o en el nuevo RAP de eclipse.
Otra pregunta (que pesao soy xd) que antes se me quedo en el tintero, sobre el tema de comet ¿que enfque sigue el framework para implementarlo?, se hace polling?, se hace manteniendo siempre abierta una conexión http?, es configurable el modo?. Y luego dices que no es necesario usar un servidor especifico (jetty con las "continuations" por ejemplo), como haces para resolver el problema de que cada conexión abierta se lleve un thread del pool?
Justo estoy preparando un articulo sobre dwr "reverse-ajax" y es más que nada por comparar un poco y ver como has enfocado tu el problema. (el enfoque de dwr personamente me gusta bastante, tampoco se puede hacer mucho más y comet es un hack como un piano, se mire como se mire xd)
javierpaniza: Lo siento no he podido evitar el comentario sobre los portlets.
No hace falta que te disculpes lo que dije es una impresión no es una manifestación categórica, tampoco es un desprecio, no tengo bola de cristal, te aseguro que en mi archivo de características futuras ya estaban los portlets. Me refiero a lo siguiente: imagina que hace 3 años se dijera que la navegación por páginas perderá cada vez más protagonismo respecto a AJAX, seguramente dirían muchos que con AJAX hay un par de webs y que con struts etc millones, hoy nadie duda que un Struts2 sin AJAX no es una apuesta de futuro.
Mi sensación es que los mashups se solapan en parte con los portlets permitiendo integración de aplicaciones mucho más desacoplada e interactiva, no digo que sea mejor, simplemente más desacopladas e interactivas porque se hace todo a nivel de cliente (la integración), el típico ejemplo de Google Maps no necesita presentación (hay más el mundo de netvibes.com, facebook.com ...) y pronto empezarán a surgir proveedores de mashups incluso de pago que ofrecerán algo más que el tiempo y cuyos problemas de integración serán casi cero porque la libertad tecnologíca del proveedor es casi total.
Es un enfoque diferente a los portlets que están orientados a la instalación en un mismo servidor y a promover un mercado de portlets como aplicaciones, más que de servicios (caso de mashups), que me da la impresión de que no existe todavía.
Finalmente el mundo de los mashups llevado al extremo implica que al igual que cualquier empresa tiene su web es posible que también en el futuro toda empresa tenga su versión mashup simplemente para que puedas tener en una misma página varias miniwebs. Igualmente cualquier "aplicación web" tendrá su versión normal y versión mashup, el buscador de Google ya lo tiene, de hecho me parece extraño que Google no haya sacado su GMail en versión mashup (ojo por otra parte mashup=robo de datos por los otros mashups). Pero en todo esto hay mucha expeculación. Creo que ahora entenderás un poco mi jerarquía de prioridades ¿no?
remoh: Me gusta la idea para aplicaciones web "clasicas" que incorporen funcionalidades ajax sencillas
Creo que has pillado la filosofía. La filosofía de ItsNat es que el programador es que tiene el control, el control y el control. Es un enfoque muy conservador, por ejemplo, los componentes listas, tablas y árboles ofrecen soporte de selección de items (notifica al usuario qué elemento ha sido seleccionado) sin embargo no hay una decoración por defecto, porque no hay una forma universal de indicar que un elemento ha sido seleccionado, si se ofreciera (cambiando el fondo por azul por ejemplo) claramente sería substituible por el sistema del usuaro. No sigue la estela para nada de otros frameworks sofisticadísimos pero que como no te guste lo que hace el control... "pues te fastidias! es lo que hay, menudo raro que eres que no te gusta mi control que tiembla cuando pasas el cursor por encima".
En cuanto a tu "necesidad" de un cliente rico y en el servidor lo que sea con AJAX, como dije antes ItsNat tiene los eventos del usuario a modo de DWR y te podrían servir los fragments cuando necesites cambiar una zona completa. Más arriba te decía que un un simple span padre se pueden meter las partes que en el cliente se van cambiar a su bola (cerré el span con < y > y desapareció obviamente en el editor HTML). Pero vamos no te quiero vender la moto porque la tienes ya comprada que lo se :)
En cuanto al COMET, mi solución es la sencilla y obvia (es curioso sin embargo no la ofrece casi nadie, casi siempre son servidores especiales o contenedores de servlets especiales), retengo el hilo request y lo libero cuando hay novedad en el servidor y automáticamente se envía un nuevo request que vuelvo a retener. Lo de la retención de la conexión HTTP del navegador no lo solucionan las soluciones a medida que existen (creo recordar) en donde todavía no hay una solución estándar pues violan de hecho el estándar Servlet. Éstas soluciones resuelven el tema de la escalabilidad de hilos al hacer pooling de hilos al desacoplar la vinculación entre conexión HTTP/hilo en el servidor (que marca el estándar servlet).
Mi solución para aplicaciones web de no demasiados usuarios concurrentes no tiene gran problema más aun con los procesadores actuales de múltiples núcleos (varios hilos de verdad en paralelo), porque el problema no está tanto en que tengas cientos de hilos abiertos sino que estén todos a la vez vivos, en ItsNat el hilo del request está dormidito y se despierta cuando hay algo en el servidor que devolver, pueden haber cientos de hilos pero pueden estar todos dormidos y tu CPU tan tranquilita.
DWR hace justo eso, envia un request inicial que se queda retenido en el servidor y luego desde otro hilo puedes acceder a esas "conexiones" para enviar a través de ellas lo que sea necesario, en ese momento envia los datos a través de la conexiónes abiertas y los vuelve a dormir (por defecto no cierra la conexión cada vez que envia datos, las mantiene abiertas durante 60 segundos, aunque por configuración se le puede las cierra cada vez que se envien datos).
Luego otro tema es si esas conexiones "retenidas" ocupan o no un hilo del thread pool del contenedor de servlets, como bien dices según la especificación de servlets tiene que ocupar uno porque se sigue el modelo "thread-per-request". Lo que hace por ejemploo jetty es una ñapa (lo llaman ·"continuations" que queda mejor que ñapa eso si), en lugar de hacer "wait()" del hilo que hacen es lanzar una excepción para desvincular el hilo de la request y luego capturar la excepción dentro del app-server y guardar la request, luego puedes despertar la continuation y se vuelve a asociar un hilo a la request y se sigue pa'lante. Vamos que todo el tinglao no es más que un mecanismo para poder devolver el hilo al thread pool en lugar de sólo dormirlo, en cuanto a cpu no se gana nada (es más se pierde algo en este proceso) la ganancia esta en cuanto a la memoria consumida por el servidor, para aplicaciones con muchos (pero muchos) usuarios puede suponer algún ahorro (¿cuanta memoria ocupa un hilo?).
Supongo que esto explica que no sepamos nada de ti desde el openjavaday... se ve que has aprovechado el tiempo ;-)
Jmarranz, mi mas sincera enorabuena. Desde luego lo tuyo tiene merito. Mucho animo y mucha suerte.
Tambien muy buen hilo, he aprendido mucho leyendolo. Me ha gustado mucho el punto de vista de jmarranz sobre portlets/mashups. Sólo una duda, remoh, por qué dices que con XHR la validacion de formularios es trivial?
César.
remoh: la ganancia esta en cuanto a la memoria consumida por el servidor, para aplicaciones con muchos (pero muchos) usuarios puede suponer algún ahorro (¿cuanta memoria ocupa un hilo?).
No, yo creo que el problema no es en absoluto la memoria, date cuenta de que cada usuario sólo necesita un request retenido para tener COMET y por tanto un hilo retenido, la memoria consumida por el contexto de ese hilo es absolutamente ínfima en comparación con la información de estado que guarda el servidor sobre el cliente (sesión, página). El problema está en el scheduler de hilos, cuando hay miles de hilos el scheduler pasa más tiempo averiguando quien le toca que ejecutando los hilos, aunque en mi opinión esto sólo ocurre si los hilos están despiertos, pero aunque estén dormidos/parados imagino que también tendrá que recorrerlos para ver si ya les toca despertarse por ejemplo en el caso de hilos dormidos con un sleep.
Por tanto cuantos menos hilos menor gestión, pero yo creo que en el tema de la escalabilidad suele haber mucha grandilocuencia y pocos servidores de aplicaciones web pueden presumir de una concurrencia de miles de usuarios a la vez.
anonimo: Sólo una duda, remoh, por qué dices que con XHR la validacion de formularios es trivial?
Respondo por remoh en lo que toca ItsNat pero es extrapolable a cualquier framework AJAX basado en componentes. Lo que sigue es aplicable a ItsNat pero también a cualquier framework AJAX decente, remoh podrá precisar en lo que respecta a otros tal y como GWT.
Cuando un elemento de un formulario (una caja de texto, combo etc) cambia, los frameworks AJAX con componentes envían automáticamente el cambio al componente del servidor actualizando el mismo. El resultado es muy chulo porque a nivel de programación es como si el usuario escribiera directamente en el componente del servidor, en el caso de ItsNat es más real aún porque por ejemplo el atributo value del objeto DOM input en el servidor tiene el valor que ha puesto en el cliente (en el cliente sería la propiedad value).
De esta manera se pueden validar los formularios con código en el servidor y no en el cliente (JavaScript) porque cuando el componente cambia cortesmente notifica a un listener Java del programador (si existe) dicho cambio, en ese momento el programador puede validar si lo que ha escrito es correcto (formato etc) si no lo es puede echar la bronca al cliente (con un alert, un cambio visual en el componente por ejemplo un cambio de color, un mensaje al lado etc) e incluso volver a poner el valor anterior. Respecto a volver a poner el valor anterior, ItsNat tiene un componente similar a JFormattedTextField de Swing que hace esto automáticamente.
También es posible otra estrategia de validación de formularios en el caso de componentes con vínculos, dejar hacer al usuario y cuando pulse un botón tipo "Aceptar Cambios" o similar entonces hacer las validaciones simplemente recorriendo los componentes en el servidor pues sabemos que cuando ha pulsado el botón el formulario del servidor será el mismo que el del cliente.
Por otra parte el concepto de formulario cambia en el mundo AJAX si estamos dentro siempre de la misma página, el form no solo es prescindible sino que debe serlo, los elementos de un formulario pueden vivir sin problemas sin un form que los recubra. Si no cambiamos de página el "submit" ya no tiene sentido, el "envio de formulario" en AJAX es más bien la aceptación de los datos del usuario como buenos como orden de guardar los datos del formulario en base de datos y quitar de enmedio el formulario con otro trozo de HTML. Es más en teoría podrían guardarse incrementalmente los datos del usuario en base de datos, en cada cambio válido de un control de formulario (por ejemplo actualizando la propiedad correspondiente en el POJO controlado por Hibernate, JPA, JDO etc o bien a base de JDBC con UPDATE de un sólo parámetro).
La "instantaneidad" de los cambios via AJAX tiene la ventaja de que podemos llenar un combo según el cambio de selección de otro etc sin recargar la página completamente que es la técnica antigua.
anonimo: Tienes pensado incluir documentacion en español?
No te doy esperanzas salvo que el éxito de ItsNat fuera arrollador y las editoriales me persiguieran como a la Pantoja je je pero no soy tan optimista. Algún tutorial para javaHispano sí se hará y posiblemente un blog ténico bilingüe obviamente también castellano.
Una pregunta. ¿Qué facilidad ofrece para trabajar con y sin Javascript? Quiero decir de automáticamente ver una versión sin Javascript cuando no está disponible pero con él cuando sí.
Lo pregunto principalmente porque el ejemplo de "sin Javascript" es bastante básico, y no veo hasta qué punto sería una elección que habría que hacer de antemano.
Enhorabuena por el framework, parece muy interesante.
La única pega que le veo es que no aproveche (por lo que creo entender) el soporte de comet de los contenedores que ya lo soportan (tomcat, jetty, glassfish,bea,...) aunque sea de forma no estándar, al menos el del más usado estaría bien.
El problema de comet no está en los hilos. Aunque los retengas no vas a solucionar el verdadero problema que es el bloquear la conexión física. Esa conexión es lo realmente caro en cuanto a recursos como memoria, ficheros, etc. 150 usuarios => 150 conexiones => X hilos => bang, límite de Tomcat. 1000 usuarios => 1000 conexiones => X hilos => bang, límite de linux. (podríamos seguir amplicando recursos pero siempre nos toparíamos con un límite, y además estaríamos desperdiciando enormemente dichos recursos) etc. etc. y hoy en día para algo serio en Internet (ojo, no intranets), 1000 usuarios en un sólo server es muy, muy poco.
Tomcat, Jetty, etc. te permiten reusar esas conexiones multiplexándolas para múltiples clientes, y ahí es donde realmente se gana. A mi, personalmente me gusta más la solución de Tomcat que la de Jetty.
Saludos.Hace no mucho intenté probar el Grizzly de GlassFish 2.0 para ver si lo incorporaba de forma opcional, el problema fue que no se llevaba bien con NetBeans 5.5 (tampoco 5.5.1 resolvió todos los problemas) y se hacía un lio con el Tomcat que lleva integrado y no conseguí hacerlo funcionar, imagino que en NetBeans 6.0 estará resuelto el tema.
El problema del mundo Comet es que NO hay un estándar, cada uno lo hace a su bola, si consiguiera integrar los diferentes COMET en el framework como añadidos opcionales (plug-in) pues sí, de hecho las interfaces COMET que uso están pensadas para que por debajo existan implementaciones diferentes, en teoría el código fuente del usuario podría no cambiar y detectar por debajo el servidor de servlets que se está usando. Este es el caso de Grizzly, el problema son soluciones como la del Tomcat que define sus propios servlet, su técnica es muy interesante pero muy muy intrusiva y difícilmente podría ItsNat ocultar los detalles y ofrecer una implementación transparente.
Mi impresión es que es mejor esperar porque el JSR 315 (Servlet 3.0) va unificar todo este lio, pues a día de hoy la "demanda" de COMET escalable, yo creo que es muy muy escasa todavía, de hecho salvo que sea problema mio no conseguí hacer funcionar Grizzly en NetBeans (aunque ItsNat si funciona en GlassFish v2) por lo que te puedes hacer una idea del grado de penetración de COMET en Java.
En cuanto a la escalabilidad el problema no es un flag de Tomcat o de Linux, se cambia y punto, hace años hice una prueba de correr 3000 hilos ¡vivos! en Windows en un pentium III de 1Ghz y funcionaba aceptablemente (y eso que realmente el procesador era monohilo). El máximo número de sockets creo que es del orden de 64000 (2^16). El problema es que la gestión de tantos hilos y tantos sockets puede degradar el sistema.
Por otra parte hay mucho mito, en mi opinión, sobre el tema de los usuarios concurrentes, los 1000 usuarios que mencionas me da la impresión de que hablas de 1000 sesiones simultáneas lo cual no significa que el servidor esté aguantando 1000 requests concurrentes, muy muy pocas empresas españolas pueden presumir de tener más de 1000 requests concurrentes el consumo de recursos de 1000 consultas concurrentes a una base de datos es mucho mayor que el problema de los threads o scokets, y en el caso de COMET dichos 1000 requests (hilos, sockets) retenidos estarían la mayor parte del tiempo aburridos. Si me equivoco me encantaría saberlo con ejemplos reales.
Por otra parte yo creo que el problema de la escalabilidad no está en los sockets sino más bien en los hilos pues el HTTP 1.1 normalmente funciona en modo keep-alive por lo que el navegador con COMET o sin COMET tiene un socket siempre abierto con el servidor.
Mi solución puede satisfacer al 90 y mucho por ciento de las aplicaciones web, las de muy alta concurrencia seguramente no, para ellas lo mejor es usar el sistema de timers de ItsNat que viene a ser un java.util.Timer en web (los métodos son casi idénticos), con AJAX por medio la escalabilidad del sistema de timers no es gran problema porque si no hay nada nuevo el request retorna al cliente sin traer nada, y con varios segundos (unos 3) de demora, el servidor puede aguantar un montón de clientes porque un servidor en 3 segundos (depende del entorno y tipo de aplicación) puede hacer mucho y más aun con AJAX por medio en donde no hay procesos completos de página. Lo que hace tiempo era una chapuza (la actualización por temporizador) hoy es una opción viable de tener un server push de mentira (es pull realmente) pero que funciona sin saturar el servidor.
venkman: Una pregunta. ¿Qué facilidad ofrece para trabajar con y sin Javascript? Quiero decir de automáticamente ver una versión sin Javascript cuando no está disponible pero con él cuando sí. Lo pregunto principalmente porque el ejemplo de "sin Javascript" es bastante básico, y no veo hasta qué punto sería una elección que habría que hacer de antemano.
No entiendo del todo la pregunta. ItsNat no aporta nada para detectar si un navegador tiene o no activado JavaScript, esa detección se puede hacer fácilmente con técnicas como ésta, es decir usando los tags script y noscript adecuadamente se puede redirigir la aplicación a la versión de la misma con AJAX y sin JavaScript (ItsNat introduce otro caso más y es JavaScript enabled pero sin AJAX, el caso non-AJAX).
Lo que pretende mostrar el ejemplo de No-JavaScript y No-AJAX es que ItsNat también sirve para hacer aplicaciones en ambas situaciones, simplemente hay que tener en cuenta de que no hay eventos, el ciclo de una página es sólo la carga (en una aplicación con AJAX es carga y eventos), en dicha fase de carga se puede utilizar la manipulación a medida del DOM, inserción de fragments e incluso un funcionamiento limitado de los componentes, es decir sin eventos (hay ejemplos en la parte final del Feature Showcase).
Otra cosa interesante de los ejemplos de uso de ItsNat "degradado" es que se puede pasar markup del DOM de una página a otra salvando temporalmente en la sesión la página antes de pasar a la siguiente, de esa manera podemos copiar el estado de la vista en su parte dinámica (la que interesa) a la nueva página evitando mucho trabajo de proceso de la nueva vista y minizando el paso de datos via cliente.
Usando componentes se puede llegar más lejos pues podemos reutilizar los data model y copiar el estado de selección de los componentes de la página anterior antes de perderla definitivamente evitando pasar esa información por el cliente. ItsNat de todas formas no trata de simular la reconstrucción del estado de los componentes en caso de recarga como hacen otros frameworks tratando de simular que ha sido el proceso de un evento y que ha habido un cambio incremental cuando realmente se ha recargado la página entera, eso está bien para navegación clásica, son trucos pre-AJAX, pero con AJAX todo eso yo creo que pasará a la historia al igual que el WAP/WML de los móviles, que tuvo su tiempo pero que ya no pinta nada.
Por cierto se me olvidó poner en la web el JavaDoc, he añadido un enlace al mismo en la página de soporte.
jmarranz, soy el anónimo anterior.
Estoy totalmente de acuerdo con lo de Servlets 3.0.
Ahora bien, asumir que el soporte de HTTP 1.1 diluye el problema es un error, al menos en mi opinión. Keep-alive es algo no muy bien especificado, sobre todo cuando dejan la puerta abierta a que cualquiera cierre la conexión con la directiva close, y que con lo que normalmente siempre habrá que pelear. El decir que la conexión se mantiene abierta siempre no es cierto. Depende de los dos sentidos. Por ej. en firefox el valor por defecto es 5 min. pero si te conectas contra Apache pues éste por defecto te desconectará a los 15 segundos. Y eso si no te ha desconectado antes cualquier proxy intermedio que es lo más probable.
Dicho esto, sólo escenarios de streaming de video, música, y vamos cualquier cosa que necesite un stream continuo necesita realmente la optimización de estas conexiones (sí, estaba hablando de 1000 sesiones simultáneas, y no es nada para un youtube-killer). Pero hay productos que te permiten multiplexar miles de requests con unas pocas decenas de conexiones físicas, y ahí está realmente la optimización ya que tienes menos threads (pool manual) y menos conexiones físicas, y menos descriptores, y menos memoria, y menos.... Pero acepto que es marginal... a no ser que sea tu negocio claro :D
Cambiando de aires de todos modos, a la hora de la web en mi opinión lo mejor es una aproximación híbrida. En serio, y que no te parezca mal pero no creo que tu solución sea la mejor. ¿e.g. qué pasa si 500 usuarios se les da por cambiar de página? ¿vas a estar enviando eventos a alguien que ni siquiera está viendo la página? ....... ¿y si el servidor no tiene eventos? ¿vas a mantener las requests y los hilos ahí sin hacer nada hasta que pase algo? ....... ¿y por qué forzar a hacer una nueva request si de pronto llegan 30 updates al servidor... eso van a ser 30 request nuevas.? ¿no sería mejor mantener la conexión abierta por x segundos y después de ese tiempo devolver la conexión forzando al usuario a hacer una nueva request pero sólo si está realmente activo y no jugando al mmorpg que acaba de abrir hace 2 segundos?
Saludos.
Interesante discusión!
Aunque puede ser cierto que la necesidad de comet a día de hoy no sea muy grande, quiza es también porque ciertas cosas ni se plantean hacer en web, google docs por ejemplo, ¿cuantos usuarios simultaneos puede tener editando en común?, claro que no creo que google use tomcat o jetty como app sever jeje, ni tampoco creo que mañana nos pongamos en un proyecto que tenga el número de usuarios de google docs (bueno quien sabe... jeje)
Sin embargo aunque se vaya a usar comet en aplicaciones de intranet, con una carga de usuarios mucho menor, creo que si es importante entrar en estas consideraciones de escalabilidad antes de usar esta "tecnología" muy alegremente para no llevarnos sorpresas desagradables.
sobre el tema de la memoria consumida por thread:
la memoria consumida por el contexto de ese hilo es absolutamente ínfima en comparación con la información de estado que guarda el servidor sobre el cliente (sesión, página)
De esto no estaria yo tan seguro, ten en cuenta que por cada thread nuevo se reserva un stack para el solito, se use esta memoria o no se use, en la jvm hay un parametro que permite definir el "thread stack size" y si lo pones muy bajo corres el riesgo de una excepción "stackoverflow". En esta pagina de jetty puedes ver una tabla sobre el consumo de memoria en función del número de threads. Vamos que por cada thread se consume una cantidad "no despreciable" de memoria que si hablamos de escalabilidad puede tener cierto impacto.
Resumiendo hay dos cosas tener en cuenta:
número de conexiones TCP/IP simultaneas: Aqui dependemos del sistema operativo y del web server que estemos utilizando y como trate las conexiones, al ultimo anonimo (registrate!! por cierto), tienes información sobre el multiplexado de conexiones que hacen tomcat, jetty o cualquier otro conenedor de servlets?, no tengo claro este tema, en principio si tienes una conexión TCP/IP abierta la tienes abierta con un socket (y sus buffers de entrada/salida) ocupando memoria en la implemtación de TCP/IP del SO que uses. Y para poder hacer server-push en ultimo termino necesitas el socket abierto, no veo la forma de poder limitar el número de sockets abierto a nivel del SO, se me esta escapando algo?
número de threads simultaneos: basicamente si tenemos o no un thread por conexión. En mi opinión si se puede evitar sin otros costos añadidos, mejor evitarlo.
Luego sobre la solución de jmarranz del timer, basicamente preguntar al servidor cada x tiempo "tienes algo para mi", en muchos contextos puede ser buena solución, dependerá de la aplicación que este desarrollando y de los requisitos de latencia y carga al servidor que quiera cumplir. Por ejemplo para un monitor de un BPM o algo similar, con que se actualize cada 20 segundos puede ser más que suficiente y no sobrecargo al servidor ni necesito chorrocientas conexiones simultaneas, pero claro si quiero hacer un chat o una aplicación "colaborativa" donde necesite comunicación instantanea entonces no me vale, todo depende.
jmarranz, a lo que me refiero no es simplemente a detectar si el cliente tiene o no javascript disponible, pero gracias de todos modos.
Lo que pregunto es si ItsNat ofrece alguna facilidad para utilizar las mismas plantillas cuando el cliente no tiene Javascript. Es decir, si automáticamente degrada el comportamiento de los componentes o si es algo que tiene que hacer el desarrollador manteniendo dos juegos de plantillas.
Hacía referencia a ese ejemplo porque en ese caso las plantillas (el XHTML) no lleva nada que haga referencia a ItsNat. Es un caso bastante trivial: si no quieres Javascript no lo pongas. Pero mi pregunta no iba por ahí, sino que preguntaba por la capacidad del framework de automáticamente degradar las plantillas sin tener que usar dos juegos.
No se trata sólo del thread. Un thread claro que no ocupará mucho, pero en este caso el framework guarda la request de Tomcat con el thread. Y probablemente la request ya no sea tan ligera.
Seria interesante saber también el efecto que tiene ese tipo de juegos sobre el contenedor. Es decir, ¿como va a reaccionar un servlet si se da cuenta que de repente se le ha agotado el pool porque le hemos parado todos los hilos del servlet /PepitoDeLosPalotesServlet? ¿qué políticas siguen los diferentes contenedores al respecto?
anónimo: Cambiando de aires de todos modos, a la hora de la web en mi opinión lo mejor es una aproximación híbrida. En serio, y que no te parezca mal pero no creo que tu solución sea la mejor. ¿e.g. qué pasa si 500 usuarios se les da por cambiar de página? ¿vas a estar enviando eventos a alguien que ni siquiera está viendo la página? .......¿y si el servidor no tiene eventos? ¿vas a mantener las requests y los hilos ahí sin hacer nada hasta que pase algo? .......
Bueno ante todo el COMET no lo he inventado yo :) aunque se puede usar sin AJAX es el añadido obvio que surge cuando entras en el mundo AJAX. Es decir es un añadido, ItsNat tiene soporte de COMET pero el funcionamiento normal no usa COMET, es un plus que sólo es útil cuando existe un proceso autónomo en el servidor que quiere notificar de sus novedades a uno o varios clientes cuando estas ocurran, esto no es la necesidad normal de la aplicación web típica. Ejemplo: un sistema de alertas en tiempo real para periodistas deportivos en radio o televisión, aunque un timer razonable valdría, via COMET se enterarían al instante de cualquier gol, falta, etc, etc.
Volviendo a tus preguntas: ItsNat detecta cuando el usuario deja la página, eso no es problema, también el hilo productor de eventos puede tener una política de tiempo límite y cerrar el CometNotifier del usuario cuando lleve demasiado tiempo conectado. En cuanto a que el hilo productor no produzca ninguna novedad durante demasiado tiempo, el CometNotifier tiene un método setExpirationDelay que especifica el máximo tiempo que ha de esperar a recibir novedades, pasado ese límite se desconecta el cliente, al desconectarse el cliente si el usuario no hace ninguna acción la sesión expirará.
anonimo: ¿y por qué forzar a hacer una nueva request si de pronto llegan 30 updates al servidor... eso van a ser 30 request nuevas.?
No funciona así, el hilo productor de novedades puede acceder a la vista y hacer lo que le de la gana con ella y cuando quiere que el cliente se entere llama al CometNofitier.notifyClient() que libera el request el cual actualiza al cliente y al mismo tiempo le dice al cliente que vuelva a enviar otra request para continuar el proceso COMET, todo ello por debajo no hay que programar nada. El propio hilo productor de novedades puede tener la política de no llamar al notifyClient() más de una vez por segundo por ejemplo pues eso significa que hay demasiadas novedades seguidas, y al cliente le va a dar igual recibir cinco juntas que de una en una porque el usuario ni se va a enterar pues es un ser humano con sus limitaciones temporales. Todo esto se sale de ItsNat y depende más del sentido común y buen hacer del programador que use el servicio COMET. Si surge un patrón de uso lo suficientemente universal podría meterse quizás en el CometNotifier.
anónimo: ¿no sería mejor mantener la conexión abierta por x segundos y después de ese tiempo devolver la conexión forzando al usuario a hacer una nueva request pero sólo si está realmente activo y no jugando al mmorpg que acaba de abrir hace 2 segundos?
Es lo que te decía del productor de eventos, él puede decidir si echar a un usuario que lleva demasiado conectado cerrando su CometNotifier, al mismo tiempo le puede enviar un confirm en JavaScript a través del cual podrá decidir el usuario si quiere seguir viendo eventos (abrir un nuevo CometNotifier).
Lo de que se vaya o esté jugando al mmorpg es un tema no resuelto, para ello se necesitaría interaccionar con la webcam y con visión artificial detectar si el careto sigue observando la pantalla o detectar si tiene cara de jugar al mmorpg, por supuesto esto último es de coña (bueno quien sabe la detección de rostros ya es algo normal...). Qué más quisieran los periódicos online que tienen un refresco automático saber si hay alguien viendo la pantalla, lo máximo que pueden hacer es dejar de refrescar tras un cierto tiempo, es lo que hacen los players de las radios online pasado un cierto tiempo sencillamente se paran y tienes que darle al play para seguir oyendo.
jmarranz, felicidades por ItsNat y por tu entrevista en "El país" del día de hoy que buena foto te han tomado :-). Estuve buscando en la web del diario pero no han subido la entrevista, que quería enlazarle aquí.
Un trabajo muy interesante, José María.
º L º
remoh: De esto no estaria yo tan seguro, ten en cuenta que por cada thread nuevo se reserva un stack para el solito
Yo si estoy seguro (bueno, no certeza absoluta), de todas formas el enlace que envías de jetty es muy bueno, aunque 64Kb por stack/thread me parece mucho pues Java hace un uso intensivo del heap más que de la pila pero puedo creérmelo, algunos servidores de aplicaciones/servlets son tan enrevesados que tu método es llamado pasando antes por un montón de niveles.
Y digo que estoy seguro porque la programación AJAX utilizada extensivamente tiene su reverso tenebroso (respiración profunda de darth vader) y es que el mantener el estado del cliente en el servidor para enviar sólo los cambios tiene su precio en memoria y no hablo tanto del framework concreto. Por ejemplo lo normal es que tengas la misma lista de datos en el servidor que está viendo el cliente, tal que cuando el usuario añade uno nuevo lo añades a la base de datos pero no necesariamente necesitas hacer de nuevo una consulta y reenviarlos de nuevo (suponemos que no hay cambios concurrentes), el gran avance es que el servidor tiene menos trabajo (más escalable), menos tráfico, mejor experiencia del usuario... pero usa más memoria.
Conclusión: ciertamente como bien apunta jetty el consumo de memoria de los threads en COMET es importante, no es despreciable, joder 700Mb por 10000 usuarios es mucho, pero es que ¡son 10000 usuarios!, pero intuyo que el mantener la información de estado en el servidor de esos 10000 usuarios debe dejar frio esos 700Mb, de todas maneras ciertamente cuenta. Insisto yo creo que es más preocupante un scheduler que tiene que gestionar 10000 hilos el cual puede perder mucho tiempo averiguando a cual le toca (no nos engañemos cada núcleo es prácticamente monohilo). Tengo que estudiar más el tema aunque no me preocupa mucho porque Google todavía no me ha preguntado por el asunto y hay muy muy pocos Googles XD
ecamacho: felicidades por ItsNat y por tu entrevista en "El país" del día de hoy que buena foto te han tomado :-).
¡¿Buena?! joer que les costaba meter un poco de Potoshop aquí y allá (bueno tampoco hay mucho que hacer es lo que hay).
Un trabajo muy interesante, José María. º L º
Gracias Luismi un saludo desde el SIMO. Joer teneis que ver como se las gastan en marketing algunos, me siento acomplejado, como para escribir un libro en plan "como llevar a la ruina a tu joven empresa en un par de SIMOs", los que tengo enfrente se han traído hasta un par de sillones de casa.
Para los "hermanos" latinoamericanos: el SIMO es una feria de tecnología que se celebra en Madrid estilo CeBit pero más modesta, a unos cuantos desarrapados nos conceden un stand por la cara a cambio de que después les barramos los pabellones (esto es broma), la verdad es que se lo dan a empresas jóvenes.
Lo del uso de memoria para mantener estado no es directamente provocado por AJAX, esto depende de tu arquitectura y del framework que utilizes, con frameworks de lado cliente puedes optar por mantener el estado (o gran parte de el) en cada cliente y en el servidor tener servicios stateless (o que almacenen un estado minimo). Claro que este enfoque también tiene sus problemas...
Hombre y lo de tener 10000 usuarios simultaneos pues si que es una burrada, si tenemos una aplicación con ese número de usuarios probablemente podriamos contratar a un tio para que se currara la escalabilidad de la aplicación y mientras tumbarnos a la bartola jejeje.
PD: podias a ver avisado de la entrevista en el Pais, no suelo comprar periodicos rojuchos (es broma, es broma jeje) pero por una vez lo hubiera comprado.
jmarranz: No funciona así, el hilo productor de novedades puede acceder a la vista y hacer lo que le de la gana con ella y cuando quiere que el cliente se entere llama al CometNofitier.notifyClient() que libera el request el cual actualiza al cliente y al mismo tiempo le dice al cliente que vuelva a enviar otra request para continuar el proceso COMET, todo ello por debajo no hay que...
Creo que no me has entendido ese punto. Lo pongo más claro. Si tengo servlet que esta enviando cosas al cliente cada segundo, el proceso de "parar la request - esperar - notificar - soltar la request - hacer una nueva request" no es eficiente, ni en cuanto a consumo de ancho de banda ni en cuanto a rendimiento (latencia). Es más eficiente: "parar la request - notificar - notificar - notificar - notificar - ... - tras 1 min. soltar la request - hacer una nueva request".
Pero eso puede ponerse para una nueva versión :)
venkman: Lo que pregunto es si ItsNat ofrece alguna facilidad para utilizar las mismas plantillas cuando el cliente no tiene Javascript. Es decir, si automáticamente degrada el comportamiento de los componentes o si es algo que tiene que hacer el desarrollador manteniendo dos juegos de plantillas.
Vale creo que ya te entiendo, yo creo que más bien te refieres a widgets o componentes ya cocinados. Pensemos fuera de ItsNat, en otros frameworks puedes tener widgets con muchas cosas ya hechas, que por ejemplo cuando pasas el cursor por encima se ilumina algo etc, eso es a base de JavaScript, dicho widget en modo no JavaScript automáticamente podría degradarse. El "problema" es que esos widgets son tipo caja negra. En ItsNat no hay componentes de caja negra, los componentes de ItsNat son tan abiertos que ni siquiera ellos deciden cual es la vista, el componente el pide al programador una "estructura" de la vista en el caso de que no le sirva la de por defecto, la vista la define el programador, en cierto modo podría considerarse ItsNat un meta-framework, el Feature Showcase es un ejemplo de widgets sencillos pero "completos", el programador "completa" a su gusto lo que "falta": la vista, el efecto de la selección, el data model etc, el propio usuario puede decidir si añadir efectos visuales en JavaScript puramente cliente si quiere.
A donde quiero llegar: pues que depende si tu componente a medida usa JavaScript o no eso es más tu terreno. En ItsNat puedes decidir si tu template (página o fragmento) usa o no JavaScript, pero nada impide que un mismo template (archivo) pueda ser registrado dos veces, usando JavaScript y sin JavaScript usarías dos nombres, el template puede no tener nada de JavaScript pues recuerda que tú puedes inyectar via DOM añadiendo elementos script o via ItsNatDocument.addCodeToSend el JavaScript que quieras a posteri, por lo que en runtime puedes tú mismo decidir si añadir o no tal o cual efecto en JavaScript.
El ejemplo que has visto en el F.S. de "no JavaScript" no usa componentes, mira el ejemplo "JavaScript Disabled and Components" abajo del todo, dicho ejemplo muestra cómo la plantilla y el código de carga de una página de un template con componentes sin JavaScript puede ser prácticamente idéntico a la versión con AJAX, la gran diferencia es que no hay eventos DOM y sí los componentes de ItsNat tienen un modo JavaScript disabled pues aún sin eventos el sistema de separación de modelo, vista, lógica de vista y gestión de selección es útil incluso sin eventos.
Realmente es el propio núcleo el que sencillamente no hace nada cuando se llaman a métodos tal y como addEventListener que en modo normal generan JavaScript, obviamente ya no estamos hablando de AJAX por lo que esto tiene un impacto en el programa Java en sí, la vista puede no enterarse de si se usa JavaSscript o no. Ahora bien a base de HTML puro y con lógica de vista y negocio a base de Java puedes hacer dos webs ,AJAX y sin JavaScript, reutilizando muchísimo, por no hablar de la copia de markup de una página a otra que es una forma de reutilizar vista (real, no plantilla) en modo no JavaScript en runtime.
anónimo: Si tengo servlet que esta enviando cosas al cliente cada segundo, el proceso de "parar la request - esperar - notificar - soltar la request - hacer una nueva request" no es eficiente, ni en cuanto a consumo de ancho de banda ni en cuanto a rendimiento (latencia). Es más eficiente: "parar la request - notificar - notificar - notificar - notificar - ... - tras 1 min. soltar la request - hacer una nueva request".
No nos entendemos, en ItsNat "notificar = soltar la request + actualizar cliente + retener nueva request" , por eso te decía que el proceso background puede cambiar la vista o cuanto quiera sin que el cliente se entere, también con addCodeToSend, el "para enviar" no significa que se envíe en ese momento, todos esos cambios en la vista en el servidor y el JavaScript añadido vía addCodeToSend son guardados por ItsNat como JavaScript interno pendiente de enviar al cliente cuando algun request retorne al cliente, por eso te decía que el proceso background es el que decide cuando y con qué frecuencia quiere que el cliente se entere (=notificar) de todo lo que ha ocurrido, es decir que la vista cliente se sincronice con la servidora y se ejecuten las órdenes en JS recibidas. No se si ha quedado claro ahora.
jmarranz, pues no, no nos entendemos...
No nos entendemos, en ItsNat "notificar = soltar la request + actualizar cliente + retener nueva request"
Yo sólo quiero saber que significa retener nueva request. ¿de dónde sale esa "nueva request"? ¿quién la realiza?
anonimo: Yo sólo quiero saber que significa retener nueva request. ¿de dónde sale esa "nueva request"? ¿quién la realiza?
Ah vale, cuando se llama a CometNotifier.notifyClient la request retenida se suelta llevando lo que hay pendiente al cliente y automáticamente el framework en la parte cliente hace una nueva request via AJAX , porque sabe que está en un proceso COMET, dicha nueva request es retenida de nuevo en el servido porque el servidor sabe que es para continuar el proceso COMET abierto. Cuando se destruye el CometNotifier se suelta la request actual y se le dice al cliente que no envíe otra nueva, que se acabó la fiesta que basta ya de COMET.
Hola,
supongo que este post llega tarde, pero estaba mirando por internet y he visto que aptana tiene un framework, bueno un servidor, que hace cosas parecidas a ItsNat:
http://www.aptana.com/jaxer
Lo conocias ??? Es de verdad un competidor, o hace cosas diferentes ?
saludos, r
Escribe tu comentario