Páginas

Mostrando entradas con la etiqueta diseño. Mostrar todas las entradas
Mostrando entradas con la etiqueta diseño. Mostrar todas las entradas

domingo, 10 de febrero de 2013

Technical issues

Trying to add support for native DataChannels on Chromium v26 I have had some problems in the last days and ShareIt! was not working correctly, so after going back and fixing it I decided to do a Draconian decission: no more references to external libraries, and use instead a local copy. I know this would break one of the points of the Universitary Free Software Championship (re-use existent code), but the fact is that the external libs are all in an unique place (the /lib folder) so it can be easily upgraded, and also this has several advantages, like being sure to have a working version all the time since it's being used an expecific version of the libraries, being easier to deploy on any other place, and since all the code is auto-contained now I don't require to add some special permissions on the FirefoxOS manifest file, so users don't need to worry about them. This also has lead me to isolate the usage of the EventTarget.js library only to WebP2P, so now the UI uses exclusively jQuery events, making it more straigforward to develop and to use less memory usage. Now it only keeps to finish a script I'm working on to update all the external libraries at a time, so the fact of being the libraries inside the source code tree or as external libs would be indiferent.

domingo, 15 de abril de 2012

A veces veo eventos...

A pesar de los fallos relativos al git-svn y tener que trabajar unicamente con el repositorio de GitHub... no he podido resistirme ni tener las manos quietas y he picado mas codigo :-P ¿Y en que he estado liado estos ultimos dias en lugar de estudiar los examenes? Pues ni mas ni menos que con el task manager :-D

El primer paso fue hacer que se imprieran los ticks fuera del driver del temporizador, ya que ahi no hacian nada util. Ahora se estan enviando por el motor de eventos en distintos periodos de tiempo: milisegundos (para lo que he tenido que aumentar la precision del timer, suerte que solo es una variable :-) ), centesimas, decimas y segundos. Asi aunque quizas lo sobrecargue un poco simplemente tengo que acoplarme a la frecuencia adecuada, en este caso centesimas (lo estandar), aunque podria hacer que el cambio de contexto fuese incluso mas rapido si quisiera.

Despues, empece con la definicion basica de lo que seria un proceso internamente para poder delegarles eventos (registrarse directamente en el gestor de eventos del sistema queda un poco feo y complicado, y mas si de todas formas habra que buscar los callbacks dentro de los procesos). Al principio pense en reutilizar la libreria de threads que he hecho para la asignatura de Fundamentos de Sistemas Distribuidos... hasta que me di cuenta que setjmp() y longjmp() son dependientes de cada sistema o no tengo manera posible de implementarlos por el momento :-/ asi que descarte esa idea y me centre por el momento en como hacer para delegar los eventos a sub-diccionarios, y aqui me encontre con otro problema: ¡un diccionario no es una funcion! Asi que como solucion rapida estoy usando un segundo diccionario a la espera de desarrollar mas como seria el tipo Event.

Por ultimo y no menos importante, en un acto de inspiracion divina (en concreto de Morfeo ;-) ) se me ocurrio que aunque actualmente este todo funcionando en el mismo espacio de usuario, podria trabajar con los eventos de los procesos de forma independiente a traves de funciones estaticas... incluso aunque esten en un mismo archivo, siempre que sea este el que se importe. Esto redunda en codigo repetido, si, pero quizas se pueda arreglar pasando las estructuras por parametros. Lo que si que es interesante es el hecho de que el preprocesador se ejecuta de forma lineal, con lo que abusando de el un poco, he conseguido renombrar las funciones relaccionadas con los eventos en el lado de las aplicaciones igual que en el lado del kernel, con lo que solo hace falta cambiar el include para poder pasar el codigo de un lado a otro :-D Esto ultimo es mas util de lo que parece, ya que aparte de hacer el codigo mas limpio, quizas pueda aplicarlo tambien a las llamadas al sistema, y por tanto, que se puedan mover los drivers del espacio de usuario al espacio de kernel de forma totalmente transparente :-D

