lunes, 9 de junio de 2014

Como configurar un RAID0 en AWS

La problemática empieza por mejorar la performance de IO en el server de Base de datos no es un problema actualmente pero tampoco queremos que lo sea

Primero que todo configuramos para nuestro renovado server una de las instancias con mejor performance de memoria según Amazon las instancias R3 [0]

Las instancias R3 están optimizadas para aplicaciones con un uso intenso de la memoria y ofrecen el coste más bajo por GiB de RAM entre los tipos de instancias de Amazon EC2.
Estos servidores tienen un Almacenamiento de Instancia [1] respaldado en Disco SSD pero estos son temporales por consiguiente si se Para y luego se Inicia nuevamente todo lo que habia en ese disco simplemente desaparece. Por eso decidimos seguir respaldando la DB en un EBS [2] y para mejorar un poco más la performance decidimos poner dos EBSs en RAID0

Entonces empecemos contando que es un EBS.  Amazon Dice:
Amazon Elastic Block Store (Amazon EBS) proporciona volúmenes de almacenamiento de nivel de bloque persistentes y diseñados para utilizarlos con las instancias de Amazon EC2 en la nube de AWS.
En resumen son digamos unos discos rigidos a pedido que van y vienen por la nube y que se pueden adjuntar a cualquier tipo de Instancia de EC2 y que son de almacenamiento permanente.

Ahora vamos con un poco sobre algo que siempre me costó entender ¿que es un RAID? [3]. Básicamente es un conjunto de discos independientes que se usan en conjunto generalmente para dar mayor redudancia a las implementaciones de Almacenamiento. Releyendo para escribir este Post me acuerdo cual es el motivo de que nunca lo terminara de entender y el motivo es que tiene muchos niveles y algunos resultan realmente complejos. Nivel se le llama a cada tipo de configuración que existente. Obviamente nosotros vamos a explicar algunas de las más caracteristicas.

El RAID0 (Data Striping) es la útilización de un conjunto de discos fisicos como si fueran uno solo. En verdad lo que se hace es distribuir equitativamente los datos en uno y otro disco por lo que esta configuración no le agrega redundancia al almacenamiento pero si nos ayudará en la mejora del rendimiento de lectura y escritura. En cuanto al tamaño este es limitado por el más pequeño de los discos si se tiene 2 discos de 100 GB el tamaño se duplicaría entonces pasariamos a tener un disco de 200GB ya que cada uno aporta 100GB a la distribución, pero si se tiene un disco de 300GB y uno de 100GB la distribución se hace sobre el más pequeño y cada uno aporta 100GB por lo que se obtiene un disco de 200GB perdiendo 200GB del disco más grande.


El RAID1 (Mirroring) crea una copia exacta de cada dato que va a un disco en uno o más. Esto es bueno para entornos donde es más importante la velocidad de lectura que la capacidad ya que (en su implementación más básica) se usarían dos discos de 100 GB cada uno y el máximo de almacenamiento es tanto como el más pequeño de los discos. Además tener un disco copiado exactamente le agrega redundancia al conjunto lo que es muy útil en ambientes de alta disponibilidad ya que si un disco falla el otro puede tomar su lugar sin demasiado problema.



Hay más? Si mucho más y es un tema largo y se puede volver bastante complejo. Leer en Wikipedia te va a dar una buena mirada [3].

Ahora vamos a lo nuestro como configurar un RAID0 para una instancia EC2 sobre Volúmenes EBS primero adjuntamos dos volumenes EBS a nuestra Instancia esto se puede hacer durante el lanzamiento de la Instancia en la Sección de "Add Storage" o posteriormente desde el Panel de Volúmenes de EC2 creando un Volumen y luego adjuntandolo a la Instancia. En este caso vamos a usar dos volúmenes de 30 GB.

Nosotros somos gente grosa así que usamos el tipo de servidores que sostiene al 95% de Internet servidores Linux entonces vamos a usar el comando "lsblk" que según man "lista los dispositivos de bloque"

vamos a  ver algo como esto

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 8G  0 disk
└─sda1   8:7    0  8G  0 part /
sdb      8:0    0 30G  0 disk
sdc      8:0    0 30G  0 disk

El disco sda de 8G es el que se monta como root por default en todas las intancias EC2 y el sdb y sdc son los que se van a usar para hacer el RAID0.

