Sunday, April 06, 2008

Escalabilidad en el servidor

Al principio fue Apache, con un modo de funcionamiento extremadamente robusto. Cada petición se sirve en un proceso hijo distinto. Si algo va mal, el proceso hijo se colgaría, pero no afectaría en absoluto al resto de peticiones servidas por los otros procesos. Método lento, ya que crear un nuevo proceso es lento, pero seguro. Para mejorar el rendimiento se suele usar un "pool" (grupo) de procesos latentes, para no tener que crear un nuevo proceso con cada petición. Así nos ahorramos la creación de un nuevo proceso por petición.

Si queremos servir páginas web dinámicas y usamos Apache tenemos principalmente dos posibilidades, usar un "pool" de procesos PHP, qué comunicarán con Apache usando FastCGI, o usar ejecutar PHP directamente desde Apache con mod_php (en lugar de PHP/fastCGI podemos usar Python/SCGI o cualquier otro lenguaje). En el segundo caso, la comunicación entre Apache y el intérprete será más rápida ya que no necesita una comunicación entre procesos (Apache - PHP) por cada petición. Para servir una petición, Apache comunicará con uno de sus procesos libres del pool, y si es una petición dinámica y ese proceso aún no ha cargado mod_php, lo cargará y ejecutará el script correspondiente.

El numero máximo de recursos por segundo que podremos servir antes de agotar la memoría será:

nb_procesos_max = mem_total / mem_proc
recursos_seg = nb_procesos_max / seg_recurso

Donde mem_proc es la memoría que ocupa cada proceso Apache y seg_recurso es el tiempo medio que tardamos en servir un recurso.

Por ejemplo, si tenemos 2 GB de memoria, cada proceso consume 20 MB, y de media tardamos 0.1 segundos en servir una petición, podremos servir un máximo de 2000 / (20 * 0.1) = 1000 peticiones por segundo. Con este modelo, si queremos activar KeepAlives (ver el artículo sobre cómo acelerar la descarga de páginas web) durante 10 segundos, tendremos un límite de 2000 / (20 * 10) = 20 peticiones por segundo. ¡Hemos dividido por 100 nuestro máximo!

Para poder activar KeepAlives sin matar nuestro servidor, o simplemente si queremos consumir menos memoria, tenemos que cambiar de modelo. Sabemos que la mayoría de recursos son simples ficheros estáticos (js, css, png, jpg, etc.). No necesitamos un intérprete PHP para servirlos. De hecho, es tan sencillo que podemos hacerlo directamente desde el proceso principal del servidor web, sin necesidad de usar un proceso secundario ya que la posibilidad de que el proceso se cuelgue haciendo algo tan simple es prácticamente nula. Apache (<= 2.1) no puede funcionar en este modo, y tendremos que usar otro servidor Web, como lighttpd, nginx o cherokee.

Para los recursos dinámicos, podemos mantener un pool de procesos PHP y comunicar con ellos usando fastCGI, o simplemente seguir usando Apache y comunicar con Apache por HTTP (ideal para una migración rápida, ya que podemos seguir usando la configuración previa). La comunicacion entre servidor y PHP será algo más lenta, pero como ventaja desacoplamos el tiempo de vida de la conexión TCP con el del proceso PHP. Lo único que hay que hacer es pedirle a Apache que escuche en otro puerto (Listen 8080) y pedirle al servidor de recursos estáticos que actue de reverse proxy hacia localhost:8080 para todas las peticiones dinámicas.

La mayoría de servidores que permiten este modo de funcionamiento, permiten también usar un pool de procesos para servir los recursos estáticos, pero esta vez un pool pequeño y fijo (por ejemplo de 4 procesos). De este modo podemos aprovechar varios procesadores o un procesador multicore, y paralelizar las peticiones en caso de que alguna llamada al sistema bloquee (en teoría todas las llamadas que se usan son asíncronas, en la práctica a veces bloquean).

Consejos para acelar las páginas web - Parte II