Como veis, esta todo bastante "en el aire" a la espera de poder dividir el codigo cuando termine el concurso y poder analizar y hacer pruebas independientes de cada parte, pero lo cierto es que al final me esta quedando un API bastante curiosa y flexible y, sobretodo, puramente orientada a eventos (que es lo que queria... :-D )

Update 23:39:

He intentado demostrar mi teoria respecto a usar la misma firma en los syscalls y ha funcionado, pero no como esperaba... sino mejor: puesto que ahora tengo el codigo mas aislado entre sus partes (y sobretodo a nivel de makefile), a la hora de compilarlo cada parte se compila con sus correspondientes syscall.h y syscall.c sin interferirse, luego no hacen falta hacer trucos de ningun tipo: las firmas de los syscalls son iguales que las de las funciones que representan dentro del kernel de forma nativa :-D Chulo, ¿eh? :-)

miércoles, 6 de abril de 2011

Fahrenheit 1832

Semanita de aupa llevo, y semanita de aupa me espera. Semanita llevo, porque he "intentado" (no existe una palabra mejor...) mezclar las dos ramas de PirannaFS (FUSE y PyFilesystem) y el repositorio ha acabado como era previsible: apocalipsis post-nuclear y terminar metiendo los archivos a mano de nuevo (con esto ya si que me paso definitivamente a GIT), al hacerlo me he encontrado bugs al prepararlo todo para la integracion (y aqui me veis, un dia antes de terminado el plazo haciendo todavia la memoria) y encima al empezar a hacer las pruebas directamente sobre el disco he descubierto que SQLite es mucho mas lento de lo que pensaba por pura paranoia y voy a tener que configurarlo y optimizarlo muchisimo antes de tener algo usable. Semanita me espera, porque el jueves tengo examen de Fundamentos de los Computadores (y no he estudiado...), el viernes tengo la presentacion del proyecto (y todavia no la he preparado...) y encima me he comprometido a hacer la version Java-Android de UnHosted en lugar de las aburridas, inutiles y nada practicas practicas de POO para el examen de dentro de 3 semanas. Me encanta vivir al limite... :-D

Pero bueno, no todo son buenas noticias, tambien he conseguido sacar tiempo para hacer la memoria del proyecto, y la teneis en la pagina de documentacion. Tambien estoy aprovechando a desarrollar toda la documentacion del proyecto para tenerlo centralizado en algun sitio y que sea usable por otras personas, y una de las cosas mas importantes es la estructura de clases, la cual ademas me ha permitido ver algunos detallitos y hacer algunas optimizaciones (siempre se me ha dado bien la memoria espacial... :-D ).


Vamos a explicar las partes. En primer lugar vemos un conjunto de clases fuera del paquete de PirannaFS a la derecha de este. Son el conjunto de clases encargadas del sistema de plugins, junto con los plugins encargados de los checksums, el log y los links simbolicos (obviamente, todos ellos en la carpeta de plugins... :-D ). Ya dentro de PirannaFS vemos un par de paquetes para las interfaces de FUSE y de PyFilesystem. Obviamente las clases de FUSE estan vacias porque tengo que adaptarlas a la nueva estructura, asi que nos centraremos en la de PyFilesystem. Ahi vemos tres clases: Filesystem, Dir y File, que heredan de sus correspondientes dentro del core, las cuales tienen sus referencias a la base de datos y al dispositivo. Ahora mismo tienen casi toda su funcionalidad dentro a la espera de que se vayan "destilando" al core a medida que reintegre la interfaz de FUSE. Como se ve la estructura por capas es realmente sencilla puesto que he desarrollado el codigo alrededor de las funciones correspondientes a las interfaces (de ahi que casi todo el codigo este ahora mismo dentro de los paquetes FUSE y PyFilesystem) y porque todo el trabajo duro se lo esta llevando la base de datos (de ahi que sea tan lenta...). Luego cuando convierta Dir y File en plugins propios ya veremos que pasa con todo esto... :-P

