[turpial-dev] Optimizaciones de la API

10 views
Skip to first unread message

Wil Alvarez

unread,
May 14, 2010, 4:52:40 PM5/14/10
to turpi...@googlegroups.com
Actualmente Turpial está presentando fallas con mucha frecuencia. La más común y grave es que deja de actualizar absolutamente todo. La aplicación se pone en un estado como "suspendido", donde la vista responde pero no actualiza nada (timeline, menciones, directos, etc) y al tratar de realizar otra función relativa a la API, por ejemplo tuitear, simplemente se queda colgado intentando para siempre.

Presumo, por lo que he podido observar durante el error y por los logs que he leído, que el problema está directamente relacionado con la API. Está pasando "algo" que está congelando el hilo y por ésta razón no se ejecuta ninguna otra tarea; todas quedan en la cola.

La API necesita refactorización desde hace algún tiempo y creo que la hora ha llegado, por eso abro este hilo. A continuación trataré de comentar e ilustrar un poco el modelo actual y el modelo que tengo en mente para la optimización, de esa forma podemos discutir y lograr la mejor solución.

Nota: no soy muy experto con esto de los diagramas de flujo así que pido disculpas de antemano por cualquier aberración xD

En el modelo actual [1] se observa el flujo desde que comienza la petición en la vista hasta que llega a la API. En ese punto, mediante funciones que están fuera del hilo (o fuera de la función run de la clase) se agrega la solicitud a la cola. Luego dentro del hilo se gestiona la cola, si no hay solicitudes pendientes se espera 300ms antes de procesar la siguiente. Si hay una solicitud pendiente se construye la URL de la petición y se procesa. Esto incluye autenticación segura (oauth) y otras tareas que, por la complejidad, es posible que generen errores no detectados y contribuyan al cuelgue de la API. Adicionalmente el resultado de la petición HTTP es procesado usando condicionales para detectar el tipo de petición y funciones que están fuera del hilo. Posteriormente ese resultado procesado es devuelto a la vista para que actualice los controles pertinentes.

En el modelo propuesto [2] la parte inicial de la solicitud permanece igual, los cambios se observan a partir de la gestión de la cola. En este punto entra en acción una nueva clase llamada Protocolo. Esta clase hereda de una interfaz común donde estarán las definiciones básicas de las funciones que debe tener cualquier protocolo, de esta forma se deja abierta la posibilidad para integrar muchos otros protocolos de microblogging. En esta clase protocolo también está una clase nueva llamada TurpialHTTP. Con ésta clase se pretende gestionar todo lo referente a peticiones HTTP, autenticación y excepciones; será la clase que entré con contacto directo con el servicio. El resultado que devuelva TurpialHTTP es procesado dentro de la misma clase protocolo e incluso dentro del mismo método que ejecutó la petición, evitando tener que usar funciones fuera del hilo. Este resultado se devuelve a la API y ésta hace lo propio para actualizar los controles de la vista. Para una siguiente optimización se puede considerar usar el controlador como intermediario para actualizar la vista (como debe ser).

Para esta nueva implementación también se pretende usar una serie de objetos que ayuden a la unificación de los datos. Entre ellos un objeto Post que represente de forma unívoca un tweet y un objeto Response que permita representar un grupo de objetos Post (como respuesta a una petición) con un error o mensaje descriptivo. Más adelante estaré dando más información al respecto.

Disculpen si es un poco ofuscada la información, fue lo mejor que pude hacer para representar las ideas que tengo en mente :P

Es todo por ahora. Comentarios, preguntas y sugerencias bienvenidas


--
“Yo construyo Soberanía, uso Software Libre”
Wil A. Alvarez
CVA Cafe C.A. CyT
Linux Counter #415026
http://damncorner.blogspot.com/

Sebastián

unread,
May 17, 2010, 10:23:01 AM5/17/10
to turpi...@googlegroups.com
2010/5/14 Wil Alvarez <wil.al...@gmail.com>:
Podemos planificar una reunión vía IRC para discutir sobre esto?

De cualquier manera, trataré de sacar un poco de tiempo para una
respuesta más completa. El registro de la lista de correos es mejor
que el del canal IRC.

Antonio Bastardo