$ sudo mdadm --create --verbose /dev/md0 --level=stripe --raid-devices=numero_de_volumenes dispositivo_1 dispositivo_2

Ejemplo:
$ sudo mdadm --create --verbose /dev/md0 --level=stripe --raid-devices=2 sdb sdc

Esto básicamente lo que hace es crear un nuevo dispositivo llamado md0 con los bloques sdb y sdc usando el nivel "stripe" que también podría ser "0" o "raid0"
-l, --level=
              Set  RAID  level.  When used with --create, options are: linear,
              raid0, 0, stripe, raid1, 1, mirror, raid4, 4, raid5,  5,  raid6,
              6, raid10, 10, multipath, mp, faulty, container.  Obviously some
              of these are synonymous.
Luego crearemos un sistema de archivos y un punto de montaje para montar el dispositivo.

$ sudo mkfs.ext4 /dev/md0
$ sudo mkdir /mnt/md0
$ sudo mount -t ext4 /dev/md0 /mnt/md0

Una vez montado ya podremos usarlo pero tendremos algunos problemas (no aparecerá el punto de montaje) si paramos y prendemos la instancia para eso se debe agregar la siguiente linea al archivo /etc/fstab. 

/dev/md0 /mnt/md0 ext4 defaults 0 0

Como dice el man de fstab 

The file fstab contains descriptive information about the various file systems. fstab is only read by programs, and not written; it is  the duty  of  the system administrator to properly create and maintain this file.

Y listo ya tenemos nuestro raid0 configurado en nuestra instancia ec2 o en verdad en cualquier linux.

Pueden probar como mejora el performance de IO con diferentes herramientas hdparm [4] o bonnie++ [5]

Más data de como hacer esta configuración y sus ventajas y desventajas en el siguiente link [6]

[0] http://aws.amazon.com/es/ec2/instance-types/
[1] http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html
[2] http://aws.amazon.com/es/ebs/
[3] http://es.wikipedia.org/wiki/RAID
[4] http://es.wikipedia.org/wiki/Hdparm
[5] http://en.wikipedia.org/wiki/Bonnie++
[6] http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/raid-config.html

domingo, 27 de abril de 2014

#Flisol2014 sede Agenda Digital



Panel de apertura "El vínculo entre el Software Libre y el Estado"
Constanza Necuzzi - Pablo Etcheverry - Santiago Ceria

Pablo Etcheverry hizo una exposición sobre los aprendizajes con respecto al Software Libre en el estado, algunos referentes a las dificultades en la coordinación de las necesidad de las areas especificas del estado que necesitan seguir gestionando sus recursos y la idea de ingresar cada vez con más software libre que por momentos son dispares, ya que el estado no puede dejar de funcionar por que se quieran cambiar sus sistemas a software libre hay cosas que llevan todo un proceso de migración.Constanza Necuzzi, hizo un analisis más profundo que el SoftLibre en sí, sino abarcando a "Las Comunidades de Práctica" [8] y como estas comunidades de práctica en general y la de software Libre en particular ayudan a generar una sociedad mejor. Santiago Ceria, nos contó sobre el programa Programar2020 [9] y como la programación y el conocimiento informático en general es importante para entender la complejidad del mundo moderno.

Panel: ¿Qué es el Grupo de Trabajo Software Libre del Foro de la Agenda Digital? [0] - Laura Marotias - Verónica Xhardez
Laura y Veronica contaron cual es su lugar dentro del Foro de la Agenda Digital y como de a poco van de manera transversal tocando las diferentes áreas que participan en aquel foro. Pero empecemos desde el principio la Agenda Digital Argentina "es una herramienta creada mediante el Decreto presidencial 512/2009 que impulsa la conformación de un Gabinete Multisectorial orientado al aprovechamiento de las posibilidades que ofrece la Sociedad de la Información y el Conocimiento." [1] y el Foro propiamente dicho, es un encuentro interinstitucional donde se debaten diferentes temáticas dentro de los que la agenda Digital tiene injerencia. Además, este lugar se convierte en un espacio "predecisional" donde diferentes organismos del estado, organizaciones civiles, etc. pueden participar de estas predecisiones, que luego, serán o no parte de una política pública según lo decidan quienes los funcionarios o las instituciones como el Congreso, etc. Los grupos que forman parte actualmente del foro son los siguientes:
Interoperabilidad, Gestión Documental/Digitalización, Profesionalización del Gestor de Información, Software Público, Datos Públicos, GeoInformación, Software Libre, Gobierno Abierto, Seguridad, Contenidos Públicos. [2]