Y bueno, aparte de eso, tambien estoy pensando si en lugar de acceder a la base de datos directamente no hacerme un controlador independiente... Eso me permitiria varias ventajas, como el poder serializarlo todo para que tenga soporte multihilo (se le lanzan peticiones y ya se encargara de resolverlas cuando pueda), cachear las peticiones para que funcione mas rapido el sistema (si solo accede el al sistema no deberia haber problema de que esten desactualizados) o incluso simplificar el proceso de sacar el codigo SQL a archivos externos y cargarlos al principio incluso por parte de los plugins... Pura poesia... :-D

PD: Fahrenheit 1832 es la temperatura a la que arde el silicio en contacto con el aire, convirtiendose en SiO2. Nunca maldigo mi suerteeeeee, porque yo friki naciiiii... :-P

jueves, 4 de noviembre de 2010

Horror, espanto, pavor (2ª parte... y media)

Si antes me quejo de lo malo que es Python-FUSE para depurarlo y para hacer unidades de test, antes me encuentro con otro con el mismo problema :-P

Bindings de FUSE para python hay varios (eso ya lo sabia) y escogí Python-FUSE aparte de por ser el mas famoso y el "oficial" (o al menos es del unico que hay documentación en la pagina de FUSE) porque ya habia paquetes en Ubuntu. Lo que yo no sabia es que otra de las alternativas (fusePy) tenia paquetes dentro de la CheeseShop (si, asi se llamaba hasta hace poco el repositorio de paquetes oficial de Python antes de "profesionalizarse"), y por lo que parece esta alternativa no solo es mas "pythonica" que Python-FUSE sino que ademas es mas completa respecto a funcionalidad de bajo nivel, y para muestra un boton:


>>> from fs.memoryfs import MemoryFS
>>> from fs.expose import fuse
>>> fs = MemoryFS()
>>> mp = fuse.mount(fs,"/mnt/my-memory-fs")
>>> mp.path
'/mnt/my-memory-fs'
>>> mp.unmount()


Si con esto no es mas facil el hacer las unidades de test sin necesidad de hackeos que baje FSM y lo vea. El problema viene entonces de tener que rehacer PirannaFS usando como base estos nuevos bindings o si hacer PirannaFS compatible con los dos, asi que quizas lo mejor sea estudiar previamente si realmente sera rentable o no, y leyendose el codigo no creo que baste. No se, otra alternativa podria ser el hacerme algun otro sistema de archivos (¿otro mas?), pero FullFAT no tiene bindings en Python (aparte de que queria usar la libreria para "entrenarme" para el paso a C++ de PirannaFS) y no he encontrado nada de bindings de Ext3 en Python, aunque sin lugar a dudas estaria interesante el hacerse una implementacion completa de Ext3 en Python (para chulo, yo :-P ). ¿Vosotros que opinais? ¿Reciclaje? ¿Reimplementación? ¿Mirar para otro lado y hacer como que no he visto esto? :-P

Al menos, de regalo me he encuentrado que CUSE, el hermano pequeño y marginado de FUSE para desarrollar drivers de dispositivo en espacio de usuario (el tio que lo desarrolló se dio cuenta que solo hacia falta añadir dos IOCTLs a FUSE para tener soporte para poder escribir drivers genericos fuera del kernel...) y del cual a casi nadie parece importarle (o al menos no he visto ningun proyecto importante o ni siquiera una pagina con documentacion)... ¡¡¡me encuentro con que han desarrollado unos bindings para Python!!! :-D

Quizas empezase PirannaFS porque CaOS (mi propio sistema operativo que llevo diseñando desde que tenia 10 años) se me hacia muy grande, pero parece que todo el universo se esta conspirando en que lo saque adelante... :-)

domingo, 17 de octubre de 2010

[0.2.3] Checksums de Octubre

Casi 20 dias despues... nueva release :-D

Este mes ha sido de aúpa, entre el trabajo y la demostración de este miércoles (que FSM nos coja confesaos...), los estudios (de los cuales todavía no tengo todos los apuntes), los compromisos sociales (aunque algunos han merecido la pena... aunque podrian haberlo merecido mas :-P ) y que los [auto-censurado] checksums se me habian atragantado no he parado quieto, pero bueno, tal y como dijo Mao "una revolución a la vez" al final esta saliendo todo adelante :-D

