Cultured Perl: Perl and the Amazon Cloud, Parte 3

Cargar imágenes y crear, editar y borrar comentarios

Esta serie de cinco partes lo conducirá a través de la creación de un sencillo sitio Web de intercambio de fotos usando Perl y Apache para acceder a Simple Storage Service (S3) y a SimpleDB de Amazon. En esta entrega, siga la interacción de su sitio con SimpleDB aprendiendo cómo la dirección URL crea un registro de SimpleDB para el archivo cargado. Aprenda también cómo crear, editar y borrar comentarios como registros de SimpleDB en una foto para un usuario determinado.

Teodor ZlatanovGold Software Systems

Teodor Zlatanov egresó en 1999 de la Universidad de Boston con una licenciatura en ingeniería en computación. Trabaja como programador desde 1992 usando Perl, Java, C y C++. Sus intereses son el trabajo con código abierto sobre análisis de texto, las arquitecturas de bases de datos, las interfaces de usuarios y la administración de sistemas UNIX.



03-08-2011

Ha pasado ya un tiempo desde mi última entrega, por lo que recapitularé el contenido:

  • La Parte 1 detalló las arquitecturas S3/SimpleDB y explicó cómo usarlas a través de ejemplos prácticos.
  • La Parte 2 mostró cómo cargar un archivo en S3 desde una página Web a través de un formulario HTML, minimizando la carga en el servidor.

Saque el mejor provecho de esta serie

Esta serie requiere un conocimiento básico de HTTP y HTML, así como un conocimiento intermedio de JavaScript y Perl (dentro de un proceso de Apache mod_perl). También es útil tener un conocimiento de bases de datos relacionales, almacenamiento en disco y redes. Dado que la serie se vuelve cada vez más técnica, consulte la sección Recursos si necesita ayuda con alguno de estos temas.

Ahora empezaremos realmente a adentrarnos en la interacción del sitio de intercambio de fotos con SimpleDB de Amazon, aprendiendo cómo la URL exitosa crea un registro de SimpleDB para el archivo cargado, y aprendiendo cómo crear, editar y borrar comentarios como registros de SimpleDB en una foto para un usuario determinado (recuerde que no estamos comparando SimpleDB con BigTable de Google ni con soluciones independientes como CouchDB).

Al igual que en las entregas previas, usaré share.lifelogs.com como nombre de dominio.

Pero antes que nada, la estructura de la base de datos.

Haciendo nuevamente referencia a la Parte 1, establecimos allí una estructura de tabla como la que se muestra en el Listado 1:

Listado 1. Estructura de tabla de la Parte 1
share_photos:
      "http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif"
                { user: "ted", name: "Amazon Logo"} 
                "http://images.share.lifelogs.com/funny.jpg" {
                user: "bob", name: "Funny Picture",
                s3bucket: "images.share.lifelogs.com" }
                share_users: "ted"
                { given: "Ted", family: "Zlatanov" } "bob" { given: "Bob",
                family: "Leech" }
                share_comments: "random-string" { url:
                "http://images.share.lifelogs.com/funny.jpg", 
                comment: "Ha ha", posted_when:
                "2009-03-01T19:00:00+05" } "random-string2" 
                { user: "ted", url:
      "http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif",
                comment: "No it doesn't", posted_when: "2009-03-01T20:00:01+05" }
                "random-string3" {
url: "http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif",
                comment: "No it doesn't", reply_to: 
                "random-string2", posted_when:
                "2009-03-01T20:00:01+05" }

En esta versión de la estructura, usted puede almacenar todos los comentarios de un hilo dentro de una estructura de comentario, pero esto es peligroso si se permite que dos usuarios borren o editen un comentario del mismo hilo a la vez.

Como mencioné en la Parte 1, esta estructura está sujeta a cambios. Una gran ventaja de SimpleDB es su flexibilidad, por lo tanto usémosla. “La coherencia absurda es la obsesión de las mentes pequeñas” como dijo Emerson. Por supuesto, también dijo: “Odio las citas”. Al diablo con esos trascendentalistas que hablan sin decir nada.

El bloc de notas de SimpleDB me pareció menos útil que hacer las llamadas directamente desde el código, aunque es posible que a usted le guste. Busque en la sección Recursos la URL del bloc de notas. Usted también puede comprar varias herramientas de administración de SimpleDB, usar la herramienta gratuita para Firefox, o probar la shell Typica. Está todo en la sección Recursos; vaya y tome el control.


