jueves, 28 de febrero de 2008

¿Tiene usted internet?

Hace unos días participé por primera vez en una encuesta telefónica. Había una pregunta que me hizo pensar en que voy siendo viejo, y que como muchos amigos míos, ya estábamos por aquí mucho antes de que esto se popularizase.

Resulta que después de preguntas sobre la vida, la política y la medicina, llegó el turno de la tecnología y la consabida de tiene usted internet. Si claro, respondí. Desde cuándo, pregunto el chico. Puf, desde hace mucho. ¿Más de cinco años? Si, bastante más de cinco años.

Después me quedé dándole vueltas a la respuesta, y efectivamente hace mucho que tengo internet. Pero mucho, mucho. De hecho, no exagero -bueno, un poco si- si digo que tengo internet prácticamente desde que llegó a España.

Recordaréis algunos de los que me leéis que en el principio, lo que teníamos eran unos ruidosos módems con los que nos conectábamos a las olvidadas BBS. Fue por aquella época cuando empezaron las ofertas en PC World o alguna revista similar donde te regalaban tantas horas de conexión a internet -si, cobraban por horas de conexión, con lo que la cosa era prohibitiva-. Fue por aquella época de universidad cuando fui a casa de un amigo -Julio- para que me explicase todo ese lío de iniciales -IRC, FTP, WWW-.

Y es que me ha recordado a esas historias que nos cuentan nuestros padres, o para los más jóvenes nuestros abuelos, de cuando no había televisión y la gente se sentaba alrededor de la radio a escuchar la radionovela. O cuando mi padre me cuenta que en su pueblo no había electricidad en todas las casas, y la gente se alumbraba con candiles de aceite. Es curioso como hay cosas que parece que siempre han existido, y resulta que no hace tanto tiempo que están con nosotros.

domingo, 24 de febrero de 2008

Reseña: Harry Potter y el misterio del príncipe

Pues si, me van a perdonar los expertos literarios pero me acabo de leer el sexto libro de las aventuras del joven mago, y acabo de empezar el séptimo y último. El que acabo de terminar es un libro bastante más oscuro que los anteriores, muy emocionante -me ha durado una semana- y al terminar deja unas ganas enormes de seguir con el último, motivo por el cual lo tenía aparcado hasta ahora.

Como decía, me perdonarán los expertos por leerme esta -para muchos- bazofia, especialmente para aquellos que opinan sin habérselo leido o, lo que es peor, únicamente habiéndo visto las películas.

Para los demás, es una lectura de lo más entretenida, que yo recomiendo si lo que se pretende es pasar el rato.

Vampiro: La Mascarada (1/2)

Artículos escritos con la intención de resumir el mundo de Vampiro: La Mascarada

Vampiro: La Mascarada (1/2)
Vampiro: La Mascarada (2/2)



Para que se entiendan futuras entradas que tengo en la cabeza, necesito hacer una breve introducción al juego de rol de "Vampiro: La mascarada". Se trata de un juego publicado por White Wolf, editado en España por La Factoría, y actualmente descatalogado puesto que ha salido una nueva versión del mismo: "Vampiro: El Requiem". Lo que sigue es un resumen del mundo en el que está ambientado. ¿De verdad hace falta que diga que todo es pura ficción?

La sociedad vampírica en Mundo de Tinieblas está ordenada jerárquicamente según la generación a la que pertenecen sus miembros. Según su mitología, el primer vampiro de la historia fue Caín, convertido cuando mató a Abel. Caín fue la primera generación, más poderosa que ninguna de las siguientes.

Los tres cainitas creados por Caín formaron la segunda generación. Éstos a su vez tuvieron 13 descendientes a pesar de la prohibición a hacerlo, motivo por el cual Dios desató el Diluvio Universal. Por eso también son conocidos como los antediluvianos, y forman los Clanes tal y como se conocen en lo sucesivo.

A partir de aquí los descendientes de estos vampiros heredan las habilidades del creador del Clan, pero cada vez la sangre de Caín está más diluida, por lo que los poderes son cada vez menores. Así se van creando generaciones a lo largo de la historia hasta llegar a la decimotercera generación en la época actual. Esta es la última que conserva algo de la sangre de Caín, y por lo tanto algunos de sus poderes -aunque muy leves-. A partir de aquí ya no tienen capacidad de crear nuevos chiquillos.

El mundo de Vampiro: La Mascarada es un mundo oscuro, donde los más poderosos manejan –directa o indirectamente- a los más débiles en una suerte de gigantesca partida de ajedrez a escala mundial, y donde los humanos forman el estrato inferior de esta pirámide de poder.