Ya hemos hablado de la importancia de la latencia en el tiempo de descarga de las páginas web. Reducir el número de "three-way handshakes" activando KeepAlives, el número de ficheros a descargar, paralelizarlos sobre un máximo de 4 dominios, etc. son consejos importantes para reducir el impacto de la latencia, pero hay algo que sobrepasa a cualquier otra técnica para reducir el tiempo de espera cuando queremos usar un recurso (imágen, hoja de estilo, javascript, etc.), y es no mandarle nada al navegador, siempre que este tenga en caché una copia del recurso en cuestión.

El navegador divide los recursos que tiene en su caché en dos tipos, los "frescos" y los "dudosos". Los recursos frescos pueden usarse sin preguntarle nada al servidor. Los recursos dudosos se pueden usar, pero antes hay que preguntarle al servidor que nos lo envió si sigue siendo válido, o si hay que tirarlo a la basura y usar una nueva versión que el servidor le mandará al navegador.

¿Cómo controlar si un recurso entra en la caché, y si lo hace el tiempo qué permanece fresco? Con las cabeceras Cache-Control o Expires. La cabecera Expires contiene una fecha a partir de la cual el recurso debe ser considerado como dudoso. Si la fecha está en el pasado, o si no es una fecha (como "0"), se considerará inmediatamente al recurso como dudoso. La cabecera Cache-Control ofrece muchas más opciones, permitiendo por ejemplo especificar si un proxy que se encuentre entre el usuario y el servidor puede guardar el recurso en caché o si sólo el navegador puede hacerlo. Podéis leer la especificación para ver todas las subopciones de Cache-Control, siendo una de las más importantes max-age, que especifica durante cuantos segundos se tiene que considerar el recurso como fresco. Si se usa Cache-Control, toma prioridad sobre Expires.

Recordemos que si un recurso es fresco, el navegador lo usa directamente sin decirle nada al servidor. Más rápido imposible.

Si el recurso es dudoso, ¿cómo puede el navegador comprobar si ha cambiado en el servidor o no? La pregunta, en prácticamente todos los casos es completamente irrelevante. Es mejor que vuestros recursos siempre se mantengan frescos, poniendo un Expires o un Cache-Control max-age de muchos años. O están en la caché y pueden usarse directamente, o no están y hay que pedírselos al servidor.

¿Por qué muchas páginas los dejan pasar al estado "dudoso" (poniendo pequeños tiempos de expiración)? Porque quieren que si cambian el recurso, el navegador se baje la nueva versión. Esto es extremadamente problemático, porque en la práctica es imposible predecir cuando se va a cambiar un recurso, asi que no le podemos decir al navegador hasta cuando lo puede mantener fresco, o nos arriesgamos a que el navegador use una versión antigua de algunas de nuestras imágenes, páginas de estilo, javascript, etc.

Tenemos tres alternativas para atacar este problema:


  1. Ignorarlo. Es lo que hacen todos los que ponen un tiempo corto en Expires. Es incorrecto porque el cliente puede ver una nueva versión de nuestra página web con una mezcla de recursos antiguos y nuevos. Es ineficiente, porque hace que el cliente le haga una petición al servidor para comprobar la validez del recurso una vez caduca, requiriendo un mínimo de una ida y vuelta al servidor, y más típicamente dos idas y vueltas (ver el artículo anterior sobre la importancia de la latencia)

  2. Poner el Expires a 0. Es correcto, ya que el cliente siempre ve la última versión del recurso. Es ineficiente, ya que siempre es necesario comprobar la validez del recurso.

  3. Nunca cambiar un recurso. Más especificamente, cuando quieras crear una versión nueva de un recurso, no le des el mismo nombre que otro recurso ya existente en tu página web. Es correcto, ya que la versión en la caché y en el servidor de un recurso siempre es la misma. Es eficiente, ya que si se sigue usando ese recurso y está en la caché, el navegador nunca le pregunta al servidor.