Cargar y modificar imágenes

Antes que nada, observe que SimpleDB permite valores múltiples para una única clave. Por lo tanto, la URL de imagen que he mencionado o el texto del comentario podrían ser matrices en lugar de valores simples. No usaremos esta característica, sino que preferiremos mantener las cosas simples con un solo valor por clave.

Comencemos con la actualización de la imagen. Cada vez que usted hace una carga, ejecuta el código para agregar la nueva imagen a la tabla share_photos.La Parte 2 le mostró el formulario de carga de S3; y en la próxima ocasión conectaremos ese formulario con el código escrito aquí.

Por ahora, escribamos una simple secuencia de comandos para agregar una imagen. Usted tiene un nombre de usuario, una dirección URL, un nombre de imagen, y un nombre de depósito opcional de S3. El depósito de S3 será simplemente un campo de la tabla; la URL será suficiente para mostrar y usar la imagen. Nos gustaría poder rechazar las cargas que tengan una URL duplicada. Pero ¿podemos hacerlo?

El problema con un almacén de datos distribuidos es que los datos que usted pone adentro de él pueden no haber salido del perímetro de la red. Es como llamar a Europa desde Japón (o hacer otra cosa en la que usted experimente una latencia o tiempo de espera en la red o en la señal de la voz): hay un ligero retraso después de cada frase mientras el otro lado se sincroniza con usted. Usted puede comenzar a hablar sin pausa, pero las respuestas del otro lado comenzarán a superponerse a sus palabras y usted se sentirá como un Verdadero Gerente en una Reunión Importante. Por lo tanto, si bien la latencia es buena para un discursoenérgicono es tan agradable cuando se trata de una conversación civilizada.

De manera similar, cuando usted pone datos dentro de un sistema SimpleDB, hay una pausa mientras los datos fluyen hacia un centro de datos. Ahora bien, esta parte no ha sido confirmada por Amazon, pero me han dicho que los datos se vuelven parte de la conciencia galáctica y mejoran la vida de criaturas de tipo babosas del sistema Runu (oriéntese a tres pársecs de Betelgeuse, doble a la izquierda y luego continúe y podrá verlos). De este modo, le estará haciendo un favor a las criaturas de tipo babosas del sistema Runu cada vez que use SimpleDB. Y usted pensaba que este artículo no era educativo.

De cualquier modo, además de mejorar la conciencia galáctica, sus datos se pondrán en marcha y sus consultas lo verán. Pero si usted hace consultas antes de que todo esto suceda, no sólo no mejorará la conciencia galáctica sino que usted obtendrá datos antiguos. Por lo tanto, no es tan simple como trabajar con una base de datos clásica como DB2, en la que los datos se ponen en marcha y tenemos ACID para asegurar que las transacciones son realmente enviadas cuando la base de datos lo dice. Con SimpleDB y otras bases de datos “eventualmente consistentes”, usted tiene que convivir con la incertidumbre.

El punto es que actualizar las imágenes no es tan sencillo. Nos gustaría rechazar las cargas que tengan una URL duplicada, pero no siempre es posible. Imagine que Alice carga http://horsey.com/wilbur.png y que Bob carga también http://horsey.com/wilbur.png al mismo tiempo. Si la carga de Alice entra primero y Bob no la ve, la carga de Bob la sobrescribirá. ¿Qué hacemos entonces?

Antes que nada, usted podría preguntarse, ¿cuál es el problema? Se incomoda en parte a los usuarios, pero no es nada de otro mundo. Además, no es una ocurrencia terriblemente probable. Bien, queremos tener a los usuarios contentos y, si somos obsesivos con la calidad, nos perturbará hasta nuestro lecho de muerte el haber lanzado un producto tan claramente imperfecto.

Por lo tanto, en lugar de llevar nuestra desdicha a la tumba, modificaremos nuestro diseño de tabla para las imágenes, como se muestra en el Listado 2:

Listado 2. Diseño de tabla modificado
                share_photos:"random-string10"
                { url:
"http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif",
                user:
                "ted", name: "Amazon Logo"} "random-string11"
                { url:
                "http://images.share.lifelogs.com/funny.jpg", 
                user: "bob", name: "Funny Picture",
                s3bucket: "images.share.lifelogs.com" }

