miércoles, 10 de octubre de 2012

Javascript: The Good Parts y JSLint

Recientemente parece que el libro Javascript: The Good Parts me persigue allá donde vaya.

Hace poco lo conocí a través de twitter, pero justo hoy, en el evento html tour de Madrid de Plain Concepts, se ha vuelto a recomendar la lectura de este libro.

Lo cierto es que cuando lo tuve en mi poder lo devoré en un solo fin de semana. Tampoco es ningún mérito, el libro es pequeño y no se anda con rodeos.

Después de su lectura, una sola idea ronda por mi cabeza “Javascript es un lenguaje incomprendido”.  Yo al menos no tengo ningún reparo en reconocer que, antes de la lectura de este libro, mi opinión sobre Javascript distaba de ser algo positivo. Además, también distaba de tener el suficiente conocimiento como para juzgarlo con conocimiento de causa.

Hoy durante el html tour, he oído una de las mejores frases que uno podría oír sobre Javascript “Javascript: the worst part. El principal problema es nuestra ignorancia”.

Creo que realmente el problema de Javascript es que cualquiera puede programar en Javascript. Da igual si eres un consumado experto o un tierno novato, escribe cuatro líneas de código y Javascript intentará por todos los medios ocultar tus vicios y ejecutar tu código.

Javascript es algo más que la función alert y la función confirm. Es un lenguaje de programación en toda regla pero con un pésimo interprete que, por no romper la web, no se quejará casi nunca y evitará así que aprendas de tus errores.

Además tampoco esperes encontrar en Javascript un lenguaje POO al estilo de C#. Javascript tiene su propia identidad y su forma singular de hacer las cosas, te gustará o no pero es lo que hay, es mejor que no intentes cambiar a Javascript sino cambiar tu forma de relacionarte con Javascript. Como dice Bruce Lee, “Be water my friend”.

Como lo cierto es que sí queremos aprender de nuestros errores y queremos ser mejores programadores, en mi opinión es indispensable realizar las siguientes tareas:

  • Leer Javascript: The Good Parts.
  • Utilizar JSLint para que valide nuestro código Javascript.

Como leerte el libro mientras te duermes plácidamente me parece un exceso, en este post lo que voy a intentar es explicarte brevemente cómo instalar JSLint y como usarlo y configurarlo.

JSLint es una herramienta creada por el mismo autor del libro, Douglas Crockford. El sitio web de la herramienta es http://www.jslint.com/. Según sus propias palabras, JSLint es una herramienta de calidad de código, es decir, una herramienta que busca problemas en tú código Javascript.

La mayoría de los problemas son bien conocidos y no admiten debate alguno, otros son guías de estilo propuestos por el autor, que podrías ignorar si así lo crees oportuno.

Aunque puedes utilizar un validador en línea desde su página, hay un proyecto en CodePlex que integra la herramienta en Visual Studio http://jslint4vs2010.codeplex.com/.

Para instalarlo, puedes descargar la extensión para Visual Studio 2010 http://visualstudiogallery.msdn.microsoft.com/961e6734-cd3a-4afb-a121-4541742b912e

También está disponible para su descarga desde el administrador de extensiones

clip_image002

Una vez instalado, tenemos disponible una nueva opción de menú: Herramientas > JS Lint Options…

clip_image004

 clip_image006

El uso de JSLint es bastante sencillo, por defecto hará lo siguiente.

  • Mostrará los errores como “warnings”
  • Sólo validará los ficheros .js
  • Ejecutará la herramienta en cada Build
  • Cancelará el Build si encuentra algún error

Como vemos en las pantallas anteriores, podemos configurar multitud de aspectos de la herramienta: desde validar ficheros .html, no cancelar el Build, ejecutarlo cuando guardamos el fichero, excluir ciertas secciones de nuestro código a través de comentarios, etc.

Mi recomendación (copiada vilmente del ponente del html tour) es que utilicemos JSLint para cualquier nuevo proyecto y que, para proyectos existentes, hagamos lo que podamos. Es decir, hoy mismo me decía un compañero que lo había activado para un proyecto en mantenimiento y el número de errores había sido demasiado alto… Yo directamente en mis proyectos antiguos no lo activaré porque tengo amor propio y no me apetece que JSLint me saque los colores cuando analice mi código antiguo.