Seres que llevan sobre la faz de la tierra desde antes de que la civilización romana fuese algo más que unas colonias de pastores manejan los hilos en la sombra, y siempre existe la duda sobre si las acciones de cada individuo son únicamente por su propia iniciativa, o ha sido manejado como una marioneta por alguno de sus poderosos antepasados.

El universo de Mundo de Tinieblas es un lugar donde todos viven atemorizando y atemorizados, manipulando y manipulados, mientras por encima de todo planea el temor a que se cumplan los augurios y llegue la Gehena: el fin de los días en los que los antediluvianos despertarán y acabarán con toda su descendencia.


Mas información en Vampiro: La Mascarada

lunes, 18 de febrero de 2008

Plan de emergencia

Hoy en día tenemos tal dependencia de la electricidad que no podemos trabajar sin ella. Para no tener cortes se preparan todo tipo de medidas de emergencia. Una de ellas son los llamados SAI -Sistema de Alimentación Ininterrumpida-. Esto viene a ser unas baterías que, cuando se va el suministro eléctrico, siguen proporcionando la ansiada luz.

Los SAI's tienen una cosa buena, y una mala: La buena es que no hay corte en el suministro, es decir, "entran" a funcionar tan rápido que el suministro es básicamente constante, con lo que los sistemas no llegan a apagarse. La mala es que la duración de las baterías va en función de los equipos enchufados, con lo que en la práctica duran muy poquito.

Otros sistemas para evitar la falta de suministro son los generadores diesel. Tienen la virtud que, mientras tengan combustible proporcionarán electricidad, pero como punto en contra es que tardan un tiempo en "arrancar", con lo que si tienen que dar servicio a ordenadores, este salto de electricidad hace que se apaguen a lo bruto.

La solución para entornos en los que no se puede permitir ningún corte de electricidad, por pequeño es éste sea, es una combinación de ambos sistemas: Un SAI de suministro inmediato para evitar el corte mientras da tiempo a que se ponga en funcionamiento el generador.

Naturalmente, no es sensato que el generador suministre a todos los sistemas. Se trata de un sistema de emergencia, con lo que sólo se proporciona electricidad para los sistemas críticos: los servidores, los ordenadores del personal de sistemas o la máquina del café. Nada de "pinchar" de esta forma los ordenadores del resto del populacho, el sistema de calefacción o los microondas de la cocina.

Hoy hemos llegado al trabajo y nos hemos encontrado, entre otras cosas, sin servidores. Tenemos montado un sistema como el que acabo de describir, el SAI y el generador funcionan perfectamente, y no hay problemas de cables, pero a pesar de eso estamos sin servidores. ¿Por qué? Pues porque el aire acondicionado del CPD no está incluido en los "sistemas suplidos por el generador de emergencia". Ver para creer.


Explicación:

Cuando un PC se calienta demasiado, se apaga como medida de seguridad para evitar daños irreparables -vamos, que se tueste-. Cualquiera puede comprobar cómo su PC o su portátil tiene unos ventiladores que sirven para este propósito.

Un servidor es bastante más grande y se calienta bastante más, con lo que aunque también tiene ventiladores, no son suficientes, así que tienen que estar en armarios especiales -o salas enteras- refrigeradas las 24 horas con aire acondicionado.

viernes, 15 de febrero de 2008

ReportDocument: "No se ha podido cargar el informe"

Una nueva entrega de errores en Visual Studio y cómo evitarlos, aunque esta vez se trata de una mala utilización del componente ReportDocument -empleado para mostrar informes en Crystal Report-. O mejor dicho, trataré de cómo evitar las malas prácticas de programación. Por decirlo fino.

Tenemos una aplicación web desarrollada en ASP.NET en la que mostramos información sobre albaranes de envío a través de un Crystal Report. Esta aplicación está publicada en una intranet donde, en determinados momentos, puede llegar a haber hasta 40 usuarios mas o menos simultáneos.

Después de hacer los desarrollos y probadas todas las opciones sin ningún error, decidimos pasar el sistema a producción. Pero, oh campos de soledad, oh mustios collados, resulta que después de llevar unos días empieza a dar un error de lo más raro:

No se ha podido cargar el informe.

Primer problema: Estábamos capturando la excepción y mostrando únicamente la información de la propiedad "Message". Esto a veces está muy bien, pero en otras la información contenida aquí no dice nada, y nos hace falta saber mas, es decir, "InnerException".

