Monday, May 17, 2010

Conclusión

A lo largo de este semestre se aprendió un nuevo lenguaje de programación. Se aprendieron nuevas técnicas del desarrollo de software. Se utilizo subversion para tener el código siempre disponible y se realizo un proyecto de un tamaño importante.

Se pudo ver como clojure es un lenguaje muy poderoso que requiere de mas tiempo para poder ser dominado. Y algo que todos nos llevamos es que nunca la primera solución que se nos ocurre es la ideal para el problema.

Sunday, May 16, 2010

Recetas de cocina


El conocimiento no vale si no se comparte, es una frase bastante sabia, ya que si uno se queda callado y no divulga su conocimiento, es como si este no existiera por que no vale.

Empezamos este post con esta reflexión, ya que en este caso vamos a compartirles algunas cosas que hemos encontrado y que nos han servido durante la realización de nuestro proyecto. Nosotros decidimos hacer este blog en español para que pudiera ayudar con la información que contiene a personas que hablen español y que tengan problemas en entender el ingles, o simplemente les guste mas su lenguaje.

A continuación unas “recetas de cocina”(por que se siguen los pasos y queda), que nos fueron bastante útiles

Serializar datos para poder mandarlos en un socket:

(defn serializar
"Convierte estructuras en strings"
[datos]
(binding[*print-dup* true]
(print-str datos))
)

Realizar un MessageDigest, en este caso MD5