En ese marco el Grupo de Software Libre [3] se encarga de concientizar a los diferentes interesados sobre la necesidad y/o conveniencia de utilizar Software Libre en el estado. Muy Pronto van a lanzar una Web donde presentarán casos éxitos de utilización de software Libre en el estado www.softwarelibre.gob.ar. Donde entre otras cosas se va a mostrar el caso de Éxito de la ANAC [4] y Xtech [5] que viene a continuación.

Panel: "El vínculo entre el Estado y las empresas de Software Libre: el caso ANAC - Xtech" - Sandra D'Agostino - Daniel Coletti

Sandra D'agostino nos relató la cantidad importante de Software Libre con el que trabaja la ANAC y como gracias a eso ahorran mucho en Licencias para invertir su "buen financiamiento" en lo que para ellos es más importante. Luego Daniel Coletti contó como por intermedio de una licitación pública que ganó Xtech la empresa de la que es dueño, empezaron un proceso de migración del correo electronico de la ANAC que antes funcionaba bajo software privativo, y que ahora, va a pasar a funcionar bajo Expresso Livre[6] que es la misma plataforma que funciona actualmente en el correo de Brasil, el cual implementó esta solución en forma acelerada desde que el Gobierno Brasilero se enteró del espionaje internacional que estaba sufriendo [7]. 

En síntesis

Las charlas a mi criterio fueron muy interesantes para saber como se mueve la comunidad de software libre dentro del estado, como se van ganando espacios de a poco y se va demostrando no solo lo importante que es a nivel económico sino lo importante que es a nivel soberanía tecnológica, independencia de las corporaciones y la apropiación de la dirección que se le quiere dar al software por parte del estado amoldandolo a sus necesidades reales.

jueves, 24 de abril de 2014

Pascal debe morir!

Pascal [0] ha sido un lenguaje muy interesante y posiblemente lo siga siendo para aprender algoritmos pero tengo la sensación que para aprender a Programar o como parte de una materia como Programación I, hace rato que es demasiado pobre, sobre todo por que hoy en día no sirve para nada más que aprender. Entonces los alumnos o quienes están aprendiendo pierden tiempo (no mucho en verdad pero todos sabemos que el tiempo es "dinero") aprendiendo su sintaxis aprendiendo algunas características particulares que no sirve para nada más que aprender no a programar :S en mi punto de vista sino para aprender algoritmos que debería ser utilizado capaz dentro de esa misma materia. Si bien quien lee este post sabe que soy Fan de Python también saben que Python es categorizado por muchos como un buen lenguaje para aprender, además de ser un lenguaje de propósito general, por lo cual aquel pibe que sabe la sintaxis de Python aprende (además del pensamiento algorítmico) un lenguaje que le puede servir para programar Web, para Programar aplicaciones de Escritorio y para hacer pequeños Scripts para automatizar cosas.
Sin ir más lejos el año pasado participé del PyDay Junin y allí en la UNNOBA[1] presentaron la muy buena iniciativa de cambiar su primer lenguaje de programación que era justamente Pascal por Python [2] [3]  y hay, desde hace unos años, cada vez más lugares donde se enseña Python como lenguaje de programación de entrada [4]. Igualmente aunque no parezca mi idea no es decir que Python DEBE ser el lenguaje de programación en verdad creo que cualquier otro lenguaje de los masomenos modernos (Python, Ruby, etc) puede ser útil para entusiasmar a los que aprenden programación en sus primeros pasos.

Esto se basa en algo que leí hace poco pero que siempre creí sin conocer esta frase.

"Si quieres construir un barco, no empieces por buscar madera, cortar tablas o distribuir el trabajo. Evoca primero en los hombres y mujeres el anhelo del mar libre y ancho."
Antoine de Saint-Exupéry