Para ver a JSLint en acción, crearemos un nuevo Sitio Web y agregaremos un fichero .js en el que escribiremos el siguiente código:

function foo() {

    bar = "baz";

    return bar;

}

for (var i = 0; i < 5; i++) {

    alert(foo());

}

 

Que nos devolverá los siguientes warnings:

clip_image008

La compilación ha sido cancelada porque JSLint encontró errores de validación.

  • Estamos utilizando la variable “bar” pero no la hemos definido previamente (hemos olvidado var y eso implica que la variable bar se está creando en el contexto global y no el ámbito privado de la función foo).
  • En Javascript no existe el ámbito de bloque, luego “for (var i” podría llevarnos a engaño. Después de la instrucción for, “i” vale 5 porque “i” sigue existiendo.

Vamos a intentar solucionar los errores:

function foo() {

    var bar = "baz"; // hemos agregado var

    return bar;

}

var i = 0; // hemos declarado la variable fuera del for

for (i; i < 5; i++) {

    alert(foo());

}

 

clip_image010

Pues lo hemos logrado a medias, ahora nos informa que “no esperaba ++” y que “alert” ha sido utilizada antes de ser definida.

En cuanto al operador ++, según Douglas Crockford, no le gusta. Yo no voy a discutir a este señor (no podría), pero como ahora mismo no sé que espera encontrar y además con este excusa podemos ver como “desactivar” ciertas validaciones de JSLint en la pantalla JSLint Options.

clip_image012

Ahora ya no tenemos errores de JSLint:

clip_image014

Respecto a los errores relacionados con las guías de estilo, bastaría con quitar un espacio entre “var bar y =”

function foo() {

    var bar= "baz";

    return bar;

}

 

Ahora JSLint nos informará sobre este nuevo error relacionado con el estilo:

clip_image016

Para los que trabajamos con Visual Studio, muchos de estos problemas se solucionan simplemente con el atajo Ctrl + K, Ctrl + D (Menú Editar > Avanzadas > Dar formato al documento). De hecho, yo también utilizo este comando para ver si mi código tiene algún error, si Visual Studio no es capaz de dar formato al documento Javascript… algo no va bien.

Otros comandos que agrega JSLint a Visual Studio son nuevas opciones en el menú contextual desde el explorador de soluciones (Solution Explorer).

clip_image017

La opción “Skip on build (item)” cobra especialmente importancia si trabajamos con librerías de terceros. Por ejemplo, jQuery 1.8.2 lanza 455 advertencias en JSLint! De este modo o lo excluimos o estamos en un serio aprieto.

Si estás trabajando con VS2012 e instalas la extensión WebEssentials (un must-have en toda regla) http://vswebessentials.com/ automáticamente dispondrás de JSHint (ver que ahora hemos cambiado la L por una H) y podrás configurar todo lo relacionado con la herramienta desde Herramientas > Opciones > Web Essentials > JSHint

image

Las diferencias entre L y H (JSLint y JSHint) radican en que JSHint es un fork de JSLint. Es decir, ambos están vigentes y ambos son válidos, utilizar uno u otro es cuestión de gustos. El porqué aquí http://anton.kovalyov.net/2011/02/20/why-i-forked-jslint-to-jshint/ Por supuesto JSHint también tiene su propio validador on-line http://www.jshint.com/

Espero que este post te sirva para entender que Javascript es un lenguaje que merece toda tu atención y que hay herramientas que podrían ayudarnos a escribir mejor código.

Un saludo!

 

 

miércoles, 8 de agosto de 2012

Plug-in de jQuery para aceptar sólo números

Estoy comenzando un proyecto en ASP.NET Web Forms y he decidido no utilizar ninguna librería de terceros de controles de servidor de ASP.NET.

De este modo, ya no tengo disponibles maravillosos controles de servidor del tipo NumericTextBox que, con franqueza, me hacían la vida muy fácil y evitaban tener que controlar que la entrada del usuario eran sólo números.

Cómo lógicamente hay que seguir validando la entrada del usuario, he optado por crear mi propio plug-in de jQuery para restringir la entrada del usuario a sólo números en cajas de texto.

Cierto es que la idea original surgió a raíz de un post de @smarreof, jQuery input text numérico. Te recomiendo que lo leas para entrar en materia… bueno ese post y cualquier otro que tenga en su blog!. Además me ha ayudado con un comentario en el post sobre parseInt que ya he incluido en el código.

Lo primero es lograr una función de validación que sea lo más completa posible.

Como en la función vamos a hablar de la propiedad keyCode del objeto evento de javascript, aquí te dejo una referencia que a mi me ha sido de utilidad http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes

La idea es lograr una función que acepte sólo números (sin decimales) y además poder establecer un valor máximo para la caja de texto.

La función es la siguiente:

function numericTextBox(e) {
        if (
            e.keyCode == 8 // backspace
            || e.keyCode == 9 // tab
            || e.keyCode == 13 // enter
            || e.keyCode == 27 // escape
            || e.keyCode == 46 // delete
            || (e.keyCode >= 35 && e.keyCode <= 39) // end, home, left arrow, up arrow, right arrow
        ) {
            return;
        }
        else {
            if (!((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105))) {
                // not 0-9, numpad 0-9
                e.preventDefault();
                return;
            }
            else {
                var keyCode = e.keyCode;
                if (keyCode >= 96 && keyCode <= 105) {
                    keyCode -= 48;
                }
                var value = $(this).val();
                value += String.fromCharCode(keyCode);
                value = parseInt(value, 10)
                var maxNumber = $(this).data("maxnumber");
                if (maxNumber) {
                    maxNumber = parseInt(maxNumber);
                    if (value > maxNumber) {
                        e.preventDefault();
                    }
                }
            }
        }
    }

Lógicamente la función podría ser mejor porque no permite copiar ni pegar, no acepta decimales, etc. Está claro que este tipo de funciones son infinitas y según vaya necesitándolo iré agregando funcionalidad a la misma.


La forma de utilizarla sería crear un input type=”text” con un atributo data-maxnumber para establecer el valor máximo permitido y asociar al evento keydown de jQuery, nuestra función.


Por ahora y a falta de plug-in he utilizado un atributo de tipo data-. Si quieres saber más sobre este tipo de atributos puedes leer un post que escribí hace un tiempo. Atributos personalizados en HTML5.


El código de nuestra página sería algo así:

<asp:TextBox ID="txtCodigoCliente" runat="server" data-maxnumber="999"></asp:TextBox>
<script type="text/javascript">
$(document).ready(function () {
   $("#<%=txtCodigoCliente.ClientID %>").on("keydown", numericTextBox);
});
</script>

A partir de aquí, está claro que necesitamos crear un plug-in de jQuery para poder reutilizar al máximo nuestra función.


Siguiendo las indicaciones desde la documentación de jQuery para crear plug-ins http://docs.jquery.com/Plugins/Authoring, el código sería el siguiente:

(function ($) {
    function numericTextBox(e) {
        if (
            e.keyCode == 8 // backspace
            || e.keyCode == 9 // tab
            || e.keyCode == 13 // enter
            || e.keyCode == 27 // escape
            || e.keyCode == 46 // delete
            || (e.keyCode >= 35 && e.keyCode <= 39) // end, home, left arrow, up arrow, right arrow
        ) {
            return;
        }
        else {
            if (!((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105))) {
                // not 0-9, numpad 0-9
                e.preventDefault();
                return;
            }
            else {
                var keyCode = e.keyCode;
                if (keyCode >= 96 && keyCode <= 105) {
                    keyCode -= 48;
                }
                var value = $(this).val();
                value += String.fromCharCode(keyCode);
                value = parseInt(value, 10)
                var maxNumber = $(this).data("maxnumber");
                if (maxNumber) {
                    maxNumber = parseInt(maxNumber);
                    if (value > maxNumber) {
                        e.preventDefault();
                    }
                }
            }
        }
    }
    $.fn.numericTextBox = function () {
        return this.each(function () {
            $(this).on("keydown.numericTextBox", numericTextBox);
        });
    };
})(jQuery);

Ahora ya podemos escribir código jQuery con nuestro plug-in integrado:

$("#<%=txtCodigoCliente.ClientID %>").numericTextBox();

O mejor aún podemos hacer lo siguiente para seleccionar todos los input type=”text” que tenga el atributo data-maxnumber.

$("input[type='text'][data-maxnumber]").numericTextBox();

Finalmente guardamos nuestro código en un fichero llamado jQuery.numericTextBox.js y parecerá un plug-in profesional y todo!!


Un saludo!

lunes, 9 de julio de 2012

Introducción a 960 Grid System

En este post empezaré diciendo que no soy diseñador sino programador. Es por eso que siempre estoy buscando soluciones para maquetar más rápido en HTML/CSS y sobre todo, maquetar más sencillo. En esta búsqueda, he descubierto recientemente el mundo de los framework CSS y más concretamente, el concepto Grid CSS.

En el blog de Koalite, hay un interesantísimo artículo que habla sobre ello Diseño Web Sensible y Grids CSS.

También hay disponible un excelente tutorial en desarrolloweb.com, http://www.desarrolloweb.com/manuales/maquetacion-css-960-grid-system.html y otro tutorial más en http://jepserbernardino.com/idea/960-grid-un-framework-para-css/

Yo por mi parte voy a apostar inicialmente por 960 Grid System para un par de sencillos proyectos que tengo que abordar próximamente.

En mis propias palabras, 960gs es un framework CSS que nos permitirá maquetar nuestras páginas web como si estuviéramos trabajando con tablas HTML. Está claro que por hoy por hoy maquetar con tablas es contra-natura, pero también hay que reconocer que maquetar con tablas (y siempre que no las anidaras excesivamente) era sencillo e intuitivo y sobre todo, muy accesible para los maquetadores noveles. Siendo así, 960gs combina para mí un diseño tableless con bondades similares a la maquetación con tablas (y que nadie me crucifique por hablar de bondades en lo relativo a tablas, ¿eh?)

Como el movimiento se demuestra andando, veamos un sencillo ejemplo con 960grid.

Queremos maqueta una típica página maestra de backend. Algo parecido a esto:

clip_image002

Está claro que este diseño tampoco supone un reto de gran calibre, pero
¿Por qué pegarse con float, width, height, etc. si puedo hacerlo más sencillo con 960gs?

Veamos el código necesario para llevarlo a cabo:

<div class="container_12">
    <div id="header" class="grid_3 prefix_9">
        header
    </div>
    <div class="clear">
    </div>
    <div id="logo" class="grid_12">
        logo</div>
    <div class="clear">
    </div>
    <div id="menu" class="grid_12">
        menu</div>
    <div class="clear">
    </div>
    <div id="sidebar" class="grid_3">
        sidebar</div>
    <div class="grid_9">
        <div id="title" class="grid_7 alpha">
            title</div>
        <div id="help" class="grid_2 omega">
            help</div>
        <div class="clear">
        </div>
        <div id="content" class="grid_9 alpha">
            content</div>
    </div>
    <div class="clear">
    </div>
    <div id="footer" class="grid_12">
        footer</div>
</div>

El resultado es el siguiente (he activado ver los bordes de los DIV desde la IE Developer Toolbar):


image


image


Como podemos comprobar hemos podido crear el layout de nuestra página con poco código y poco esfuerzo.


Ciertamente tampoco quiero dar demasiado misterio al concepto de framework CSS.
En resumen, nos son más (ni menos tampoco) que 3 ficheros css que tenemos que incluir en la cabecera de nuestra página.

<link href="StyleSheets/reset.css" rel="stylesheet" type="text/css" />
<link href="StyleSheets/text.css" rel="stylesheet" type="text/css" />
<link href="StyleSheets/960.css" rel="stylesheet" type="text/css" />


  • reset.css es un reseteador de estilos para intentar homogenizar la visualización en todos los navegadores.

  • text.css es una hoja de estilos que define los estilos básicos de texto (h1…h6, p, etc.)

  • 960.css es realmente quien define la rejilla.

Las clases definidas en el fichero 960.css son:


container_12 y container_16 que tiene que ser asignadas al DIV contenedor de una rejilla. Digo “una” rejilla porque se pueden anidar columnas e incluso podemos tener varias rejillas al mismo nivel en la misma página (incluso de distinto número de columnas).


Si no tenemos suficiente con una división de 12 o 16 columnas, también podemos utilizar el generador on-line para definir el número, anchura y margen entre columnas desde http://grids.heroku.com/


Después de haber definido el contenedor, tenemos las clases grid_1 hasta grid_12 o grid_16, que lo que hacen es definir el número de columnas que utilizará cada uno de nuestros DIV.


También tenemos las clases alpha y omega, que sirven al propósito de eliminar el margen izquierdo y derecho, respectivamente, cuando anidemos columnas dentro de otras columnas. En líneas generales, primera columna de una columna anidada tiene que llevar alpha y última columna de una columna anidada tiene que llevar la clase omega. Todo ello para eliminar margen izquierdo de la primera columna y margen derecho de la última columna.


Si queremos crear espacios en blanco antes o después del contenido, tenemos igualmente las clase prefix_1 hasta prefix_11 o prefix_15 y la clase suffix_1 hasta suffix_11 o suffix_15.


Para limpiar los floats, tenemos la clase clear que tendremos que meter siempre después de una separación horizontal.


Como últimas clases disponibles, también es posible alterar o intercambiar columnas en lo relativo a su posición con las clases pull y push. Más información sobre reorganizar las columnas en http://www.clubosc.com/960-grid-tutorial-understanding-push-and-pull-classes.html


Por último, también hay herramientas disponibles para ver la grilla en Photoshop o desde el mismo navegador (esto nos ayudará bastante a la hora de plantear el Layout a conseguir con 960gs). Por ejemplo y ver la grilla en el navegador podemos seguir las instrucciones de esta página http://peol.github.com/960gridder/ que lo que hace es agregar un bookmarklet al navegador para cargar un overlay con la grilla.


image


Está claro que para mi las grillas CSS son aún un terreno por explorar y sobre todo llegar al convencimiento de que son útiles y no intentar utilizar para nada más que para lo que son, es decir, Layouts.


Un saludo.

miércoles, 4 de julio de 2012

Acciones disponibles en máquinas virtuales de Hyper-V

En la oficina hemos estrenado recientemente un nuevo servidor Windows 2008 R2 y hemos apostado por la virtualización para intentar ahorrar costes.

En este post no voy a hablar sobre la virtualización (sobre todo porque no soy ninguna voz autorizada), pero a cambio explicaré cuales son las acciones que pueden llevarse a cabo sobre una máquina virtual.

Aunque en principio podría no parecer necesario hablar sobre estas acciones, lo cierto es que cada vez que accedo al Administrador de Hyper-V, tengo que recordar cual era la diferencia entre Apagar y Desconectar, qué era Guardar, etc.

Sin más dilación, hay van las acciones disponibles para una máquina virtual:

Conectar.

Esta acción simplemente abre una nueva ventana para acceder a la máquina virtual.

Aunque parezca de Perogrullo, cerrar esta ventana no conlleva ninguna acción para la máquina virtual.

Desconectar

Aunque en principio podría parecer que es la acción opuesta a Conectar, nada más lejos de la realidad. Desconectar es y, haciendo el símil con una máquina física, como si apagáramos la corriente. Es decir, es una apagado forzado de la máquina virtual.

image

Iniciar

Iniciar es encender la máquina virtual, es arrancar el sistema operativo invitado.

Apagar

Al igual que Desconectar forzaba un apagado forzado, Apagar fuerza un apagado controlado.
Es el equivalente a apagar la máquina virtual desde el botón Inicio > Apagar del propio Windows de la máquina virtual.

Guardar

Guardar permite guardar el estado actual de la máquina virtual y ponerla fuera de línea.

Es similar a hibernar en un PC de escritorio o portátil.

Después de Guardar,  podremos volver a activar la máquina virtual con la acción Iniciar (que es junto a Instantánea las únicas opciones disponibles después de Guardar)

Pausar

Esta acción deja fuera de línea a la máquina virtual pero no guarda su estado.

Después de Pausar, sólo podremos Desconectar, Guardar o Reanudar.

La opción que normalmente acompaña a Pausar es Reanudar que vuelve a dejar operativa la máquina virtual.

Reanudar

Como hemos dicho antes, Reanudar sirve al propósito de volver a dejar operativa una máquina virtual después de Pausar.

Reestablecer

Esta opción permite reestablecer la máquina virtual al estado que tenía al arrancarla.

Esto permite deshacer los cambios realizados en la máquina virtual desde el actual arranque de la misma.

image

Instantanea

Toma una instantánea de la máquina virtual.

Revertir

Sólo en caso de que la máquina virtual disponga de instantáneas, Revertir aplicará automáticamente la última instantánea.

image

Algunos otros enlaces que podrían ser de utilidad son los siguientes:

Hyper-V: 5 Ways to Transfer Files Between Physical and Virtual Host http://ketstech.blogspot.com.es/2015/04/hyper-v-5-ways-to-transfer-files.html

Removing the ghost Hyper-V vNic adapter when using Converged Networks after in-place upgrade to W2012R2 http://cloudtidings.com/2013/11/20/removing-the-ghost-hyper-v-vnic-adapter-when-using-converged-networks-after-in-place-upgrade-to-w2012r2/

Using Hyper-V with a Wireless Network Adapter http://blogs.msdn.com/b/virtual_pc_guy/archive/2008/01/09/using-hyper-v-with-a-wireless-network-adapter.aspx

Un saludo!

martes, 19 de junio de 2012

Reciclaje de grupos de aplicaciones en IIS

Lo cierto es que, aunque conocía la característica de reciclaje de un grupo de aplicaciones de IIS, hasta hoy no había tenido la necesidad de meterme con ella en serio.

Normalmente, cuando subo una aplicación a IIS los únicos parámetros que configuro del grupo de aplicaciones es seleccionar la versión del .NET Framework correcta. En la mayoría de los casos no hay mucho más que hacer al respecto pero, como te mostraré a continuación, en según qué escenarios podría no ser suficiente.

Imagina una aplicación que realiza ciertas tareas pesadas o críticas (lo dejo a tu elección) al arranque de la aplicación (por ejemplo en el evento Application_OnStart del fichero global.asax).

Con este escenario ¿Sabes con certeza en que momentos será ejecutado tu código de inicialización? Está claro que se ejecutará al levantar el grupo de aplicaciones asociado a tu aplicación pero ¿Cuándo y porqué se vuelve a levantar tu grupo de aplicaciones?

Las respuestas más obvias es que un grupo de aplicaciones se iniciará en los siguientes casos:

  • Reinicio del servicio W3C
    • Bien sea de forma manual, bien porque se ha reiniciado el servidor, etc.
  • Reinicio o reciclaje manual del grupo de aplicaciones.
    • Acto totalmente voluntario y, por ende, controlable.
  • Cambios en la configuración de la aplicación (web.config, global.asax, etc.).
    • De nuevo un acto voluntario y programable.

A partir de aquí es cuando me he encontrado que, muy diversos factores también podrían forzar el reciclaje del grupo de aplicaciones y, por consiguiente, que mi código pesado de inicialización volviera a ejecutarse cuando yo no lo tenía previsto.

Si accedemos a la “configuración avanzada” de un grupo de aplicaciones desde la consola de administración de IIS, las secciones que podrían interesarnos son: Modelo de proceso y Reciclaje.

clip_image001[4]

Sin meternos en configurar límites de memoria o CPU, que al ser alcanzados provocarían el reciclaje de la aplicación, hay otros valores que “de serie” pueden hacer que nuestro grupo de aplicaciones se recicle sin nosotros haberlo previsto. Principalmente estoy hablando de “Tiempo de inactividad” e “Intervalo de tiempo regular”.

“Tiempo de inactividad” ha sido el mayor de mis problemas durante algún tiempo y, de hecho, es el valor que ha originado la redacción de este post. Este valor indica un cantidad de minutos en las que, sino hay actividad en el servidor, el grupo de aplicaciones será reiniciado.

En IIS 7.5 tiene por defecto el valor 5, lo que significa que si en 5 minutos nadie hace una petición a tu aplicación… el grupo de aplicaciones se reciclará.

Por otro lado, “Intervalo de tiempo regular” es un valor, también expresado en minutos, después de los cuales se reciclará el grupo de aplicaciones, con independencia de si están o activas las aplicaciones del grupo.

Por defecto son 1740 minutos (29 horas).

En esta situación resulta que tengo una aplicación que se recicla después de 5 minutos de inactividad y además cada 29 horas… luego se recicla cuando quiere y no tengo nada controlado el tema!

Para solucionar esto he optado por utilizar el valor “Horas específicas”, que permite especificar una o más horas en las cuales será reciclado el grupo de aplicaciones. En mi caso he pasado de un “reciclado aleatorio” a un “reciclado determinista”. Además, al especificar “Horas específicas” ya no se tiene en cuenta el valor de “Intervalo de tiempo regular”.

Por otro lado (y como no quiero ser un killer server), tampoco voy a poner 0 en “Tiempo de inactividad”… pero tampoco voy a dejar 5 (es más que probable que un usuario esté en mi página sin generar tráfico durante 5 minutos)… así que pondré un valor más alto (por ejemplo 20 para coincidir con el Session.Timeout).

Llegados a este punto creo tener algo más controlado cuando se reciclará mi grupo de aplicaciones, pero ¿Cómo puedo confirmar que mi nueva política de reciclaje se está llevando a cabo? Pues registrando los reciclados en el visor de eventos de Windows.

clip_image002[4]

Ahora cada vez que se recicle el grupo de aplicaciones podré consultar el visor de eventos y ver algo parecido a esto:

clip_image004[4]

clip_image006[4]

Está claro que la administración de un servidor IIS probablemente no sea tarea de un programador pero, al final, siempre acaba siendo tu tarea controlar el entorno donde se ejecuta tu aplicación y supervisar el rendimiento de la misma.

Aunque no es el propósito de este post, parece ser (no lo he comprobado) que la sección “Modelo de proceso” se puede especificar a través del fichero de configuración de nuestra aplicación (web.config) http://technet.microsoft.com/es-es/library/cc779563(v=ws.10).aspx. Sin embargo, la sección “Reciclaje” parece que no http://stackoverflow.com/questions/9697119/disable-iis7-pool-recycling-from-asp-net-config 

Por último, si quieres una referencia exacta de estas 2 secciones, puedes visitar los siguientes enlaces:

Process Model Settings for an Application Pool <processModel>

http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/processModel

Recycling Settings for an Application Pool <recycling>

http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/recycling

Un saludo!

miércoles, 30 de mayo de 2012

Diferencias entre bind, live, delegate y on

Está claro que una de las partes fundamentales de jQuery es el manejo de eventos, pero cuando tenemos que ponernos manos a la obra se nos presentan distintas opciones y no siempre sabemos cual es la idónea.

A nuestra disposición tenemos diversas funciones que aparentemente hacen lo mismo:

·         bind

·         live

·         delegate

·         on

El porqué de esta diversidad es fruto de querer hacer una mejor librería jQuery a la vez que se mantiene retrocompatibilidad con versiones anteriores del producto. Aquí está claro que no todos los proyectos pueden cambiar de jQuery 1.0 a jQuery 1.7.2 sin que ello conlleve una refactorización de código de magno esfuerzo.

Cronológicamente hablando (y espero no equivocarme), la primera función en aparecer en escena fue bind. Después apareció live para cubrir un hueco que no llenaba bind (la delegación de eventos), pero enseguida vieron que live no funcionaba como se esperaba de ella, así que incorporaron delegate en detrimento de live. Por último y para evitar que la gente se volviera loca teniendo que decidir si utilizar bind, live o delegate, surgió on, que en un solo método reúne la funcionalidad de todos los métodos anteriores.

Una vez que ya tenemos claro el orden cronológico de aparición de todos estos métodos, la siguiente pregunta a contestar sería ¿Por qué apareció live? ¿Qué es eso de la delegación que bind no podía hacer?

Con bind podemos adjuntar manejadores de eventos (o callbacks en terminología javascript) a elementos existentes en el DOM. Lo cierto es que bind siempre ha funcionado maravillosamente bien pero tiene un grave problema cuando nos encontramos en escenarios donde el DOM cambia dinámicamente (por ejemplo aplicaciones con AJAX). El problema está en que bind adjunta manejadores sólo a elementos existentes, es decir, futuros elementos que se incorporen al DOM no sabrán nada de los eventos manejados por bind (aunque coincidan con el selector suministrado a bind).

Por ejemplo pensemos que tenemos un ul con un solo li hijo. Adjuntamos un manejador al evento click en los li hijos del elemento ul (no sólo para el único hijo existente, sino en general para todos los hijos li de ul). Cada vez que hagamos click en un li agregaremos un nuevo li al ul padre. ¿Si hacemos click en los nuevos elementos li creados dinámicamente se disparará nuestro manejador? Pues no, porque bind adjuntó el evento sólo a elementos existentes en el momento de su declaración, así que nuevos elementos que coinciden con nuestro selector de bind no se darán por aludidos.

    <ul id="lista">

        <li>1</li>

    </ul>


$(document).ready(function () {

    $("#lista li").bind("click", function () {

        var ul = $(this).parent();

        var length = ul.children().length;

        // aunque el nuevo li coincide con el selector $("#lista li"), bind no funcionará con el nuevo elemento recién agregado

        ul.append("<li>" + (length + 1) + "</li>");

    });

});


Lógicamente tenemos un problema con este código ¿Cómo adjuntar o re-adjuntar nuestro manejador a los nuevos elementos li? Pues para eso apareció live.

Live funciona con la delegación de eventos, es decir, es vez de adjuntar el manejador click al único elemento li presente que cumplía el selector $("#lista li") en el momento de la declaración, lo que hace es declarar un manejador global a elementos que coincidan con el selector, esto es tanto a elementos que existen ahora como elementos que vayan a existir en el futuro.

Veamos ahora que nuestro código sólo requiere un simple cambio para trabajar con live en vez de con bind.

$("#lista li").live("click", …

 

A partir de este momento, cualquier elemento li que sea hijo de #lista tendrá adjunto el manejador de evento especificado (danto igual si el hijo existía en el momento de la declaración del manejador o fue creado después de forma dinámica).

El principal problema del que adolece live es que para hacer funcionar la delegación de eventos, adjunta el manejador al elemento document. De este forma, cada vez que se haga click en el documento (en cualquier sitio del documento) se chequeará si el elemento clicado coincide con el selector $("#lista li"), y si coincide se lanzará el evento.

Para solucionar el cómo funciona live, rápidamente se incorporó delegate.

Delegate respeta el mismo principio de delegación de eventos que live, pero a diferencia de éste, delegate adjunta el manejador a un padre específico. De esta forma ya no podemos hablar de un manejador global, sino de un manejador local con un ámbito concreto.

Para adaptar nuestro código a delegate, tenemos ahora que especificar un padre y un selector de hijos que se validarán ahora y en el futuro:

$("#lista").delegate("li", "click", function () { …

 

Si nos fijamos, con delegate hemos especificado que queremos adjuntar el manejador click a todos los hijos li (ahora y el futuro) para el padre #lista. Y todo esto confinado a un padre, es decir, sólo se chequeará el selector si el click sucede dentro de #lista, no a nivel de documento como sucedía con live.

Llegados a este punto está claro que hemos descartado live y sólo nos quedaría elegir entre bind y delegate según el escenario, pero lo cierto es que utilizando la nueva función on podemos olvidarnos de todo lo anterior y tener en un solo método toda la funcionalidad de bind y delegate.

Por ejemplo nuestro código anterior con bind pasaría a ser:

$("#lista li").on("click", function () { …


Y nuestro anterior delegate sería ahora:

$("#lista").on("click", "li", function () { …

 

Como vemos, con on podemos tanto gestionar eventos al estilo de bind (sólo para elementos existentes) como al estilo de delegate (con delegación de eventos para elementos futuros).

Ya no tienes excusa… utiliza on ... que no lo digo yo, lo dice jQuery!

Un saludo!