(defn MD5
"Calcular el MD5 de ciertos datos”
[datos]
(let [md (doto (MessageDigest/getInstance "MD5"))]
(.update md (.getBytes datos)
(let [resultado (.digest md)]
(str-join "" (map #(Integer/toHexString (bit-and % 0xff)) resultado)))))

Obtener la documentacion con gen-html-docs
Hay que asegurarse que el archivo que deseamos tener tenga dentro de su namespace (:require clojure.contrib.gen-html-docs).

Ejemplo (ns ejemplo.ejemplo (:require clojure.contrib.gen-html-docs))

Dentro del REPL

(use 'clojure.contrib.gen-html-docs)
(generate-documentation-to-file “archivo.html” [ejemplo.ejemplo])

Generar un jar a partir de diferentes archivos en diferentes namespaces, incluyendo clojure.

Lo primero es tener el jar de clojure y clojure-contrib

Despues dentro de la carpeta donde estemos trabajando, crear una carpeta classes. Digamos que teníamos la carpeta proyecto, con los namespasces a, b. Ahora tenemos a, b y classes.

Tenemos dentro de la carpeta donde están a, b y classes el jar de clojure y el jar de clojure-contrib.
Nos aseguramos que todas las clases que queramos compilar tengan (:gen-class) en su namespace.

Corremos:

java -cp clojure-contrib.jar:clojure.jar:.:./a:./classes:./b clojure.main

Una vez dentro del REPL, compilamos cada archivo, digamos que dentro de a existe prueba y dentro de b prueba 2

Compilamos con:

(compile 'a.prueba)
(compile b.prueba2)

Y salimos del REPL

Es importante notar que alguno de los archivos debe tener una función (defn -main [] etc), donde los parámetros, son los parámetros que recibrecibirá nuestro jar desde la linea de consola

Ahora se necesita crear un Manifest.txt. Digamos que en prueba esta nuestro main, por lo tanto hacemos

Main-Class:a.prueba y lo guardamos como Manifest.txt

El siguiente paso es desempaquetar el jar de clojure, abriéndolo con cualquier programa que desempaquete .zip, y colocamos la carpeta clojure dentro de classes

Hacemos lo mismo con clojure-contrib, pero en vez de poner la carpeta clojure dentro de classes ponemos la carpeta contrib dentro de clojure.

Ahora en la consola corremos jar cmf Manifest.txt Nombre_de_nuestro_jar.jar a b clojure.

Esto nos generara un jar, el cual esta listo para ser usado en computadoras que tengan el jre instalado.

Imagenes en jar

Para que se pueda desplegar una imagen desde el jar, esta tiene que estar en la carpeta donde la va a llamar y esta a su vez dentro de jar.

Digamos que necesitamos un Imageicon. Para llamarlo usamos el siguiente codigo:

(ImageIcon. (ClassLoader/getSystemResource"Ruta_imagen"))

Esperamos que estos pedacitos de codigo les puedan ser útiles En un rato mas, les mostraremos la aplicación finalizada.

Soren Out


Finalmente... la interfaz

Para esta reunión, Gianfranco y yo estuvimos arreglando detalles con la interface, enfocado al "Look and Feel" de java, las ventanas seleccionadas para este punto fueron los de "Create" y del "Update". Para la fechas, agregamos JComboBox para año, mes y día; lo interesante resulta al momento de seleccionar un mes, ya que los días aparecen en relación a éste.

En el "menu bar", ahora tiene mas opciones activadas, ya que hay ocasiones que los usuarios se guían mas por la barra de herramientas, pretendemos ampliar la gama de posibilidades para que el usuario este cómodo.

Paso algo raro al momento de crear un string en base a los elementos seleccionados del JCombobox, extrañamente no los concatenaba y tuvimos que agregar un string vacío (""), únicamente así funcionó.

Realmente la parte poco amigable del diseño resulta cuando todo debe de quedar perfectamente centrado y alineado. Es lo que mas batalla nos dio, pero finalmente ha quedado listo.

-- Dev-it --


Saturday, May 1, 2010

Concurrencia y hashing


Hola a todos

En la junta del viernes definimos que haríamos exactamente con la concurrencia, para la cual utilizaríamos agentes del lado del servidor, ya que estos tienen un pool de threads y van actualizando a partir de una función. En nuestro caso ya tenemos una función llamada manager, donde esta el punto de choque, ya que ahí es donde se mandan todas las demás funciones a trabajar, lo que nos sirve para llamarlo desde la función que espera las conexiones en el socket.

Tambien encontramos que podría pasar que un cliente actualice y otro cliente en otro lado quiera actualizar, pero en nuestra implementan, el segundo cliente tendría una versión desactualizada. Para lograr solucionar esto, propusimos diversas alternativas: una era que los clientes actualizaran cierto tiempo pero esto no aseguraba que en realidad tuvieran versiones actualizadas al momento de interactuar con el servidor. Otra opción era actualizar siempre que se fuera a hacer una actualización, sin embargo esto generaría bastante overhead en la red, ya que no siempre va a estar desactualizado y hacer eso por vez, puede causar que se deteriore el desempeño del programa. Lo que propusimos y quedo aceptado, fue el usar una función de hash en los campos, para obtener el valor de estos, y así comparar el del cliente y el servidor, si son diferentes no se hace nada y se prosigue con la transferencia de datos y modificación de la base de datos. Si no son diferentes, el cliente actualiza a la ultima versión de los datos y entonces se ejecuta la actualización

Tuvimos que realizar un cambio en la forma en que el cliente manejaba sus datos, ya que por vez que quería realizar una acción, actualizaba sus datos, sin embargo no los tenia guardados en ningún lugar, lo cual no nos permitía usar las funciones de hash, por lo que decidimos usar una referencia, para poder mantener un estado en el cliente, dentro de un valor mutable. Esto ya esta reflejado en la revisión 45 de nuestra aplicación

Después les platicare de como resulta esto, ahora es tiempo de seguir trabajando.

Soren out.

Enviar estructuras por red en clojure



Hola a todos

(Este post se iba a llamar y antes de la concurrencia vino la red, sin embargo le cambiamos el titulo para que sea mas fácil de encontrar)

El vagabundo reportando desde los cuarteles de dev-it, donde se trabaja a toda marcha para tener listo el proyecto en la fecha de entrega. Actualmente atacamos el problema de la concurrencia, donde en la junta a pie que ocurrió el día de ayer se definió que se iba a hacer y mas importante el cómo. Pero antes quiero tomarme unos momentos para mostrarles un poco de como se realizo la parte de red de nuestro proyecto.

Estamos usando una conexión basada en sockets, los cuales van al servidor, y le piden el servicio que quieren, este a su vez interfacea con la base de datos y ejecuta lo que el cliente le pide para enviarle la información Lo importante que queremos compartir que fue una solución muy ingeniosa es el de como se pasa la información Se sabe que en sockets o se pasa en binario, o a un nivel mas grande de abstracción y se pasan strings, integers, etc. Pero en nuestro caso pasamos estructuras de datos hechas en mapas(los que van entre {} por si se confunden entre tantos tipos de datos útiles de clojure). El problema al que nos enfrentábamos era como pasar por la red esta estructura, la primera idea que tuvimos y que empece a implementar, como podrán ver en la revisión 43 y 42 del proyecto http://code.google.com/p/dev-it/source/detail?r=43 era destruir la estructura, pasarla y rearmarla en el lado del cliente. Muy eficiente a nivel de que no generaba overhead innecesario en la red, pero perdíamos tiempo en re ensamblar la estructura. El extranjero(Gianfranco) encontró una solución gracias a la ayuda que tuvo en el SHDH, como detallo en el post pasado, sin embargo dejo a todos en suspenso al no decir la solución, la cual detallare aquí:


(defn serialize
"Converts structures into strings"
[data]
(binding[*print-dup* true]
(print-str data))
)

Simple y sencillo. Segun el API de clojure la bandera/variable * print-dup* nos permite imprimir una variable de forma en que conserve su tipo para que al leerlo con read-string se pueda leer completa la estructura. Así pasamos de un describe de aproximadamente lineas a uno de 5. Para pasar los datos, simplemente se “imprimen” en el stream de salida y se leen con el read-string en el stream de entrada del otro lado. Decidimos dedicar un post especial para esto, ya que es una forma bastante interesante de atacar este problema, que permite programar mucho mas rápido este problema

Mas tarde, concurrencia

Soren out

Sunday, April 18, 2010

Super Happy Dev House Mexico City

Hola a todos los que siguen este blog. 8D

Les habla el extranjero (aka Gianfranco), reportándose después del SHDHMC. Este es mi primer evento de este tipo y decidí aprovecharlo para trabajar un poco en el proyecto.

Decidí que lo que intentaría sería implementar la parte de red del proyecto. Después de que un amigo me hablara de una opción para poder convertir una estructura (diccionario, vector, etc) a una cadena de caracteres me dispuse a probarlo.

Una vez que se podía convertir las estructuras a una simple cadena era mucho mas fácil pasarlas del servidor al cliente y viceversa. Entre los problemas mas grandes que hubieron:

1) Estaba el hecho de que al importar los archivos de servidor para convertirlos poco a poco en las versiones de red había que poner una bandera para que a la hora de importarlos no se ejecutara el servidor.

2) Otro de los problemas fue que por alguna razón no me dejaba hacer el bind hasta que reinicié la computadora. Esto solo ocurrió una vez al principio cuando todavía estaba experimentando con los strings.

Una vez que funcionó el select (a lo que estaba casi bailando de felicidad), hacer funcionar el create, update y delete fue muy fácil. Luego fue cuestión de ponerlo todo en el archivo client.clj y revisar que todo siguiera funcionando. =D

Fue un dia muy productivo y espero ir de nuevo a SHDHMC.


Wednesday, March 24, 2010

Avances del domingo

Saludos a todos =D

Algo tarde pero mejor que nunca. En esta ocasión vengo a contarles los avances y percances que tuvimos el domingo pasado. Nos reunimos Ana y yo(Gianfranco) para poder ver cómo cargar la información en la base de datos.

El problema que teníamos y que nos contó otro equipo, era que si creabas la JTable con los valores entonces ya no se podía modificar. Luego de experimentar y buscar mucho entendimos que para poder hacer funcionar la JTable teníamos que implementar el AbstractTableModel. Para lograrlo tuvimos que usar un proxy. Después el otro detalle que solucionamos fue convertir un mapa a un arreglo de 2 dimensiones que es lo que necesita el AbstractTableModel.

Una vez logrado eso generalizamos todo en una función que recibe los records(de una búsqueda por ejemplo) que se convierten a un modelo de ahí se cargan en la JTable. Al principio suponíamos que era algo muy difícil, pero una vez que funcionaba nos dimos cuenta que era fácil. ¡YAY!

Otro de los detalles que en este momento estamos solucionando y que no funciona tan bien, es el hecho que queremos poner un identificador a los registros para que a la hora de borrarlos se fácil.

Sunday, March 21, 2010

Cambio en el diseño y RandomAccessFile


Hola a todos

Empezare por detallarles un poco nuestro diseño actual. En esta parte lo que teníamos como ya dijimos en otro post era un Cliente ligero que se comunicaba con el servidor el cual sera pesado. En el servidor se hacia la parte de Networking y de Comunicación a la base de datos. El problema es que todas estas funciones estaban en el modulo del servidor, lo cual hace que pierda cohesión

El viernes tuvimos una pequeña junta, donde llegamos a la solución que debíamos separar esto en dos módulos, es decir el servidor el cual es el que se encargara de la parte de networking y probablemente de locking después y la parte del manejador de base de datos. Estos cambios se reflejaran mas tarde, ya que hay que hacer algunas modificaciones para que puedan ser llamados desde el server y no directamente.

En este habíamos tenido un pequeño problema y es que pensábamos que no podíamos editar directamente el archivo donde esta la base de datos. Esto es por que nuestra elección de herramientas estaba mal, ya que intentábamos usar un DataOutputStream, ya que muchas cosas las estamos manejando a nivel Byte. Para lograr realizar nuestro objetivo investigando con diversas personas y en diversos lugares, descubrimos que lo que realmente necesitábamos era un RandomAccessFile, la cual es una clase que tiene métodos como seek(long v) que te permite poner un apuntador en el archivo y que empiece a escribir o leer desde ahí Así que todos los que en los foros decían que con Java(y por lo consiguiente con Clojure) para poder modificar una parte de un archivo, tenias que reescribirlo todo, creo que esta solución es algo mas interesante en nuestro caso. Claro que no aplica si tienes que usar delimitadores para poder leer lineas, ya que las lineas generalmente son de diferente tamaño, pero cuando todo esta bien delimitado, RandomAccessFile es bastante útil.

La liga al API de Java donde se encuentra la descripción de RandomAccessFile: http://java.sun.com/javase/6/docs/api/java/io/RandomAccessFile.html


Aclaraciones y presentación


Hola a todos

Tal vez sea un poco tarde para esto, considerando cuanto tiempo llevamos trabajando en el proyecto, pero mas vale tarde que nunca. Nosotros somos el equipo dev-it, pero eso no dice mucho. ¿Exactamente qué hacemos?. Desarrollamos un proyecto, una aplicación en un escenario ficticio donde sirve para hacer preservaciones en un hotel, la aplicación se llama URLyBird. Es ficticio ya que es un proyecto académico, desarrollado en el ITESM-CEM para la clase de proyecto de desarrollo de software.

Y que tiene de especial que necesite un blog el proyecto. Pues muchas cosas, la primera es el lenguaje en el cual estamos desarrollando, siendo este Clojure, un lenguaje de programación funcional que trabaja sobre la maquina virtual de Java. Es un lenguaje muy interesante a consideración mía en desarrollo, pero que tiene mucho potencial. Tenemos un blog ya que puede que encontremos alguna solución ingeniosa y nos gustaría que el conocimiento que obtengamos se pueda compartir. También es interesante el observar como se desarrolla un proyecto, que aunque esta limitado un poco por ser de carácter académico, tiene los elementos necesarios para ser completamente un proyecto de desarrollo de software y personalmente me parece interesante ver los pasos que se realizan, así como los pensamientos del equipo que esta desarrollando.

De este blog pueden esperar pedazos de código que consideremos interesantes en clojure, anecdotas de como vamos desarrollando el proyecto. Es importante resaltar que el código esta disponible a todo el que quiera revisarlo, ya que le puede ser útil en algún momento. Si desean hacer esto, lo único que tienen que hacer es visitar nuestra pagina en Google Code, ademas de respetar la licencia GPL con la que estamos liberando el proyecto.

La pagina de Google code: http://code.google.com/p/dev-it/

Se pueden preguntar quienes somos y por que dev-it, por mi parte me presento, soy Jorge, aunque la mayoría me dice Soren. Aunque compartimos todo el código y intentamos todos revisar el trabajo de los demás, para seguir con la practica de desarrollo ágil de que no solo una persona sea la que tenga el control sobre cierto código, estoy encargado principalmente de la parte del servidor, la conexion con la base de datos y el networking que es mi área favorita, ademas de hacer una parte del diseño principal, el cual comentare en otro post. Elegí trabajar con esas áreas, ya que personalmente el desarrollo de interfaces gráficas se me hace complicado en demasía, ademas de que no es un área que me atraiga mucho. En el caso de dev-it, tiene un significado mas serio, derivado de develop it, o sea desarrollarlo y el mas comico que seria las siglas de: la Dama, el Extranjero y el Vagabundo, siendo yo el Vagabundo(lo dejo a la imaginación del lector el porque).

En cuanto al blog, la razón por la que esta en español es debido a que creemos que mucha información se genera para las personas que hablan el idioma ingles y muchas personas que solamente hablan español se pueden perder de información que es interesante difundir y aprender, ademas de que les podría interesar o ser útil. El código esta en ingles por especificaciones, pero es totalmente entendible con un poco de conocimiento de Clojure. Esperamos que encuentren información útil.

Soren out.

Monday, March 15, 2010

¡Una piedrita en el desarrollo!

Para el avance del proyecto se ha realizado un mapa general de cómo quedaría nuestra aplicación, por el momento se está definiendo la parte del cliente y del servidor, el servidor será pesado por lo que se encargará de la parte fuerte del sistema, permitiendo al usuario ser ligero y se facilite su distribución. Del lado del servidor se implementarán métodos de crear, modificar y eliminar; también se está haciendo una búsqueda para los records.

Pero, ¡ups! hemos encontrado una piedra mas en el camino, al parecer no se puede modificar un archivo en la base de datos, por lo que tendremos que reescribirla cada vez que modifiquemos la información, esto nos añade tiempo extra a la programación y un poco más de esfuerzo para el método modificar y borrar.

Estamos en la búsqueda de una solución óptima o al menos una más sencilla.

Equipo Dev-it


Tuesday, March 2, 2010

Licencia e implicaciones filosóficas

La razón por la cual elegimos una licencia GNU, es debido a que está en nuestro interés que el código que realicemos siempre esté disponible a quien lo quiera consultar. Aun cuando existiera alguna aplicación que implementara parte de lo que estamos realizando, no nos agradaría que ésto se convirtiera en código propietario como se puede hacer con una licencia BSD.

Creemos que en especial en lenguajes como clojure, que se están desarrollando y obteniendo seguidores (ya que aun probablemente no sea un lenguaje bien establecido), es importante tener programas que sirvan de ejemplo. Que se pueda mostrar las capacidades del lenguaje y que mejor que con un programa que incluya su código así como su desarrollo. Esto es para que los nuevos programadores en este lenguaje se puedan beneficiar de ejemplos ya hechos y probados como pretendemos que sea nuestro proyecto. Además dar la posibilidad de correrlo cuando y donde sea si le es útil a alguien.

Es por eso que preferimos la licencia GNU, aun en su característica vírica, ya que esto asegura que la permanencia al acceso de la información. Otra razón un poco menos importante es que al tener una licencia GNU damos nuestro apoyo a la filosofía del software libre, que es la filosofía que implementan GNU y la Free Software Fundation (http://www.gnu.org/philosophy/philosophy.html). Esto da las libertades de correr el software, estudiarlo a fondo (obteniendo el código fuente), además de que se pueda distribuir libremente el programa, tanto el original como modificaciones hechas por otros.

Equipo Dev-It

Friday, February 19, 2010

We go live!!!

El blog ha sido creado, ahora solo falta usarlo.