El proceso de conocer algo no siempre es hermoso, fluido y tangible generalmente es abstracto, a veces engorroso y pareciera poco útil por eso creo fervientemente que para hacer algunas cosas en programación o en cualquier trabajo en verdad. uno debe creer en lo que hace, debe amar lo que hace, por que sino no se entiende como alguien hace cosas tan complicadas. Por eso mi justificación es que Pascal no ayuda en ese proceso HOY de amar la programación, capaz si lo hacia hace años pero creo que el Rol de quienes enseñan hoy en día es actualizarse y no tenerle miedo al cambio y además ser autocríticos y analizar año a año el cambio de los paradigmas sino pasa que te quedás atrás inevitablemente y con eso atrasas a todos a los que les enseñás.
[0] http://es.wikipedia.org/wiki/Pascal_(lenguaje_de_programaci%C3%B3n)
[1] http://www.unnoba.edu.ar/
[2] http://prezi.com/haoscmd_yuca/cambio-de-lenguajes-para-programacion-imperativa/
[3] http://journal.info.unlp.edu.ar/journal/journal35/papers/JCST-Apr13-6.pdf
[4] http://python.org.ar/Proyectos/UsoDePythonEnLaUniversidad

miércoles, 9 de abril de 2014

Aprendiendo Erlang parte 6 Modulos II

Una última función agregada al modulo, usando ambas funciones anteriores

greet_and_add_two(X) ->
    hello(),
    add(X,2).

No olvides agregar greet_and_add_two/1 a la lista de funciones exportadas. En las llamadas a hello/0 y add/2 no necesitas escribir el nombre del modulo delante de ellos por que son declaradas en el módulo mismo.

Si hubieras querido ser capaz de llamar a io:format/1 en la misma manera que add/2 o cualquier otra función definida en el módulo, deberías agregar el siguiente atributo de modulo al comienzo del archivo -import(io, [format/1]). Entonces podrías llamar a format('Hola Mundo!~n'). directamente. De manera más general puede seguir esta receta.

-import(Module, [Funcion1/Aridad, ..., FuncionN/Aridad]).

Importar una función no es más que un atajo para los programadores cuando escriben su código. Los programadores Erlang a menudo desalientan el uso del atributo -import ya que algunas personas encuentran que reduce la legibilidad del código. En el caso de io:format/2 la función io_lib:format/2 también existe. En caso de que se use una de estas el programador tendría que ir al comienzo del archivo para saber de cual de las dos se trata. Consecuentemente, dejar el nombre de módulo es considerada una buena práctica. Usualmente, las únicas funciones que verás importadas vienen del módulo de listas: estas funciones son usadas con mucha frecuencia  que las otros módulos.

Tu módulo useless debería ahora verse algo así

-module(useless).
-export([add/2, hello/0, greet_and_add_two/1]).

add(A,B) ->
    A + B.

%%
%%
hello() ->
    io:format("Hola mundo!~n").

greet_and_add_two(X) ->
    hello(),
    add(X,2).

Hemos terminado con el módulo 'useless'. Puedes guardar el archivo bajo el nombre userless.erl . El nombres del archivo deberá el nombre del módulo como fue definido en el atributo -module, seguido de '.erl' que es el tipo de extensión standard para Erlang.

Anteriormente vimos como compilar el módulo y finalmente intentar todas sus funciones, veremos como definir y usar macros. Las macros de Erlang son realmente similares a las declaraciones '#define' de C, principalmente usado para definir funciones cortas y constantes. Ellas son expresiones simples representadas por texto que será reemplazado antes de que el código sea compilado por la VM. Tales macros son útiles principalmente para evitar valores mágicos flotando alrededor de tus módulos. Una macro es definida como un atribudo módulo de la forma -define(MACRO, some_value).  y es usada como ?MACRO dentro de cualquier función definida en el módulo. Una 'función' macro debería escribirse como -define(sub(X,Y), X-Y). y usada como ?sub(23,47) luego reemplazado por 23-47 por el compilador. Algunas personas usarán macros más complejas, pero la sintaxis básica se mantiene igual.

Compilando el código

El código Erlang es compilado a bytecode para ser usado por la máquina virtual. Puedes llamar al compilador desde distintos lugares $ erlc flags file.erl en la linea de comandos, compile:file(FileName) en la shell o en un módulo c() en la shell, etc.

Es tiempo de compilar nuestro módulo useless. Abrir la Shell de Erlang y escribir lo siguiente.

1> cd("/path/to/where/you/saved/the-module").
"Path name to the directory you are in"
ok