unread,
May 17, 2010, 10:26:33 AM5/17/10
to turpi...@googlegroups.com
SI se da lo del IRC avisen
Salu2

2010/5/17 Sebastián <sebas...@gmail.com>

Wil Alvarez

unread,
May 17, 2010, 10:42:31 AM5/17/10
to turpi...@googlegroups.com
Bueno si quieren podemos reunirnos hoy mismo tipo 8pm en el canal #turpial en IRC. Les parece ¿o cuadramos otra hora/fecha? Si es entre martes o jueves deberíamos hacerla un poco más tarde porque llego a mi hogar a eso de la 10pm

Deivinson Tejeda

unread,
May 17, 2010, 10:51:57 AM5/17/10
to turpi...@googlegroups.com
Yo pudiera participar si es eso de las 10pm, para participar y ver si puedo aportar algo al diseño de esta nueva API, de todas maneras si cuadran otra hora pudieran guardar el log de la conversa...

Éxitos!

2010/5/17 Wil Alvarez <wil.al...@gmail.com>

Deivinson Tejeda

unread,
May 17, 2010, 11:04:22 AM5/17/10
to turpi...@googlegroups.com
Wil otra cosa interesante que ha anunciado twitter sobre su nuevo
formato para ver los tweets vía API hasta ahora, los desarrolladores
de Twitter tenían que trabajar con tweets individuales solos,
extrayendo las etiquetas, las respuestas con @, los enlaces y otros
datos de ese tipo. Con su última incorporación a la API de Twitter,
esta información se proveerá en bocados fácilmente digestibles.

Mas detalle[1], como vez esto hará mas rápido turpial seguramente por
el hecho de muchas expresiones regulares se acabaran porque la misma
naturaleza del tweets será fácil de digerir.

[1] http://groups.google.com/group/twitter-api-announce/browse_frm/thread/9b869a9fe4d4252e


Éxitos!


2010/5/17 Deivinson Tejeda <deivins...@gmail.com>

Wil Alvarez

unread,
May 17, 2010, 11:08:31 AM5/17/10
to turpi...@googlegroups.com
Epa que buena noticia Deivinson! Tienes toda la razón, eso hará a Turpial más rápido pues no hay que estar hurgando en el cuerpo del tweet para buscar eso sino que lo tendríamos disponible en el hash que devuelve la API. De verdad es grandioso, hoy mismo empezaré a leer sobre eso.

Gracias por el dato

Wil Alvarez

unread,
Jun 4, 2010, 3:26:57 PM6/4/10
to turpi...@googlegroups.com
Continuando con el trabajo de optimización de la API les dejo algunas cosas que hice en la nueva API, digamos a manera de documentación.

1.- Primero tenemos una estructura mejorada de los directorios y módulos de la API. Quedaron así:

turpial
└─ api
      ├── turpialapi.py
      ├─ __init__.py
      ├── interfaces (solo las clases comunes)
            ├─ __init__.py
            ├── http.py
            ├── response.py
            ├── post.py
            └── service.py (antes llamado generic.py)
      ├── services (todos los servicios disponibles)
            ├─ __init__.py
            ├── shorturl (servicios de cortado de URL)
            └─ uploadpic (servicios para subir imágenes)
      └── protocols (todos los protocolos soportados y sus respectivas librerías)
              ├─ __init__.py
              ├─ twitter
                    ├── twitter.py
                    ├── oauth.py
                    ├── http.py
                    ├── globals.py
              │      └─ __init__.py
              └─ identica
                      ├── identica.py
                      ├── globals.py
                      └─ __init__.py


2.- Se han creado algunos objetos comunes para las distintas clases/servicios:

TurpialHTTPRequest: una clase que representa una petición HTTP y dispone de todos los atributos necesarios para realizarla.
  • argStr
  • headers
  • argData
  • encoded_args
  • method
  • strReq
  • uri
  • params