La última opción es obviamente la ideal, y la que más trabajo necesita por parte del desarrollador, ergo es la opción menos usada. En realidad no es tan dificil de implementar. En lugar de poner en el HTML enlaces como "imagen.png", pondremos un enlace llamado "imagen.png?v=1". El servidor evidentemente ignorará el "?v=1", pero el navegador eso no lo sabe. Cuando actualicemos "imagen.png", cambiamos el número de versión, y en el HTML ponemos "imagen.png?v=2". Asi pues, en el mismo instante en que tengamos una versión nueva de "imagen.png" el navegador tendrá que pedírsela al servidor (él no tiene en su caché nada sobre "imagen.png?v=2"). Si queremos aumentar la legibilidad, o evitar que algún proxy no cachée nuestra imagen por usar un ? en la URL, podemos escribir imagen.v2.png, y eliminar el .v2 con mod_rewrite en Apache. Con un poco de esfuerzo, todo el proceso puede automatizarse. En Panoramio por ejemplo tenemos una tabla con el MD5 de todos los recursos estáticos qué usamos, y su número de versión (excepto para las imágenes que suben los usuarios). Cuándo subimos una nueva versión de Panoramio, un script comprueba el MD5 de todos los recursos, y si este cambia, aumentamos su número de versión. Todas las URLs a nuestros recursos las generamos a través de una función que le añade a la URL el número de versión que hemos calculado anteriormente. Todo esto se basa en que nuestro HTML no debe de estar cacheado, o los clientes puede recibir una versión antigua del HTML con una versión nueva de algunos recursos.

Si teneis algún recurso para el que este tipo de solución no es práctica, entonces tendreis que dejar que vuestros recursos pasen al estado dudoso (o no cachearlo en absoluto). Para comprobar si un recurso sigue siendo válido, el navegador le pregunta al servidor si ese recurso ha cambiado desde que se metió en la caché, usando la cabecera If-Modified-Since. Si no ha cambiado, el servidor responde con HTTP/304 Not Modified, y si ha cambiado responde enviando el nuevo contenido.

Si nuestro recurso no tiene una fecha de modificación clara (por ejemplo, si se ha generado dinámicamente), este método de verificación no nos servirá. Si ese es nuestro caso, al enviar el recurso la primera vez tendremos que añadir la cabecera ETag, que contendrá un identificador único que deberá cambiar cuando cambie el recurso. Los ETag que tanto Apache como IIS generan no dependen exclusivamente del contenido del fichero, si no que también dependen de datos especificos del servidor (por ejemplo, el inode donde se encuentra el fichero). Si usamos varios servidores, este ETag será inutilizable. En la práctica hay muy pocas razones para usar un ETag, siendo la validación por fecha suficiente en la mayoría de los casos.

En el anterior artículo de esta serie preguntasteis por herramientas para poder medir el tiempo de descarga de páginas web. Una formidable es Fiddler, desgraciadamente sólo disponible para Windows. Especificamente para Firefox tenemos firebug, sin duda el plugin de desarrollo más útil que existe para Firefox, y que incluye un panel donde podemos ver el tiempo que tarda cada petición al servidor, pero ¡cuidado al interpretar los resultados!, firebug muestra cuando las peticiones entran en la cola de peticiones de Firefox, no cuando se despacha la petición realmente al servidor.

El autor de Fiddler tiene un artículo donde habla también sobre el rendimiento de páginas web, y donde explica con algo más de detalle las diferentes cabeceras involucradas en todo el proceso de cacheo.

Queda bastante que hablar de este tema, sobre la compresión de los recursos en el servidor, y sobre todo de los distintos bugs en servidores y clientes que le ponen un poco de pimienta a la vida, pero ya es tarde. ¡Hasta la próxima!

Consejos para acelerar las páginas web - Parte I

La velocidad de carga de las páginas web viene determinada por muchos factores, pero los más importantes son la combinación de la latencia y el número de recursos a descargar, y por otro lado el ancho de banda y el tamaño de estos recursos.

Como diseñadores web, lo único que podemos hacer para disminuir la latencia entre nuestros servidores y nuestros usuarios es colocar los servidores lo más cerca posible de nuestros usuarios, o distribuirlos por todo el planeta si nuestra página web no tiene un uso mayoritario en un solo país. Pero están soluciones suelen ser muy caras y no están al alcance de todo el mundo.