De manera predeterminada, la shell solo busca archivos en el mismo directorio que esté fue lanzado y en la libreria estandar: cd/1 es una función definida exclusivamente para la Shell de Erlang, diciendole que cambie el directorio uno nuevo por lo que es menos molesto navegar por nuestros archivos. Los usuarios de Windows deberían recordar de usar la barra invertida. Cuando esto se realice haz lo siguiente.

2> c(useless).
{ok, useless}

Si obtienes otro mensaje, asegurate que el nombre del archivo es correcto, que estás en el directorio correcto, y que no tienes errores en tu módulo. Una vez que compiles el código exitosamente, te darás cuenta que un archivo useless.beam fue agregado en el mismo directorio que tu useless.erl. Este es el módulo compilado. Probemos nuestras funciones.

3> useless:add(7,2).
9
4> useless:hello().
Hello, World!
ok
5> useless:greet_and_add_two(-3).
Hello, World!
-1
6> useless:not_a_real_function().
** exception error: undefined function useless:not_a_real_function/0

Las funciones funcionando como esperamos add/2 agrega números, hello/0 muestra por pantalla "Hello World!", y greet_and_add_two/1 hace ambas cosas. Por supuesto, te preguntarás por que hello/0 retorna el atomo ok luego del texto saliente. Esto es por que las funciones Erlang y expresiones deben siempre returnar algo, incluso si ellas no son necesarias en otros lenguajes. Así como, io:format/1 retorna 'ok' para denotar una condición normal, la ausencia de errores.

La expresión 6 muestra un error siendo lanzado por que una función no existe. Si te olvidás de expotar una función, este es el tipo de mensaje de error que obtendrás cuando lo ejecutes.

Hay un montón de banderas de compilación existentes para tenes más control sobre como es compilado el módulo.  Puedes obtener una lista de todos ellos en la documentación de Erlang [0] . Los más comunes son.

-debug_info
Las herramientas de Erlang como debuggers, cobertura de código, y herramientas de analisis estático se usan para la información de depuración de un módulo con el fin de realizar su trabajo.

-{outdir, Dir}
Por default, el compilador de Erlang creará los archivos 'beam' en el directorio actual. Este te permitirá elegir donde poner el archivo compilado.

-export_all
Ignorará el atributo -export del módulo y en su lugar exportará todas las funciones definidas. Este es principalmente útil cuando estás probando o desarrollando código nuevo, pero no debería ser usado en producción.

-{d, Macro} or {d,Macro,Value}
Define una macro a ser usada en el módulo, donde Macro es un atomo. Este es usado más frecuentemente cuando se trata de pruebas unitarias, lo que garantiza que un módulo solo tendrá sus funciones de prueba creadas y exportadas cuando se quieren explicitamente. Por default, Value es 'true' si esta no es definida en el tercer lugar de la tupla.

Para compilar nuestro módulo useless con algunas banderas, deberíamos hacer lo siguiente:

7> compile:file(useless, [debug_info, export_all]).
{ok, useless}
8> c(useless, [debug_info, export_all]).
{ok, useless}

Puedes tambien ser astuto y definir opciones del compilador dentro de un módulo con un atributo de módulo:

-compile([debug_info, export_all]).

Entonces solo compilará y obtendrás los mismos resultados que si pasaras las banderas manualmente. Ahora estamos listos para escribir funciones, compilarlas, y ejecutarlas. Es el momento de ver hasta donde podemos llevarlo.

Tarde y de a poco sigo traduciendo, como salga, pero aprendiendo algo cada día. [1]
[0] http://erlang.org/doc/man/compile.html
[1] http://learnyousomeerlang.com/modules

martes, 18 de marzo de 2014

Patrones Estructurales - Adapter

Los patrones estructurales se refieren a como las clases y objetos son compuestos para formar grandes estructuras. Los patrones de clase estructural usa herencia para componer interfaces o implementaciones. Como un ejemplo simple, considerar como la herencia múltiple mezcla dos o más clases dentro de uno. El resultado es una clase que combina las propiedades de su clase padre. Este patrón es particularmente útil para hacer que bibliotecas de clases desarrolladas independientemente trabajen juntas. Otro ejemplo es la forma de la clase del patrón Adapter. En general, un adaptador hace una interfaz (el adaptado) para ajustarse a otro, así provee una abstracción uniforme de diferentes interfaces. Una clase adaptador logra esto por la herencia privada desde un clase adaptada. El adaptador entonces expresa su interfaz en términos del adaptado.