Lascadenas aleatoriasque usted ha visto hasta ahora son UUID. No son perfectas, pero al menos nuestras imágenes no chocarán si las URL son iguales. Pero, un momento… ¿qué sucederá con los comentarios de las imágenes? Tranquilo, simplemente cambiaremos la clave externa como se muestra en el Listado 3:

Listado 3. Cambio de la clave externa
                share_comments:"random-string3"{ image_id:
                "random-string10", 
                comment: "No it doesn't", reply_to: "random-string2",
                posted_when: "2009-03-01T20:00:01+05" }

Ahora tenemos que considerar que puede haber múltiples entradas en share_photos con la misma URL, pero por lo demás el sistema parece estar bien.

Comprenda que, en lugar de mostrarle la versión artificialmente lista de las tablas, estamos resolviéndolas en conjunto. Esto me permite mostrar la flexibilidad de SimpleDB y también exhibir la agilidad de desarrollo en su mayor expresión: inventar, probar, refinar, repetir. En lugar de planificar todo, planificamos sólo lo necesario para pasar a la próxima etapa, aunque:

  • No olvidamos la imagen de mayor tamaño en ninguna ocasión.
  • Las decisiones arquitectónicas no se toman ni se cambian tan ligeramente como las decisiones específicas de tareas.

Por lo tanto, cargar una imagen es algo sencillo, ¿no? Simplemente agregue una nueva entrada a SimpleDB con la URL dada, el nombre de la imagen y el nombre del usuario. El depósito de S3 es opcional. Esto se hace con una llamada PutAttributes.

Modificar una imagen es igual de fácil, pero permitámonos sólo cambiar el nombre por ahora. Esto también se hace con una llamada PutAttributes.


Agregar y modificar comentarios

Consulte en la sección previa la tabla share_comments. Algo realmente simple. El agregado de un comentario requerirá el texto del comentario, el ID de la imagen y, de manera opcional, el ID del comentario primario y un nombre de usuario. Por ahora, la modificación de un comentario permitirá cambios sólo en el texto del comentario.


La secuencia de comandos independiente

He incluido una secuencia de comandos Perl independiente (simple_go.pl; usted puede conseguirla en la sección Descarga en la parte inferior de este artículo) para hacer las tareas que he mencionado (agregar y modificar una imagen, agregar y modificar un comentario). Ésta no creará los dominios, por lo tanto usted necesitará crear externamente los dominios share_photos.share.lifelogs.com y share_comments.share.lifelogs.com de SimpleDB. Esto es muy sencillo usando cualquiera de las herramientas de administración de SimpleDB. Observe que el conmutador de --domain convertirá share.lifelogs.com en otra cosa para obtener el nombre completo del dominio (almacenado en $full_domain).

La secuencia de comandos usa el módulo CPAN Data::UUID para generar nuevos identificadores únicos.

La secuencia de comandos es bastante desdeñosa en cuanto a la manipulación de errores, y elige morir() en cada oportunidad que se le presenta. Esto es algo perezoso y despreciable, y usted no debería hacerlo a menos que esté escribiendo artículos y quiera mostrar al mundo la absoluta depravación de los programadores que escriben artículos.

De nada.

Las últimas tareas son enviar una instrucción SELECT y borrar un elemento. Le mostraré aquí cómo implementarlas porque son sencillas y las necesitará más adelante.

Para catalogar las imágenes, llame a la secuencia de comandos como se muestra en el Listado 4:

Listado 4. Catalogación de imágenes
./simple_go.pl -l -i --ak=accesskey
                --sk=secretkey

Advertencia: asegúrese de que el equipo en que usted ejecuta esto no sea usado por otros. Otras personas podrán mirar la lista de procesos y ver su clave secreta de Amazon. De manera similar, si usted está en un shell que mantiene historiales, su clave secreta terminará en su archivo de historial. Una medida prudente es transferir un nombre de archivo y obtener la contraseña de ese archivo pero, en beneficio de la simplicidad, no la he implementado aquí.

Para catalogar comentarios:

Listado 5. Catalogación de comentarios
./simple_go.pl -l -c --ak=accesskey
                --sk=secretkey

Bastante fácil hasta ahora. Internamente la secuencia de comandos llama al método $service->select(), analiza los resultados e imprime los datos con show_list(). Todo se hace suponiendo que una clave tiene sólo un valor (observe que especificamos Replace=true en el método put()), por lo tanto ésta no es una secuencia de comandos SimpleDB multipropósito.