En la práctica, la latencia y el ancho de banda del usuario lo tendremos que tomar como elementos incontrolables. Ya que el ancho de banda ha ido creciendo exponencialmente desde hace unos años, este elemento ya no tiene la importancia tan crítica que tenía hace tan solo unos años, y el tiempo de espera debido a la latencia y el número de recursos a descargar ha cobrado más importancia.

Veamos pues en detalle el proceso de descarga de una página web, y por qué afecta tanto la latencia al tiempo total de descarga. Cuando el navegador tiene que mostrar una página web nueva, digamos http://www.ejemplo.com/, primero tiene que convertir el nombre del dominio a una dirección IP con la que poder conectar, asi que contacta con los DNS de nuestro ISP para conseguir esta dirección IP.

Con la dirección IP en su mano, intenta establecer una conexión TCP con ese servidor, siguiendo el proceso conocido como “three-way handshake”. El navegador envía un paquete SYN y espera pacientemente la respuesta del servidor, que será un paquete SYN + ACK. Cuando el navegador reciba el paquete respuesta del servidor ya puede mandar un paquete ACK de respuesta e inmediatamente lanzar una petición HTTP GET del recurso que nos interesa (en nuestro ejemplo, “/”), a lo que el servidor responderá por ejemplo, mandando el contenido del fichero “index.html”.

Si el tiempo que tarda un paquete en llegar de nuestro navegador al servidor es de 100 ms, necesitaremos 400 ms debido a la latencia antes de que el navegador consiga el primer byte de contenido real, y ya podemos tener una flamante conexión a 20 Mb/s que no reducirá nada este tiempo de espera. A partir de aquí, y hasta que el navegador termina de recibir “index.html” pasará un tiempo dominado por el tamaño de este fichero y el ancho de banda de que dispongamos. Si “index.html” pesa 100 KB y tenemos una conexión de 4 Mb/s tardará unos (100 * 8) Kb / (4 * 1024) Kb/s * 1.2 = 235 ms. El factor “mágico” de 1.2 tiene cuenta de la sobrecarga típica de datos a enviar debido a la encapsulación de estos datos en paquetes.

Una vez con el contenido del HTML, el navegador procede a interpretarlo, y típicamente encontrará dentro del HTML referencias a otros recursos, como hojas de estilo CSS, Javascript, imágenes, etc. Para cada uno de estos recursos extra se repite todo el proceso anterior, asi pues si hacemos referencia a 10 recursos, un número muy conservador hoy en día, perderíamos 10 * 400 ms = 4 s extra debido a la latencia.

Afortunadamente el navegador paraleliza estas peticiones, pero para no sobrecargar al servidor no hace más de dos peticiones a la vez al mismo dominio. Mención especial merecen los ficheros Javascript, que no se descargan en paralelo. Si en nuestro HTML no usamos ningún fichero Javascript, los 10 recursos añadirán entonces 10 * 400 ms / 2 = 2 s extra.

¿Cómo podemos “engañar” al navegador para que descargue más ficheros en paralelo de nuestro servidor? Hay un truco muy sencillo, y es crear varios subdominios que apunten al mismo servidor, y dividir el enlace en el HTML a nuestros recursos entre estos subdominios. El navegador empezar a descargar en paralelo un máximo de 2 recursos por subdominio, sobre un máximo de 4 dominios simultáneamente. Haciendo esto el tiempo perdido estableciendo las conexiones TCP y empezando a descargar los recursos será de 0.8 s (400 ms para establecer las primeras 8 conexiones + 400 ms para las 2 últimas conexiones).

Hay una forma aún más sencilla de reducir este tiempo de espera. Si el servidor no cierra la conexión TCP con el cliente en cada petición HTTP, usando KeepAlives, dividimos por dos el efecto de la latencia en cada recurso que se descargue en una conexión ya abierta. El efecto de KeepAlives depende del número de subdominios que tengamos, si lo servimos todo desde el mismo dominio, en lugar de los 2 s anteriores tardaremos 400 ms para establecer las 2 primeras conexiones en paralelo + 200 ms por cada uno de los otros 8 recursos a bajar / 2 (número de recursos que se descargan en paralelo) = 400 + 200 * 4 = 1.2 s. Sobre 4 subdominios tendremos una espera usando KeepAlives de 0.6 s, ya que los 2 últimos recursos se descargan sin necesidad de establecer otra vez la conexión TCP.