Adapter

Intento,
Convertir la interfaz de una clase a otra interfaz que el cliente espera. Adapter permite que las clases trabajen juntas que de otro manera no podrían por que sus interfaces son incompatibles.

Motivación
A veces una clase de una caja de herramientas que es diseñada para su reutilización no es reutilizable solo por que sus interfaces no coinciden con la interfaz especifica del dominio que una aplicación requiere.
Considera por ejemplo un editor de dibujo que permite a los usuarios dibujar y organizar los elementos gráficos (lineas, polígonos, texto, etc.) dentro de imágenes y diagramas. La clave del editor de dibujo es el objeto gráfico, que tiene una forma editable y puede dibujarse a si mismo. La interfaz para objetos gráficos es definido por una clase abstracta llamada Shape. El editor define una subclase de Shape por cada tipo de objeto gráfico: un clase LineShape para lineas, una clase PolygonShape para polígonos, y así sucesivamente.

Clases para cada forma elemental de la geometría como LineShape y PolygonShape son bastante fáciles de implementar, porque su dibujo y capacidades de edición son limitados por la herencia. Pero una subclase TextShape que puede mostrar y editar texto es considerablemente más dificil de implementar, desde la edición de texto, incluso lo más básico consiste en la actualización constante de la pantalla y el manejo del buffer. Mientras tanto un producto listo para la interfaz de usuario es el kit de herramientas que deberia estár listo para proveer una sofisticada clase TextView para mostrar y editar texto. Idealmente, nos gustaría reusar TextView para implementar TextShape, pero el kit de herramientas no fue diseñado con la clase Shape en mente. Así que nosotros no podemos usar los objetos TextView y Shape de manera intercambiable.

Como puede una clase existente y no relacionada como TextView trabajar en una aplicación que espera clases con una interfaz diferente e incompatible? Podríamos cambiar la clase TextView tal que sea ajuste a la interfaz de Shape, pero ese no es una opción a menos que nosotros tengamos acceso el código fuente del kit de herramientas. Incluso si lo tuvieramos, no tendría sentido hacer el cambio a TextView; el kit de herramientas no deberia tener que adoptar interfaces especificas del dominio solo para hacer que una aplicación funcione.

En su lugar, definimos TextShape tal que esta adapte la interfaz de TextView a Shape's. Podemos hacer esto en una o dos maneras: (1) por herencia de la interfaz de Shape e implementación de TextView o (2) componiendo una instancia de TextView con una TextShape e implementando TextShape en terminos de la interfaz de TextView. We call TextShape an adapter.

Aplicabilidad
Usa el patron Adapter cuando:

  • quiere usar una clase existente, y su interfaz no coincide con el que usted necesita.
  • quiere crear una clase reutilizable que coopera con clases no relacionadas o imprevistas, es decir, clases que no necesariamente tienen interfaces compatibles.
  • (solo adaptador de objetos) necesitas usar muchas subclases existentes, pero no es práctico adaptar su interfaz por subclaseo cada vez. Un objeto adaptador puede adaptar la intefaz de su clase padre.
Participantes.
Target, define la interfaz especifica del dominio que el cliente usa.
Cliente, colabora con objetos ajustándose a la interfaz del Target.
Adaptee, define una interfaz existente que necesita ser adaptada.
Adapter, adaptar la interfaz del Adaptee a la interfaz de Target.

Ejemplos de uso en Python [0] [1]

Patrones Creacionales - Singleton

Intento,
Asegurar que una clase solo tiene una instancia y proveer un punto de acceso global.

Motivacion

      Es importante para algunas clases tener exactamente una sola instancia. Aunque puede haber muchas impresoras en un sistema, debe haber solo una cola de impresión. Debe ser solo un sistema de archivo y un administrador de ventanas. Un filtro digital tendrá un convertidor A/D. Un sistema contable será dedicado a server una compania.
Como podemos asegurar que una clase tiene solo una instancia y que la instancia es facilmente accesible? Una variable global hace a un objeto accessible, pero no te resguarda de instanciar multiples objetos.