En primer lugar estaba el tema de los plugins. Los checksums no aportaban simplemente funcionalidad no existente como pasaba con los symlinks sino que trabajaban directamente con los datos, por lo que ya no se podia usar un simple mapeo como antes sino que habia que empezar a desarrollar el sistema de plugins, y a ser posible de una forma un poco mas consistente que como lo habia hecho antes. Por suerte fue facil y ademas el codigo ha quedado bastante limpio, pero tengo la sospecha de que en el futuro voy a tener que hacerle profundos cambios para darle mas potencia y versatilidad (conflictos entre modulos es lo primero que se me viene a la cabeza, luego vereis porque).

Pero el principal problema que tenia con los checksums (y que no identifique hasta hace poco) no estaba relaccionado directamente con ellos, sino que mas bien era un pequeño fallo de diseño (mas bien de falta de planificación) que tuve cuando desarrolle el codigo de escritura y modificación de los archivos (el cual en su momento ya me dio bastante guerra hasta el punto de tener que modificar el diseño de la base de datos tres veces...). Este fallo consistia por un lado que accedia desde distintos puntos del codigo directamente a las funciones DB.Split_Chunks y a LL.Write, con lo que a la hora de generar los eventos para los plugins tendria que generarlos desde multitud de sitios distintos. Sin embargo su funcionalidad era muy parecida y de hecho el codigo era casi el mismo en muchos sitios (como ya indique en mi anterior post entre DB.truncate y DB.Split_Chunks), asi que finalmente he conseguido encarrilar a todo el ganado a través de una nueva función (File.__Split_Chunks) que se encarga efectivamente de llamar a DB.Split_Chunks y de generar el evento correspondiente en caso de que haya producido alguna división.

Al menos todo este follón me ha servido para varias cosas: en primer lugar, una revisión a fondo del código de los archivos, de la base de datos y del acceso a bajo nivel (este al fin es una clase y es instanciada en FileSystem, con lo que ya no abrirá y cerrara el dispositivo en cada llamada. La ventaja es que el acceso es mucho mas rápido, el inconveniente que usara los buffers de archivo del sistema y no escribirá los datos directamente a disco y todavía no estoy usando las transacciones, que es justo una de las razones por las que decidí usar un motor de bases de datos, para aprovechar las que ya tiene... :-/ ). Esta revisión me ha permitido aplicarle muchas mejoras menores y reutilizar mucho código duplicado, con lo que ahora el tamaño y las posibilidades de error son menores, pero sobretodo he quitado "inteligencia" a la base de datos (ahora solo ejecuta sentencias SQL, apenas toma decisiones por si misma aunque lo cierto es que se podría "estupidizar" aun mas) y he eliminado la notificación de eventos desde la base de datos y el acceso a bajo nivel, con lo que por un lado permite mayor control de quien envía realmente los eventos (todo se esta perfilando a que la comunicación entre los plugins va a ser realmente sencilla... :-) ) y también permite mayor portabilidad en el futuro a otros motores de bases de datos o sistemas de almacenamiento o incluso a sacar el código SQL a archivos externos y que los parsee en el arranque en lugar de estar directamente dentro del código Python (esta idea la tengo desde hace tiempo, pero aunque permitiría un mejor mantenimiento al poder tenerlo aislado y que sea mas fácil procesarlo con un editor de texto con coloreado de sintaxis -me encantan :-D - todavía no me he planteado en serio el realizarlo porque consumiría mas memoria y seria un poco mas lento... :-/ )