Hay que tener en cuenta que en algunos servidores web la activación de KeepAlives tiene un impacto sobre el rendimiento muy significativo. Os recomiendo utilizar un servidor web alternativo, como lighttpd, nginx o cherokee al menos para vuestro contenido estático, con KeepAlives activado.

Un cambio que puede tener un efecto significativo en el tiempo de descarga es concatenar todos los ficheros CSS a descargar en un solo fichero (o 2, uno general al sitio y otro particular a la página), concatenar los ficheros Javascript, e incluso concatenar las imágenes, seleccionando la subimagen a mostrar usando CSS Sprites. Así podremos reducir significativamente el número de recursos a descargar.

Otro de los factores que sorprendentemente puede influir en el tiempo de descarga es el tamaño de las peticiones que hace el navegador. Cuando el navegador le pide al servidor una página, le envía también información extra, como el nombre del navegador, el idioma preferido por el usuario, las cookies, etc. Muchos de estos datos (como las cookies) no suelen influir en el resultado devuelto por el servidor para los ficheros CSS, JS o imágenes, y si nuestras cookies son cross-subdomain podemos evitar que el navegador tenga que mandarlas si colocamos los ficheros estáticos en otro dominio. Yahoo! por ejemplo usa el dominio yimg.com para servir este tipo de ficheros. A pesar de que las cookies son relativamente pequeñas, hemos de recordar que típicamente los usuarios navegan con conexiones asimétricas, donde la velocidad de subida puede ser 50 veces inferior a la velocidad de bajada de datos.

Una vez aplicados estos cambios en nuestras páginas, podremos concentrarnos en la segunda parte de mayor influencia en la velocidad, el tamaño de los recursos a descargar, y las distintas formas en que podemos influenciar la caché del navegador para evitar tener que descargar todo cada vez que un usuario llegue a nuestra página. Pero esa es otra historia de la que hablaremos otro día.

Thursday, August 18, 2005

Re: Ctrl+N in IE

Havoc comments on Internet Explorer showing the same page you're already viewing when you open a new window:

I'm pretty sure this is the only page on the Internet that I could not possibly want to see in the new window, since I already had it open.


Havoc is a smart guy, and usually he's right in the money, but he is soooo wrong on this one.

First, it's not always the case that you do not want to see the same page on the new window. You may want to check the bottom of the page to have a window with the footnotes, but still retain a window on the current reading position. But granted it's extremelly rare.

The thing that is invaluable is having the whole history of previous / next links on the new window. When you create a new window it's usually just because you want to fork your lecture. You have found two interesting links to follow on the same page, for instance. In no way is one of the windows more important than the other one to the user. Both are part of the current lecture “tree”.

All the Mozilla derivated I've seen handles new windows (or tabs) from a programmer point of view. They are just new, virgin, history-less windows. A pity.

Wednesday, August 17, 2005

¿Es ilegal compartir música con eDonkey / eMule / bittorrent / KaZaa?

La respuesta intuitiva a esta pregunta es que sí, ya conoceis el discurso oficial, pirateria, chicos malos, etc.

En pocos paises se ha puesto en duda que algo asi sea ilegal, siendo bastante controvertido el método usado contra “los culpables”.

Los EE.UU. fueron pioneros de los ataques en justicia hacia este tipo de programas, primero contra sus creadores. Estos no siempre fueron condenados, argumentando que no eran responsables de las obras que los usuarios copiaban con sus programas. Cuando este método falló, los ataques cambiaron de objetivo, pasando a ser contra cualquiera que compartiese música sin la conveniente autorización del autor.

¿Como atacar a millones de personas? No hace falta atacar a millones, solo tenían que seleccionar unos cientos para conseguir el efecto deseado. Nadie volvió a sentirse impune, y arrancar kazaa pasaba a ser como jugar a la ruleta rusa.