Este error tenía unos efectos colaterales nada desdeñables, puesto que a partir de este momento ya no se podía mostrar ningún otro informe, ni en esta sesión ni en ninguna del mismo usuario o de otros, teniendo que reiniciar el IIS -el día que deje de funcionar lo de salir y volver a entrar no se qué vamos a hacer-.

Reproducir el error en desarrollo era bastante complicado porque no sabíamos bajo qué condiciones se daba, así que lo siguiente fue sacar toda la información del error. Como ya he dicho, fue en "InnerException" donde empezamos a encontrar la luz al final del túnel con este mensaje:

Se ha alcanzado el límite máximo de tareas de procesamiento de informes configuradas por el administrador del sistema.

Genial. Desde el inicio ya había un cierto tufillo a recursos no liberados, y este mensaje parece que va por ahí. Próximo paso, ver si estamos liberando todo lo que utilizamos. Después de una búsqueda rápida no encontramos en todo el código ningún Dispose() ni ningún Close() del objeto que utilizamos para mostrar el informe. Mecachis.

Lo que faltaba era cerrar el ReportDocument pero claro, la programación web no tiene mucho que ver con la basada en formularios, y no siempre tenemos claro cuándo se producen los eventos. Además tenemos los famosos postback, que hace necesario entender cómo funcionan para no andar repitiendo procesos que ralentizan la carga de la página sin necesidad.

Así pues, ¿dónde cerramos el ReportDocument? No puede ser en el mismo procedimiento que lo crea, porque todavía no lo ha mostrado. El sitio natural es en el evento Page_Unload, ya que es el momento en el que termina de procesarse la página... cuyo concepto es algo parecido al evento Leave de un Windows.Form -insisto, parecido-. Es decir, algo como:


protected void Page_Unload(object sender, EventArgs e)
{

if ((informe != null) && informe.IsLoaded)

informe.Close();

}

[Actualización 06/11/2008: Además de informe.Close(), no estaría demás hacer también informe.Dispose(), tal y como me han dicho en varios comentarios de esta entrada. :-)]

"informe" es una variable del tipo ReportDocument privada de la página. En este fragmento de código se puede ver cómo primero comprobamos si está instanciada -no lo estará si no hemos encontrado el albarán de carga buscado- y después comprobamos si tiene datos cargados -esta propiedad cambia a true al utilizar el método SetDataSource(), entre otros-.

Con esto terminaron nuestros quebraderos de cabeza, al menos en lo relativo a este error.


PD: Al que hizo esa página le tenemos escribiendo 1024 veces "Liberaré los recursos cuando termine de utilizarlos". :-)

martes, 12 de febrero de 2008

El que avisa no es traidor

Eso es lo segundo que pensé después de ver el siguiente mensaje; lo primero fue que había leido mal. El aviso corresponde al Service Pack 1 de Visual Studio 2005:


Pues eso, que el que avisa no es traidor. Es avisador.

domingo, 10 de febrero de 2008

Reseña: Mascarada

Después de la última y entretenida lectura, esta vez me he decidido por algo un poco más ligero: Mascarada. Su autor -Terry Pratchett- es, según reza la introducción del propio libro, el segundo autor británico más vendido después de J. K. Rowling -Harry Potter-.

Me regalaron esta novela en verano, pero hasta ahora no había tenido tiempo de leerla. Divertida e irónica, es una de esas novelas que puedes leer en un fin de semana si las condiciones -y la familia- son propicias. Como muestra, la dedicatoria que encabeza el texto:

Mi agradecimiento a la gente que me mostró que la ópera era más extraña que lo que podría imaginarme. La mejor manera de recompensar su amabilidad es no mencionar sus nombres aquí.

El resto va en la misma línea.

miércoles, 6 de febrero de 2008

ComboBox en Visual Studio 2005

Cuando estás acostumbrado a hacer las cosas de una forma, suele costar un poco cambiar la mentalidad y hacerlas de otra distinta. Independientemente de que ésta nueva forma sea mejor o más cómoda.

Cualquiera que haya tratado con los famosos ComboBox -en algunos libros se traduce como cajas desplegables- ha podido utilizar esa característica mediante la cual no puedes escribir en él -se suele decir que el estilo es DropDownList- pero si pulsas varias teclas, se posiciona en el elemento cuyo comienzo corresponde con ese inicio.