Una mejor solución es hacer a la clase responsable de si misma para mantener un registro de una sola instancia. La clase puede asegurar que ninguna otra instancia puede ser creada(interceptando los pedidos para crear nuevos objetos), y puede proveer una manera de acceder a la instancia. Este es el Patrón Singleton.

Aplicabilidad

Usa el patrón Singleton cuando.

  • Debe haber exactamete una instancia de una clase, y esta debe estar accesible a los clientes de un punto de acceso conocido.
  • Cuando la única instancia debería ser extensible por subclaseo, y los clientes deberían ser capaces de usar un instancia extendidad sin modificar su código.
Participantes
Singleton, define una operación de Instance que permite a los clientes acceder a la instancia unica. Instance es una operación de clase (que es, un metodo de clase en Smalltalk y una función miembro estático en C++).
Puede ser responsable por crear la propia única instancia.

Ejemplos del Patrón Singleton [0] [1] 

lunes, 17 de marzo de 2014

Analizando Quiper - Compará precios descuidados

Quiper[0], es una aplicación móvil desarrollada en la empresa donde trabajo, que se llama Quicuo[1].

Su nombre es principalmente una fusión de la palabra Quicuo y Super. Es una aplicación que permite comparar los precios de todo tipo de productos en los supermercados más grandes del país y en principio funciona bastante bien para los que son de Capital y Gran Buenos Aires.

Aplicación Movil
La aplicación móvil está desarollada en HTML, CSS y Javascript. Con una terrible ayuda de PhoneGap [2] para hacerla multi plataforma. Principalmente fue creada para Android[3] pero con muy pocos cambios puede ser y va a ser generada para IPhone muy pronto.

Backend - API
La API de consulta está desarrollada sobre node.js[4], con expressjs[5] como Framework de desarrollo y sequelize[6] como ORM[7] para las consultas a la base de datos.
Todo esto es servido a tráves de pm2[15] como supervisor de procesos en nodejs y con Nginx[16] como WebServer.

Backend - DB, Extracción y Analisis
La extracción que es parte principal del desarrollo está escrita sobre Python[9], en principio se analizó un Scrappeador profesional pero para los primeros intentos nos pareció un poco complejo así que se optó por hacer un Scrapper propio bien amoldado para nuestro propósito. Por consiguiente, se utilizaron diferentes librerías que son bastante típicas en verdad para esto. BeautifulSoup[10] como parseador de las respuestas HTML para extracción de datos. Mechanize[11] como generador de requests dinamicas y crawler de webs, en principio fue generado todo con Mechanize y luego en algunos casos simples se usó requests[12] una librería con una API mucho más elegante. Además para guardar estos datos de forma más programática se uso SQLObject[13] como ORM en esta etapa.

Finalmente el análisis y unión de datos fue escrito en PHP[14] y se usó su conector para MySQL limpio sin ORM.

Servidores
Básicamente los servidores están en Amazon EC2[17] y por el momento son Dos uno como WebServer para los servicios que corren Nodejs. La Api que consume la app móvil y la Web que todavia no se lanzó.
Y otro server que es el más grande y es el de la DB que tiene MySQL y corre periódicamente la extracción y análisis de datos.
Los servidores fueron ambos desplegados con Ansible [18]

Un crisol de tecnologías libres que unidas generan una aplicación que funciona y cumple su objetivo, principalmente participaron de este proyecto Dos Desarrolladores(principalmente uno para Phonegap css html y js y otro para el Analisis de datos con PHP), un ProjectLeader, el CEO de Quicuo y un SysAdmin/Desarrollador Python (este soy yo).

[0] http://www.quiper.com.ar
[1] http://www.quicuo.com.ar
[2] http://phonegap.com/
[3] https://play.google.com/store/apps/details?id=com.quicuo.quiper
[4] http://nodejs.org/
[5] http://expressjs.com/
[6] http://sequelizejs.com/
[7] http://en.wikipedia.org/wiki/Object-relational_mapping
[8] http://www.mysql.com/
[9] https://www.python.org/
[10] http://www.crummy.com/software/BeautifulSoup/
[11] http://wwwsearch.sourceforge.net/mechanize/
[12] http://docs.python-requests.org/en/latest/
[13] http://sqlobject.org/
[14] http://php.net/
[15] https://github.com/Unitech/pm2
[16] http://nginx.org/
[17] http://aws.amazon.com/es/ec2/
[18] http://www.ansible.com/home