En Europa la ley es distinta, pero naturalmente a grandes rasgos se mantiene la idea de la de EE.UU. Protección del copyright y de los derechos de autor.

Después de esta disgresión, volvamos a casa, a España, donde una lectura ingenua de la LPI parece sacar fuera de la ley a
los usuarios de los programas P2P.

Un extracto de los artículos que son en mi opinión relevantes:


Artículo 17. Derecho exclusivo de explotación y sus modalidades

Corresponde al autor el ejercicio exclusivo de los derechos de explotación de su obra en cualquier forma y, en especial, los derechos de reproducción, distribución, comunicación pública y transformación, que no podrán ser realizadas sin su autorización, salvo en los casos previstos en la presente Ley.

Artículo 18. Reproducción

Se entiende por reproducción la fijación de la obra en un medio que permita su comunicación y la obtención de copias de toda o parte de ella.

Artículo 19. Distribución

1. Se entiende por distribución la puesta a disposición del público del original o copias de la obra mediante su venta, alquiler, préstamo o de cualquier otra forma.
[...]

Artículo 20. Comunicación pública

1. Se entenderá por comunicación pública todo acto por el cual una pluralidad de personas pueda tener acceso a la obra sin previa distribución de ejemplares a cada una de ellas.

No se considerará pública la comunicación cuando se celebre dentro de un ámbito estrictamente doméstico que no esté integrado o conectado a una red de difusión de cualquier tipo.
[...]

Artículo 31. Reproducción sin autorización

1. Las obras ya divulgadas podrán reproducirse sin autorización del autor y sin perjuicio en lo pertinente, de lo dispuesto en el artículo 34 de esta Ley, en los siguientes casos:
[...]
2.º Para uso privado del copista, sin perjuicio de lo dispuesto en los artículos 25 y 99.a) de esta Ley, y siempre que la copia no sea objeto de utilización colectiva ni lucrativa.
[...]


Asi pues siguiendo con análisis “intuitivo”, la ley da derecho exclusivo al autor para la “reproducción, distribución, comunicación pública” de su obra, añadiendo una excepción para la reproducción de la obra, siempre que esta no sea “objeto de utilización colectiva ni lucrativa”. Una copia de un CD para llevar en el coche, por ejemplo. Primer detalle curioso, no necesitas hacer la copia a partir de un “original”, y en caso de que asi lo hagas, el “original” no tiene porque ser tuyo.

Hay sin embargo un abogado español, David Bravo Bueno que sostiene que compartir música en un programa P2P no cae dentro de:

  1. la utilización colectiva de la reproducción de una obra
  2. ni la distribución
  3. ni la comunicación pública

David expone su tesis en su Copia este libro (página 105 en adelante).

Las restricciones del artículo 31 son, tal y como David explica:

  1. Que la obra esté divulgada.
  2. Que la copia lo sea para uso privado del copista.
  3. Que la obra no sea objeto de utilización colectiva.
  4. Que no sea objeto de utilización lucrativa.

La única restricción potencialmente problemática para los que usan un programa P2P es la de la utilización colectiva, ya que al mismo tiempo que una canción o película se descarga en el ordenador se esta también enviando a los demás usuarios.

Sin embargo la ley entiende “utilización” en el sentido de escuchar una canción, o ver una pelicula, pero no se está “utilizando” una obra por el mero hecho de servir de soporte a una copia.

Asi pues, nada viola el derecho de reproducción sin autorización del autor cuando se usa un programa P2P.

Sin embargo, y aqui es donde mi postura se diferencia de la de David, no comparto su argumentación sobre la “Distribución” (página 111). él dice:


Sin embargo, es de manual (literalmente) que el acto de distribución no puede darse nunca en Internet porque se refiere, exclusivamente, a ejemplares físicos de las obras. El libro “Manual de Propiedad Intelectual” coordinado por Rodrigo Bercovitz nos recuerda que “la distribución implica necesariamente la incorporación de la obra a un soporte físico que permita su comercialización pública a través de los medios señalados en el art. 19. El carácter físico del soporte exige la posibilidad de aprehensión del mismo por parte del público (…). Todos aquellos modos de explotación que no permitan la incorporación física de la obra no pueden ser considerados como de distribución (…). El aspecto fundamental del derecho de distribución es que la obra se incorpore a un soporte tangible, general y similar para el conjunto de integrantes del público”.


(Un pie de nota añade que en este aspecto la doctrina especializada es unánime.)

Hay algo en lo que no estoy de acuerdo. Si leemos detalladamente los artículos 19 y 18 (en este orden), vemos lo siguiente:


Se entiende por distribución la puesta a disposición del público de[...] copias de la obra.
Se entiende por reproducción la fijación de la obra en un medio que permita [...] la obtención de copias[...]


Según cuenta David, son estos dos artículos juntos los que llevan a la conclusión de que para que haya distribución, la obra se tiene que incorporar a un soporte físico. Mi educación es la de un físico y no un abogado, pero volviendo a mis orígenes cartesianos, yo no veo en la descripción de la reproducción una claúsula que diga que solo se pueden obtener copias a través de la fijación de la obra en un medio.

Es decir, el enúnciado del artículo 18 no parece dar una forma exclusiva a la obtención de copias, y a partir de ahi, la deducción de que las copias a las que se refiere el artículo 19 tengan que tener un soporte material me parece errónea.

David comenta también que utilizar un programa P2P tampoco infringe el derecho exclusivo del autor a la “Comunicación pública” de la obra. Su argumento es el siguiente:


Las redes Peer to Peer establecen conexiones exclusivamente entre dos personas. Son redes “punto a punto” y resulta difícil calificar como comunicación pública un sistema que carece de público.


Esto es falso. Se puede traducir Peer to Peer como se quiera, pero
eso no hace que la comunicación sea exclusivamente entre dos personas. El término Peer to Peer tiene origen en la ausencia de un servidor en la red, asi pues todos los nodos de la red tienen el mismo estatus, y las comunicaciones se realizan entre “pares” (ningún comunicante tiene un estatus más elevado que el otro).

En general, un usuario conectado en una red P2P envia sus obras compartidas a varios usuarios simúltaneamente. Cuando un usuario A carga una de las obras de otro usuario B de la misma red, nada impide que A no sea el único “cliente” de B.

Para finalizar, y ya que David comenta un caso judicial francés para apoyar su tesis de que cargar obras por internet es legal[1], mencionar que ha habido numerosas condenas en Francia a usuarios de programas P2P, a pesar de que no tenían animo de lucro.

Nota: No soy abogado, ni lo parezco. Solo soy un ciudadano interesado por saber si puede usar los programas P2P con la conciencia tranquila, o no. Ha habido decisiones de justicia contradictorias en este sentido en Francia, pero la gran mayoría apuntan a que no es legal. La opinión de los abogados también es contradictoria, pero la inmensa mayoría también parecen estar de acuerdo en que no es legal.

La ley francesa y la española en este sentido se parecen como dos gotas de agua, pero el lenguaje utilizado es lo suficientemente sutil como para ignorar todo lo que se salga de la LPI.

En Francia no tengo muchas dudas de que no debo usar un programa P2P, y la única forma que me queda de sacar una conclusión al respecto es leer por mi mismo la ley, ya que la opinión de los expertos es contradictoria.

Si alguien quiere aportar alguna corrección a este artículo, que me la mande y la añadiré gustosamente.



1: Tesis con la que estoy de acuerdo. Con lo que no estoy de acuerdo es con que enviar obras por internet también sea legal.

Tuesday, August 16, 2005

Fade in and out

Playing with the effects in script.aculo.us I added a new little effect to switch from an element to another one smoothly.

Better see it in action, go to Panoramio, register as a new user, and see the little fade out of “Login     Register” and the fade in of “Hi Foo Bar”.

Sure enough, it was not working on IE. It's a documented problem, the Opacity effect didn't work on elements without layout. The “layout” is some kind of karma that IE throws on certain elements, and you can activate it manually if you use the right CSS incantation.