Ahora las cosas han cambiado, y esto ya no funciona así en Visual Studio 2005. En esta versión, la herramienta de desarrollo de Microsoft ignora las teclas que has pulsado previamente, y sólo se queda con la última, seleccionando el primer elemento que comienza con esa letra -o número-.

Esto descoloca al más pintado, que con la incredulidad todavía pintada en la cara se pone a buscar una solución por el basto mundo de los foros de ayuda. Y la solución por llamarle de alguna forma está en esta nota del Soporte Técnico. Lo mejor de todo es la explicación oficial de la causa, que viene a ser literalmente:

This problem occurs because the ComboBox search is based on one character instead of the complete character set.

O utilizando la herramienta de traducción de la misma página:

Este problema se debe a la búsqueda ComboBox basarse en un carácter en vez del juego de caracteres completo.

Pensarás genial, si está encontrada la causa, ahora sólo queda poner un remedio. Pero no, resulta que la solución que propone el mismo documento técnico es la utilización de un Timer, el evento KeyUp del ComboBox y un código que funciona fatal y crea un efecto visual como para echar la pota. Así, al más puro estilo Pepe Gotera y Otilio.

Hasta aquí la crítica a la chapuza. Ahora pasamos a la solución de verdad, y es que la gente de Microsoft ha decidido que esto ya no se hace así, sino con otras dos nueva propiedades y una forma de trabajar muy distinta. Estoy hablando de:

AutoCompleteMode = SugestAppend
AutoCompleteSource = ListItems

La primera propiedad va mostrando los valores que coinciden (de la misma forma que funciona la barra de direcciones de Firefox o Internet Explorer) al mismo tiempo que completa el texto con la primera coincidencia (hay otras dos opciones igual de válidas, pero a mi me gusta ésta). La segunda propiedad dice que la lista de valores posibles para “autocompletar” son los propios Items del ComboBox.

El único problema es que así no te aseguras de que te han elegido un elemento de la lista -imaginemos que no permitimos la iniciativa individual -. Así, no nos quedará otra opción que incluir en el evento Leave del ComboBox un código más o menos como este:

if (comboBox1.Text != "") && (comboBox1.Items.IndexOf(comboBox1.Text) == -1)
{
MessageBox.Show("El valor elegido no está en la lista.");
comboBox1.Focus();
}


Por cierto, en el código anterior he puesto comboBox1 para facilitar su lectura y comprensión. Lo ideal es poner en su lugar (sender as ComboBox), ya que de esta forma el mismo código sirve para todos los eventos Leave de todos los ComboBox, consiguiendo así ese mito de la reutilización.

Esta es la forma que he encontrado para hacerlo, pero si estás leyendo esto y sabes otra mejor, por favor, no dudes en decírmelo.

domingo, 3 de febrero de 2008

Foros de Interpretación

Todos conocemos los foros de internet y todos sabemos que los hay de todo tipo, desde los dedicados al soporte técnico hasta aquellos que se ocupan de cualquier tipo de afición. Dentro de este amplio abanico también están, o estuvieron alguna vez, los foros de interpretación. Es decir, foros para jugar a rol.

En ellos, cada usuario es realmente el personaje del juego de rol interpretado por una "persona humana" -como dice Gomaespuma-. De esta forma, todos los post que hay son interpretaciones dentro de la enorme partida que supone el foro. Y digo enorme, porque ya no estamos hablando de un grupo de juego de cinco o seis amigos alrededor de una mesa, sino de más de cincuenta o cien personajes que con su interpretación hacen que el foro realmente esté vivo, cambie y evolucione. La idea es similar a los mundos persistentes de juegos como "Neverwinter" o "World of Warcraft".

En su día yo también participé en un foro de interpretación que creó y administró un amigo -David, alias Sla-. Estaba ambientado en el oscuro ambiente de "Mundo de Tinieblas", que abarcaba juegos como "Vampiro: La Mascarada", "Hombre Lobo: El apocalipsis" y "Mago: La ascensión" entre otros.

Sla ideó una ciudad -Ciudad del Limbo- y puso todo lo necesario, tanto técnicamente como de ambientación -incluido su ordenador, su ADSL y una millonada de horas de su tiempo-, para que todo funcionase. Luego fueron los usuarios los que terminaron de dar forma a la ciudad con sus localizaciones, y por supuesto con sus interpretaciones.

Pero creo que como introducción ya me he extendido bastante, y tampoco es cuestión de aburrir al personal. Así que dejo para otra entrada una descripción más detallada de Ciudad del Limbo, sus personajes y lo que allí pasaba.