TurpialHTTP: encargado de manejar una petición HTTP. Construye un request, le aplica la autenticación y devuelve una respuesta. Esta clase debe extenderse para cada protocolo en caso de que los procesos de autenticación sean diferentes de la autenticación básica (todos los métodos marcados con *** son los que se deben reimplementar en ese caso). Una de las ventajas de hacer esto es que todas las excepciones relacionadas con el servicio (comunicación, conexión, peticiones, etc) pueden interceptarse desde un mismo punto y convertirlas en errores fáciles de manejar por Turpial.
  • _build(uri, args) -> Construye un TurpialHTTPRequest
  • _send(httpreq) -> Envía al servidor y devuelve una respuesta o una excepción en caso de error
  • __basic_auth(httpreq) -> Aplica autenticaciòn básica a un request. Es llamado por apply_auth
  • do_request(uri, args) -> Llama a __build para construir el request, le aplica la autenticación con apply_auth y lo envía con __send. Devuelve la respuesta
  • apply_auth(httpreq) -> Toma el request, le aplica la autenticación y devuelve un request autenticado ***
  • auth(username, password, args) -> Guarda y establece las credenciales del usuario ***
  • request(uri, args) -> LLama a do_request para procesar la solicitud pero efectuando las validaciones pertinentes ***
Status: objeto que representa un estado (tweet o dent)
  • id
  • text
  • username
  • avatar
  • source -> Cliente usado en la generación del estado
  • timestamp -> Hora/fecha del estado tal y como se verá en turpial (procesado)
  • in_reply_to_id -> Id del estado al que se le está respondiendo
  • in_reply_to_user -> Nombre del usuario al que se le está respondiendo
  • is_favorite 
  • retweeted_by -> Usuario(s) que han retuiteado el estado
  • datetime -> Hora/fecha del estado en entero largo
Response: representa una respuesta. type indica el tipo de respuesta y en items se guardan los objetos
  • items
  • type #status/profile/rate/error/mixed
  • errmsg
Profile: éste objeto representa un perfil de usuario (tanto propio como de amigos)
  • id
  • fullname -> Nombre completo
  • username -> Nick o nombre en pantalla
  • avatar
  • location
  • url
  • bio
  • following -> Indica si estás siguiendo al usuario o no
  • followers_count -> Número de seguidores
  • friends_count -> Número de seguidos
  • password
  • profile_link_color -> Color de los elementos resaltables del perfil
  • statuses_count -> Cantidad de estados del usuario
RateLimit: permite almacenar los datos sobre límites de llamadas a la API (si es que existen)
  • hourly_limit -> Límite por hora
  • remaining_hits -> Llamadas disponibles
  • reset_time -> Hora/Fecha de reset tal y como se verá en turpial
  • reset_time_in_seconds -> Hora/Fecha de reset en segundos
GenericService: clase genérica para implementar servicios. Las funciones que comienzan con _ son las más comunes en los servicios y que vienen implementadas por defecto
  • _download_pic
  • _get_request
  • _json_request
  • _quote_url
  • _upload_pic
  • _encode_multipart_formdata
  • _get_content_type
  • _get_pic_name
  • _parse_xml
  • do_service -> Debe implementarse en la clase hija con la lógica de cada servicio
Protocol: ésta clase es la fulana que permite implementar distintos protocolos de microblogging. Es muy extensa para documentarla toda así que mi limitaré a comentar las funciones que se deben reimplementar en cada protocolo.
  • response_to_statuses -> toma un objeto Response y lo convierte en un arreglo de objetos Status
  • response_to_profiles -> toma un objeto Response y lo convierte en un arreglo de objetos Profile
  • auth
  • get_timeline
  • get_replies
  • get_directs
  • get_favorites
  • get_rate_limits
  • get_conversation
  • get_friends_list
  • update_profile
  • update_status
  • destroy_status
  • repeat
  • mark_favorite
  • unmark_favorite
  • follow
  • unfollow
  • send_direct
  • destroy_direct
  • search

3.- Ahora se emplea correctamente el join para salir de los hilos (tanto de la API como de los servicios) de forma limpia y no dejar procesos zombies (es decir, ya Turpial no se congela al salir de la aplicación)

4.- Se logró reducir la API a solo: llamadas para registrar las solicitudes en la cola y la función run para sacarlas de la cola y ejecutarlas en el hilo. Posteriormente se devuelve el resultado usando el respectivo callback

Es todo lo que tengo a mano por los momentos, iré posteando más en la medida que vaya recordando y evolucionando en el desarrollo :D

Saludos
Reply all
Reply to author
Forward
0 new messages