So here we go, I put height: 1px; to my CSS elements to no joy, it still didn't work. Let's try zoom: 1... on the money! My page didn't validate anyway (and no, I don't care) so I'm sell on zoom.

But now I have another problem. If you have cleartype activated the result is ugly beyond belief. Pssst. Well, nobody said that's going to be easy. Another google search, and we see this lovely blogger giving us a work-around. Just put an explicit background color to this element. Luckly enough I'm using an uniform background for this part of the site, so I just added a background-color: white; and now I have something that works like a charm at the very least on IE6 and on Firefox.

I can now take my breakfast.

Tuesday, August 09, 2005

Panoramio

It seems as this blog thing is not for me. I'm trying to resume regular posting (again).

I did lately some work on web technologies, to cut my teeth on Ajax and what not.

You can see the result at Panoramio. Still very crude, but I'm improving it. Things I should deploy very soon now™:


  • a way to login/register - so you can show your photos.

  • a revamped search - so you can have more than 50% chance of getting suggestions.

  • smaller previews on the sidebar - so you can... you know... see smaller previews on the sidebar

  • a help page - the thing that anybody ask for and nobody reads.


It's crazy the amount of work that can take a site that looks so simple. I should start blogging about all the stuff I find developping this thing, at least I will have a record.

The question of the day. Should I blog in spanish or in english?

As I don't think anybody is reading these rumblings, I will need to take a decision on my own...

Monday, July 11, 2005


De vuelta de la boda de Juan y Estela en España.

Wednesday, June 08, 2005

Word document format

I've started to learn the Word document format.

First, a doc file is a container of several files, like a zip file but not compressed and optimized to be read in blocks of 512 bytes (or 4096 sometimes).

The container spec is easily understandable, so a few hours after reading it I had a little C program that was able to extract the different "sub-files" (streams from now on).

All the meat for a Word document is in the "WordDocument" stream. Besides this stream you will find at least the "SummaryInformation" and the "DocumentSummaryInformation" streams, that store things like the Title, Subject, Author, etc. (go to File -> Properties in Word to see them).

The "SummaryInformation" and "DocumentSummaryInformation" streams are described in the Ole2 Programmer's Reference (fortunately we have a copy at work).

The "WordDocument" stream's format is much harder to decode, as here Word stores all the format information, text, etc. It seems that Microsoft published the Word spec on MSDN, and people have copied it on Wotsit, correcting some bits in the process.

So, with this spec, I read the header of the WordDocument trying to extract the text of my mini Word test file. First surprise, the doc says that text is stored between FIB.fcMin and FIB.fcMac (FIB is the header), but fcMin is 0x200 bytes before the beginning of my "Hello". If I read the text between FIB.fcMin and FIB.fcMac I got:

00 00 00 ... repeat 0x200 times ... H e l l o

I first though that I had a bug in my Ole decoder, as 0x200 is exactly the size of one big block in the Ole Container, but no luck, it seems that my code was not buggy, as I extracted the WordDocument stream using laola, but I was getting the same result.

Weird.

After looking at libwv, it seems that it ignores completely fcMin, as since Word 97 you need to read the piece table stored in the word file, even if it has been saved without the "fast-save" option (to know the encoding of each piece of text you read).

So I headed to where the piece table is supposed to be, to extract at least the first piece of text, but so far I've not yet made any sense from the piece table in my test document :-(

To be continued...

And then...

it crashed.

After 2 hours working on an icon, Gimp decided I should take a rest, and it crashed.

Of course, it would not be funny if I had saved it, and sure enough, I didn't save it. Not a single time.

I can hear you...
It's your fault! You should always save no matter what software are you using.


But sorry, I'm not that stupid. It's GIMP fault, 100%. Given that it's not the first time it decides to ruin several hours of my work, I wonder if I should start learning Photoshop. It can't be as hard as it seems...

And for all the artists out there, a wonderful link from simplebits: firewheel design has the best Portfolio I've never seen. Their colors on all their creations are extremely hot and vivid. A pleasure for the eye.