Ademas todos estos cambios me han hecho replantearme en serio la necesidad de hacer modulos de prueba, por lo que voy a empezar a usar PyUnit, que es el estandar en Python. Nunca he desarrollado ninguno y ademas siempre he sido reaccio a hacerlos (si funciona, ¿para que comprobarlo?) pero un proyecto tan complejo como este lo necesita. Por suerte hace tiempo cuando estaba buscando los codigos de error de los sistemas de archivos tratando de averiguar porque fallaba me encontre con esta pagina que contiene la definición de todas las funciones UNIX con sus parametros, errores y limitaciones, con lo que me vendra de perlas para desarrollar los modulos de test (espero que no me pidan comprar una licencia de POSIX o que Linux Tordvalds me preste la suya... :-D ). Tambien aprovechare a documentar todo el codigo con vistas a liberar publicamente la version 0.3 a ver si se apunta alguien a echarme una mano, y tambien aprovechare a cambiar la filosofia de la API, ya que hasta hace poco (bendito trabajo que tambien lo estoy haciendo en Python y me permite aprender de forma intensiva... :-D ) no entendia correctamente uno de los aspectos mas extraños del lenguaje: en Python no hay metodos o atributos privados, todo es publico. Sin embargo por convenio los atributos y metodos que empiezan con un guión bajo (_) no se muestran en el completado de sintaxis, aunque se sigue podiendo acceder normalmente a ellos. Aparte tambien estan los que empiezan por dos guiones bajos (__) que aqui si el lenguaje los considera como atributos especiales y su firma es distinta, haciendo por tanto que sea mucho mas dificil acceder a ellos. Hasta ahora solo usaba este ultimo metodo para emular los atributos privados, pero realmente era un engorro cuando me encontraba con que queria acceder a algo que habia ocultado demasiado hasta que descubri en que se basaba esta diferencia: la filosofia en Python es la confianza en el programador, por lo tanto no tiene sentido pensar en atributos publicos, protegidos y privados, sino en mostrar (normal), no mostrar (_) y ocultar (__), teniendo en cuenta por ambas partes que si quieres acceder a algun sitio siempre vas a poder pero que necesitas tener buenas razones para ello (por ejemplo, en los debuggers). Despues de tanto tiempo con C++ cuesta acostumbrarse, pero la posibilidad de ver el codigo de los demas para ver que es lo que esta haciendo realmente es de gran ayuda... :-D

Y bueno, ese es el toston de hoy. Espero que cuando este aprendiendo a usar las unidades de test y documentando el codigo no me encuentre con demasiados problemas como hasta ahora, porque entonces esto va a parecer la biblia... :-P Por el momento para mi desgracia acabo de descubrir que ZFS si tiene bloques de tamaño variable (lo que yo creia que era una feature exclusivamente mia... ¬¬) pero por otro lado tambien he descubierto que su algoritmo de compresion tiene una implementación en Python, asi que no hay mal que por bien no venga... :-D
Published with Blogger-droid v1.6.2

domingo, 3 de octubre de 2010

Proyecto Brainstorm

Como habréis podido ver hace días que no escribo por aquí y sin embargo en el svn ha habido muchos cambios... Esto es debido por un lado a que las modificaciones en el core para que acepte el lanzamiento de eventos para los plugins esta siendo mas complicado de lo que parecía debido a que hay que pensar en como aislar correctamente cada una de las partes (hasta ahora no tenia problemas, pero el plugin de checksums funciona a muy bajo nivel y además recibe eventos de distintas partes del código). Sin embargo estos replanteamientos están permitiendo una mayor independencia entre cada una de las partes y además me esta permitiendo el optimizar y documentar código bastante antiguo (en concreto estoy rompiéndome la cabeza para que DB.truncate utilice por debajo a DB.Split_Chunks), así que estoy matando tres pájaros de un tiro :-)

Pero por otro lado también he estado aprovechando el tiempo, y el sistema de plugins ya esta bastante maduro. El sistema me ha quedado bastante escueto y portable, por lo que se podría utilizar en otros sistemas que precisen de un sistema de plugins, pero aunque ya haya otros sistemas de plugins para python (y algunos ya se me han adelantado en la idea de convertirlos en sistema "oficial") lo cierto es que no he visto ninguno que tenga algún mecanismo de control de dependencias entre plugins, y aunque creía que iba a ser mas complicado lo cierto es que al final ha sido casi obvio: al cargar el modulo obtenemos las clases de los plugins y vemos cuales son sus dependencias. Si no están todas disponibles dejamos el plugin pendiente, y si lo están entonces lo cargamos y comprobamos entre los pendientes si para alguno de ellos ha cambiado la situación. Simple, fácil y para toda la familia :-D