¿Por qué no usamos una secuencia de comandos multipropósito? Porque no la necesitamos. Adoptemos una solución simple. Si necesitamos múltiples valores, podemos adaptar la secuencia de comandos más adelante o simplemente escribir un nuevo código. Esta secuencia de comandos es el campo de juego para crear las estructuras de base de datos de nuestro sito Web.

No se tiente con usar esta secuencia de comandos en el sitio real (“Simplemente llamaré al system() y permitiré que los errores vayan a un archivo de registro”). Sí, tiene unos pocos cientos de líneas de código y funciona, pero es necesario descartar todos los prototipos sin lamentarlo si se desea escribir un programa real. No hagamos una excepción en este caso, aun si nos hemos encariñado un poco con sus sangrías de un espacio y su diseño fortuito (este…, “creativo”).

Volvamos a la secuencia de comandos. Crear una nueva imagen es simple (el depósito es opcional):

Listado 6. Creación de una nueva imagen
                ./simple_go.pl -i --ak=accesskey --sk=secretkey 
                -u ted
                --url="any url" --name="any name you like" 
                --bucket=mybucket

La edición del nombre de la imagen (-l -i nos dio un ID de 25EC17B8-0F6B-11DE-A1A1-944E07F9DEC1). Esto permite crear ahora una imagen con un UUID único:

Listado 7. Creación de una nueva imagen con un UUID único
                ./simple_go.pl -i --ak=accesskey
                --sk=secretkey --name="new name"
                --id=25EC17B8-0F6B-11DE-A1A1-944E07F9DEC1

De manera similar, es fácil crear un comentario (useryrefcommentidson opcionales):

Listado 8. Creación de un comentario
 ./simple_go.pl -c 
                --ak=accesskey --sk=secretkey -u ted
                --refimageid="any image ID" --text="the text" 
                --refcommentid='any comment ID'

Nuevamente, el ID del comentario será de un UUID único. La edición del texto de un comentario se realiza de esta manera (-l -cnos dio un ID de 4BE2EA0A-0F6B-11DE-976B-A542FC6BD07C):

Listado 9. Creación de un comentario con un UUID único
                ./simple_go.pl -c --ak=accesskey
                --sk=secretkey --text="the text" 
                --id=4BE2EA0A-0F6B-11DE-976B-A542FC6BD07C

Finalmente, el borrado de imágenes o comentarios se realiza de esta manera:

Listado 10. Borrado de imágenes y comentarios
                ./simple_go.pl --delete -i --ak=accesskey
                --sk=secretkey --id=25EC17B8-0F6B-11DE-A1A1-944E07F9DEC1
                ./simple_go.pl --delete -c
                --ak=accesskey --sk=secretkey
               --id=4BE2EA0A-0F6B-11DE-976B-A542FC6BD07C

Conclusión

Esta entrega mostró cómo se crean, editan y borran imágenes y comentarios en la base de datos SimpleDB que respalda el sitio de intercambio de fotos que estamos creando.

Hemos establecido el esquema (de manera aproximada) e implementado una herramienta para agregar, catalogar, modificar y borrar imágenes y comentarios. Hemos establecido los UUID como la clave primaria tanto para imágenes como para comentarios a fin de evitar el escenario improbable de que dos usuarios carguen la misma URL de imagen a la vez.

Hemos establecido que usaríamos sólo un único valor por clave, ya que actualmente nuestro esquema no exige más y estamos buscando la simplicidad. Tal vez sea necesario tratar esta imperfección más adelante en el código, pero por el momento conviviremos con ella.

En la Parte 4 se le mostrará cómo comenzar a ensamblar todo esto en un sitio Web mod_perl.


Descargar

DescripciónNombretamaño
Sample script for this articlesimple_go.zip4KB

Recursos

Aprender

Obtener los productos y tecnologías

Comentar

  • Participe en la comunidad My developerWorks; con su perfil personal y su página principal personalizada, usted puede adecuar developerWorks a sus intereses e interactuar con otros usuarios de developerWorks.

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Lotus, WebSphere
ArticleID=412583
ArticleTitle=Cultured Perl: Perl and the Amazon Cloud, Parte 3
publish-date=08032011