Es por esto por lo que todavía no le estoy dando mucha popularidad al sistema ya que quiero tenerlo bien fino antes de abrirlo al publico (sobretodo por el tema de los plugins que se meten muy adentro del funcionamiento del sistema), pero probablemente para la versión 0.3 ya haga un llamamiento publico buscando ideas y colaboradores (y si, prometo que intentare poner al día y en la web cuales son los checkpoints para cada versión...). Sin embargo precisamente por esto he estado actualizando (y limpiando) el diagrama de la estructura de tablas mas acorde a como se esta perfilando el sistema ahora que empiezan a funcionar los plugins (mi idea era implementarlo después de la versión 1.0, pero con motivo del concurso y de la "participación de la comunidad" he tenido que cambiar las fechas para hacerlo mas accesible) y este es el resultado:

(Los colorines son para indicar la dificultad de implementar cada uno de los modulos según cuanto haya que modificar el código: blanco=implementado, verde=directo o casi directo, amarillo=alguna modificación, naranja=reimplementación en parte, rojo=reimplementación de gran parte y turquesa=implementado pero necesita mejoras. Obviamente, con los checksums me equivoque...)

Como podéis ver, arriba a la izquierda tenemos el core, ya implementado. He agrupado lo que correspondería al plugin de directorios y al de archivos porque aunque por el momento no tenga pensado implementarlos como modulos externos, lo cierto es que cada vez me esta tentando mas la idea (¡Mama mama, sin directorios! ¡Mama mama, sin archivos! ¡Mama mama, sin datos! X-D). Luego en el siguiente nivel tenemos los modulos de implementación que como dije anteriormente son dependientes de los elementos del core, y por ultimo tenemos los de valor añadido, en los cuales he puesto el ACL y el log (antes los tenia como de implementación) debido a que no son dependientes directos del core. También tengo aquí a un nuevo vecino en el barrio, xattrs (atributos extendidos), que aunque si es dependiente del core lo cierto es que no depende de sus claves únicas. Además, realmente voy a implementar los atributos extendidos para completar la funcionalidad del sistema de archivos y porque va a ser igual de sencillo que los symlinks (al igual que estos, se podría hacer con un mapeo directo de funciones) ya que a titulo personal, me parece una solución mucho mejor el usar algún tipo de estructura como las tablas id3 y exif, no un simple clave-valor que no da ninguna idea de cuales datos faltan por rellenar (lo admito, estoy obsesionado con los tags de los mp3s en el iTunes hasta el punto de que no solo relleno todos los campos de autor/album/disco/pista/titulo para tenerlos bien organizados sino que le meto dentro a los archivos todas las imágenes del album e incluso la letra de las canciones... :-P). Sin embargo también tengo que reconocer que aunque no son muy usados (al menos son unos completos desconocidos para el usuario medio, y para mi hasta hace poco), realmente pueden ser muy potentes y en un sistema de archivos "tradicional" puede ser usado para implementar un ACL y aumentar el nivel de seguridad, por ejemplo. En cualquier caso, para todo lo que se pueden usar los atributos extendidos un sistema dedicado puede cumplir su tarea mucho mejor, pero las estructuras en los sistemas de archivos tradicionales son demasiado fijas como para añadir este tipo de funcionalidades. Por eso la flexibilidad que ofrecen las bases de datos en estos casos es justo una de las razones que me impulsaron a usar una como base para diseñar el sistema de archivos.

Pero este pequeño by-pass con replanteamiento de puntos de vista incluido también me esta permitiendo el tener tiempo para pensar sobre nuevos modulos, plugins y funciones que añadir al sistema, y parte del merito se lo tengo que dar a mi buena amiga Jennifer, una completa n00b para estas cosas (bastante que la conseguí sacar del lado oscuro y que empezara a usar Linux... :-P) pero que sin embargo su punto de vista como usuario raso me ha sido bastante útil (¡gracias! :-D ).

Una de las ideas que me dio fue el implementar algún sistema de búsqueda avanzada en situaciones limite, del estilo "he buscado la foto del garito aquel en la playa en que estuve desfasando con mis amigas en la que salia guapísima, pero no me acuerdo si es de este año o del anterior y no se si las he borrado o que porque no las encuentro" (nota: aunque no haya dicho nada, casi desde que empecé el proyecto en el diagrama arriba a la derecha hay un modulito muy majo llamado "unlinks"... Si, he pensado en todo, también en otro llamado "purge" que no sale ;-) ). "Además, no quiero que salgan las fotos del tío con el que me enrolle esa noche no sea que entre mi novia en un momento inoportuno cuando este buscando la foto" (a esto ultimo lo llamo yo "ganas de fastidiarme", solo que no con estas palabras...). Al leer esto algunos pensaran que eso es imposible, y otros pensaran que quizás SpotLight o Beagle ya lo hacen (realmente esta idea suya les correspondería mas a unas aplicaciones de alto nivel como ellos que a un sistema de archivos, pero un poco de ayuda por debajo les facilitaría mucho la tarea al igual de lo que podría ocurrir si combinásemos ZFS con TimeMachine... :-) ). Lo cierto es que SpotLight es buenísimo (Beagle nunca lo he usado porque siempre lo desinstalaba ya que mis maquinas con Linux nunca han sido lo suficientemente potentes como para encima tener un proceso accediendo al disco todo el rato...) pero nunca he visto que llegara a un nivel de precisión quirúrgica tan avanzado (quizás lanzandolo desde linea de comandos y procesando una consulta muy elaborada, pero si fuera así de fácil habría un montón de artículos escritos en internet al respecto y lo cierto es que no he oído nada). Yo tengo que ser sincero: es muy complicado, pero no imposible. Aquí el mayor problema depende de la adquisición de los metadatos (día-noche, fechas contextualizadas, reconocimiento de caras...) pero si se tienen y están bien organizados, el problema se reduciría a una simple búsqueda en la base de datos. No diré que lo vaya a implementar... pero si que lo tendré en cuenta para orientar posibles mejoras futuras.

Otras ideas que surgieron entre los dos fueron la eliminación segura de archivos (que ya lo tenia pensado antes pero me gusto ver que no soy el único preocupado :-) ) o la compactación de los archivos (quizás para mas adelante, ya hay suficiente lío con la escritura de los chunks como para encima meter esto). Sin embargo al ver todo lo que esta creciendo el sistema me esta entrando una pequeña duda: ¿y si SQLite no es lo suficientemente potente como para moverlo todo? SQLite es un motor de bases de datos muy optimizado, pero tiene el inconveniente de que cuando se accede a el bloque la base de datos entera, y con tanta funcionalidad añadida a falta de pruebas de rendimiento un sistema que ponga a funcionar muchos modulos podría tener problemas... Una solución bastante practica podría ser el que los modulos en lugar de crear sus tablas en la base de datos principal las creen en bases de datos secundarias, con lo que aparte de aumentar la modularización permitirá el acceder en paralelo a las distintas tablas (sobretodo con equipos multicore como los que se venden hoy día) y además se evitaría el meter "mierda" en la base de datos principal y la desinstalación de modulos seria mas sencilla, sin embargo la adaptación a un sistema autocontenido se complicaría sobremanera. Bien es cierto que todavía queda mucho para entonces, pero siempre es bueno planear tus actos con dos o tres pasos de antelación... :-D Por el momento lo dejo aquí anotado como recordatorio para el futuro ;-)

domingo, 19 de septiembre de 2010

Una pequeña idea...

Como puse en mi anterior entrada, PirannaFS empece a hacerlo entre otras razones porque queria experimentar con FUSE. Si, cuando quiero probar una nueva tecnologia no me leo un manual y hago el famoso Hola Mundo, me saco mi propio libro :-P y es por eso por lo que debido a todos los problemas que estoy teniendo para desarrollar PirannaFS y lo escueta, ofuscada y desfasada que es la documentacion que se puede encontrar en la pagina de FUSE por lo que estoy escribiendo mi propio tutorial de desarrollo de sistemas de archivos usando python y FUSE.

Mi idea en un principio era utilizar PirannaFS directamente como codigo de ejemplo del tutorial y es por eso por lo que he intentado que el codigo fuese lo mas claro y limpio posible, pero lo cierto es que el proyecto se ha convertido en algo realmente grande y complejo, aparte de por las optimizaciones que le he hecho para la escritura de los archivos como sobretodo por el usar una base de datos (y eso ya si que no es normal) asi que decidi empezar de cero otro sistema de archivos, este ya con mas complejo de Hola Mundo ;-)

PyRamFs es un sistema de archivos que usa objetos en memoria para guardar los datos: los archivos son strings y los directorios son diccionarios. Mas simple, imposible :-D Lo bueno del caso es que lo he estado escribiendo en orden de importancia a la hora de realizar un sistema de archivos, y es por eso por lo que empece con los archivos antes que con los directorios con lo que hasta ahora es un sistema de archivos de un unico nivel como el de CP/M y similares. Realmente me esta quedando bastante simple y minimalista, en parte por la simpleza del diseño y en parte porque ya no me pilla de nuevas, y es por eso que pense: si este sistema es tan simple porque (por ahora) no tiene subdirectorios... ¿se podran sacar tambien los subdirectorios del nucleo de PirannaFS para que sea aun mas simple e implementarlos como un modulo externo al igual que ha pasado con los links simbolicos?

Asi que nada, me fui al diagrama en el que tengo organizadas las tablas de la base de datos a echar un vistazo :-D

(Lo que esta en el recuadro azul son las tablas del core, las que estan alrededor son modulos "de ampliacion" ya que sus primary keys coinciden con las de las tablas del core y amplian su funcionalidad, y las dos tablas de abajo son de modulos auxiliares en los que su primary key no es dependiente de ningun elemento almacenado en el core)

Como podeis ver, dentro del core estan bastante separadas las tablas relativas a los directorios de las relativas puramente a los archivos, por lo que si no fuera por el nombre y por la fecha de creacion de la tabla links no seria complicado el sacar los directorios fuera y que el core funcione con un unico directorio aunque sin lugar a dudas donde se complicaria mas el tema seria con las consultas de acceso a los datos, que tendria que volver a cambiarlas (¿otra vez a cambiar la estructura de la base de datos? no, por favor...).

Sin embargo, la idea me gusta. No se si sera mejor desarrollarlo tambien como otro modulo externo y que el usuario elija uno u otro, o si ver la posibilidad de sacar los campos de nombre y creacion de la tabla links a una tabla aparte que sea la que se mantuviese dentro de la estructura minima para poder acceder a los archivos, pero en cualquier caso viendo el diagrama me he dado cuenta que aunque no tuviera nombres de archivo tampoco seria mucho problema, ya que si llego a implementar los modulos de metadatos (como el ejemplo que tengo puesto de mp3) se podria acceder directamente a traves de las bibliotecas de musica, fotos o lo que sea puramente a traves de los metadatos y entonces eso si que seria algo revolucionario: un sistema de archivos sin archivos :-P

Ahora bien, en caso de que llegara a implementarlo, ¿como lo hariais vosotros? ¿que el usuario tenga que decidir entre los dos modulos (un solo nivel o sistema jerarquico), o dividir la tabla links y que el mono-nivel este por defecto? ¿la tabla directories tendria algun sentido entonces (esta puesta para forzar luego en las consultas que links.parent_dir sea efectivamente un directorio valido)? ¿lo tiene ahora?

Yo, de momento, ya he alineado dir_entries con files y chunks en el diagrama por si sigo adelante con la idea... ;-)