FB API + Workers

56 views
Skip to first unread message

Marcos Chicote

unread,
Apr 24, 2014, 8:36:06 AM4/24/14
to rub...@googlegroups.com
Hola
Estoy armando una aplicación que va a superar el límite impuesto por FB de 600 llamados a la api cada 600 segundos por app token por ip[1]. 

Quizás estoy haciendo una pregunta más de arquitectura, pero en algún punto también es tecnológica porque voy a tener que pensar qué librerías usar y estoy programando todo en Ruby. También me viene bien el solo poder discutir un poco con alguien. 

Tengo que tomar varias decisiones:
  1. Un servidor con un pool de IPs vs Varios servidores: dado que hacer llamados a la API de FB no es el único proceso en background que voy a correr, no me molestaría tener varios servidores con distintas IPs y que cuando no puedan hacer llamados a la API, hagan otra cosa. Como no me gustaría que los llamados a la API queden encolados durante mucho tiempo, creo que me conviene la primer alternativa porque puedo ir sumando servidores según se necesite. 
  2. Control de la cantidad de llamadas en los últimos 15 minutos: no se me ocurre una estructura de datos copada para hacer esto. No quiero tirar una query para ver cuantos llamados van. Una lista con un combinación de #drop_while y #length? 
  3. Quién lleva la cuenta? Desde el diseño también tengo que decidir si el proceso lleva la cuenta de cuantas llamadas hizo o alguien externo lo va regulando y le dice "frena", "arranca", etc.
  4. Cola de tareas: qué uso para la cola donde guardo las tareas a ejecutar. Por lo que leí en un thread hace un poquito más de un mes en esta lista lo que mas me convence es Sidekiq. 
  5. Cómo guardo los resultados de los llamados? Le pego directo a la base? Un callback? Meto los resultados en otra cola y que alguien se ocupe? En principio esta última me suena la más limpia. 
  6. Hay un servidor central? Me permitiría levantar más instancias si las tareas están tardando mucho, controlar la cantidad de llamados a la api de cada servidor que hace llamadas, decirle a que proceso switchear si está llegando al límite o hay otras prioridades, etc. Siento que está bueno porque me da más control.
En fin, como ven estoy en un quilombo, pero que a mi al menos me resulta interesante. Cualquier ayuda que me puedan dar es bienvenida.

Gracias!
Marcos

Angel Java Lopez

unread,
Apr 24, 2014, 9:04:16 AM4/24/14
to rub...@googlegroups.com
Interesante tema!

Bien, sin saber de Ruby, algunos comentarios. Primero, jerga:

- Maquina Worker: es la que hace los llamados a la API externa, sea FB, Twitter o la casa de mi tia carlota
- Maquina Central: es la que sabe que llamados a la API tiene que hacer, y lo reparte a las worker

Primero, haria que cada Worker controle: "No puedo hacer mas de 600 llamadas en 600 segundos". Cada worker sabe exactamente eso, el central a lo sumo sabe: "che, le pedi al worker 1 que hiciera llamadas, pero no se si las hizo o no". Asi que el origen de la verdad, esta en el worker

Ahora bien, cuando el Central tiene una nueva llamada, podria decidir a que Worker mandarselo, pero me parece "too much". Mas mejor me parece: mira, Cacho, no se a que Worker se lo envio, pero lo pongo en una cola, expuesta a todo el que quiera (si, suena medio feo lo de "cola expuesta" ;-),  y el que se este rascando el higo que tome las llamadas de ahi.

Cada worker, toma trabajo de la cola, siempre vigilando: no puedo tomar mas trabajo si ya llegue al limite de 600 llamadas en 600 segundos.

Entonces, automagicamente, los Worker veran repartido el trabajo. El que sea rapido, pero no haya llegado al limite, tomara mensajes de la cola central. El que sea rapido pero haya llegado al limite, se llamara a auto recato, y no consumira mensajes por un tiempo.

El central puede darse cuenta del tamanio de la cola, y vigilarla, dando alguna alarma: che, o estan de huelga, o los worker no quieren trabajar, o necesito mas worker, porque la cola de pendientes esta creciendo.

Se pueden prender mas worker, y voila, la armonia regresa.

Jeje... ni idea en Ruby, pero en Node es a piece of cake.

Nos leemos!

Angel "Java" Lopez
@ajlopez



--
Has recibido este mensaje porque estás suscrito al grupo "rubysur" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a rubysur+u...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Lorenzo Jorquera

unread,
Apr 24, 2014, 9:12:37 AM4/24/14
to rub...@googlegroups.com
Hola Marcos!

 una vez que tuve que hacer algo así pero con SMSs (en Java) utilicé una combinación de ActiveMQ y Camel. Camel tiene mecanismos para limitar el rate de mensajes que se consumen por periodo de tiempo y para distribuir mensajes entre consumidores así que prácticamente el laburo fue aprender a usarlo. Si usar JRuby es una alternativa para vos, esto podria ser una solución.

Julio Lucero

unread,
Apr 24, 2014, 9:20:35 AM4/24/14
to rub...@googlegroups.com
Marcos, 

Estás seguro que con eso vas a evitar el  'user rate limit' y el 'app rate limit' ?. Los 600/600 creo que son para la 'api rate limit' (error: 613) [3]


Matias Mascazzini

unread,
Apr 24, 2014, 9:21:52 AM4/24/14
to rubysur
Muy bueno lo que propones Angel, "una cola, múltiples servidores" sería en Teoría de Colas (http://es.wikipedia.org/wiki/Teor%C3%ADa_de_colas). Es la solución más eficiente si mal no recuerdo, porque si un Worker es más lento que los otros se balancea la cosa, y el tiempo de espera se mantiene en promedio; por eso los bancos y otro tipo de oficinas usan el sistema de cola única para abaratar costos.


Saludos
Matías Mascazzini

Corrientes, Argentina

Me encuentras en:
LinkedIn: http://ar.linkedin.com/in/matiasmasca/es
Twitter: @matiasmasca
ComunidadTIC: @matiasmasca
---------
Le recomiendo visitar: www.ComunidadTIC.com.ar
"¿Eres Informático?"

PD: aunque en la AFIP me pusieron un solo Worker y me comí de 4 horas de espera.


2014-04-24 10:04 GMT-03:00 Angel Java Lopez <ajlop...@gmail.com>:

Marcos Chicote

unread,
Apr 24, 2014, 9:40:38 AM4/24/14
to rub...@googlegroups.com
Gracias Angel, Lorenzo y Julio!
Una aclaración general: no estoy atado a Ruby, si algun otro lenguaje resulta más flexible para solucionar este problema o tiene características que me lo facilitan o librerías que me simplifican la vida, bienvenido sea. 

Lorenzo, lo que decis de Camel tiene muy buena pinta! Lo voy a chusmear!

Angel, pensé también la alternativa que sugerís. Coincido en que es más eficiente y que la verdad de la milanesa la tiene el worker. Me pregunto si no perderé un poco de control (siempre puedo tener distintos "modos" de funcionamiento) y si es igual de limpio. Quizás el comentario de Julio sobre limites globales haga que tenga que tener centralizada la cantidad de llamados globales. 

Julio,
No, no estoy seguro. El user rate limit no creo q lo pase. El escenario esperado es muchas llamadas pero a distintos usuarios. Para un usuario en particular dudo que supere las 100 llamadas por día en el peor caso. Con respecto al app rate limit, no me queda claro, pero puede que sea un problema. En principio el tipo de llamadas que voy a hacer no deberían ser muy complejas (actualizar un estado, fijarse cuanta gente le dio like/share/comment a un post, ver cuantos amigos tengo, etc.). Trabajaste alguna vez con este problema? Tenes alguna sugerencia? Yo lo que pienso es que de alguna forma el Candy Crush postea en todos los muros en los que postea con la frecuencia con la que lo hace...

Saludos!

Manuel Garcia

unread,
Apr 24, 2014, 2:09:25 PM4/24/14
to rub...@googlegroups.com
Hola Marcos, 

On Apr 24, 2014, at 10:40 AM, Marcos Chicote <totoc...@gmail.com> wrote:

Gracias Angel, Lorenzo y Julio!
Una aclaración general: no estoy atado a Ruby, si algun otro lenguaje resulta más flexible para solucionar este problema o tiene características que me lo facilitan o librerías que me simplifican la vida, bienvenido sea. 

Lorenzo, lo que decis de Camel tiene muy buena pinta! Lo voy a chusmear!

Angel, pensé también la alternativa que sugerís. Coincido en que es más eficiente y que la verdad de la milanesa la tiene el worker. Me pregunto si no perderé un poco de control (siempre puedo tener distintos "modos" de funcionamiento) y si es igual de limpio. Quizás el comentario de Julio sobre limites globales haga que tenga que tener centralizada la cantidad de llamados globales. 

Julio,
No, no estoy seguro. El user rate limit no creo q lo pase. El escenario esperado es muchas llamadas pero a distintos usuarios. Para un usuario en particular dudo que supere las 100 llamadas por día en el peor caso. Con respecto al app rate limit, no me queda claro, pero puede que sea un problema. En principio el tipo de llamadas que voy a hacer no deberían ser muy complejas (actualizar un estado, fijarse cuanta gente le dio like/share/comment a un post, ver cuantos amigos tengo, etc.). Trabajaste alguna vez con este problema? Tenes alguna sugerencia? Yo lo que pienso es que de alguna forma el Candy Crush postea en todos los muros en los que postea con la frecuencia con la que lo hace…
La política de uso de la API no es trivial y sería un garrón que no uses al máximo la posibilidades que tenes, más cuando 600/600 no es NADA. Además de eso, no te avisan del uso que vas haciendo de tu quota (como otras APIs). Si te pasas te degradan a 1/3 el rate limit y así hasta bannearte. 

Nosotros en Altoros (con Julio) tenemos un proyecto que tiene miles de 'Social Network users’, algunos con solamente FB, otros con solo Twitter (ooootro mundo) y algunos con ambos. 
Una de las cosas que tenemos que hacer es traernos LA 'VIDA’ desde las redes sociales de cada user. En el caso de FB, los posts, amigos, posts de amigos, likes, …. No solo traernos sino mantenernos actualizados. Obviamente que para esto usamos el diff desde la última vez que trajimos.

Comentarios inline..
Si seguis las reglas de FB no vas a necesitar engañarlos utilizando varias IPs. No son ningunos tontos :)
Como dice la buena práctica, arranca lo más chiquito que puedas y luego, si realmente lo necesitas, fijate de poder escalar horizontalmente fácilmente.

  1. Control de la cantidad de llamadas en los últimos 15 minutos: no se me ocurre una estructura de datos copada para hacer esto. No quiero tirar una query para ver cuantos llamados van. Una lista con un combinación de #drop_while y #length? 
Es un tema en Ruby. Cuando buscamos no había nada de nada que lo maneje. Para interactuar con la API si lo hay: https://github.com/arsduo/koala

  1. Quién lleva la cuenta? Desde el diseño también tengo que decidir si el proceso lleva la cuenta de cuantas llamadas hizo o alguien externo lo va regulando y le dice "frena", "arranca", etc.
Tal vez Julio o Juan Pablo (otro chico involucrado en el proyecto) pueden explicarte mejor este tema. Hasta donde se, utilizamos https://github.com/lostisland/faraday para interceptar los requests a las APIs y mantener controlado el Rate Limit según nuestras propias reglas. Como se manejan muchos Workers Servers hay que tener una vision unificada de los ‘contadores’. Para esto guardamos la data en Redis, que además utilizamos para Sidekiq

  1. Cola de tareas: qué uso para la cola donde guardo las tareas a ejecutar. Por lo que leí en un thread hace un poquito más de un mes en esta lista lo que mas me convence es Sidekiq. 
Nosotros usamos Sidekiq y nos esta dando muy buenos resultados. Es más, utilizamos su API programáticamente para obtener estadísticas como: cuánto falta para terminar de traernos la data de ‘Manuel García’? etc.

  1. Cómo guardo los resultados de los llamados? Le pego directo a la base? Un callback? Meto los resultados en otra cola y que alguien se ocupe? En principio esta última me suena la más limpia. 
Todo depende de lo que quieras hacer con ellos. Podes ir desde tratarlos en el mismo Job hasta tirarlo hacia otras colas con otros Jobs que se hagan cargo de lo traído de FB.


  1. Hay un servidor central? Me permitiría levantar más instancias si las tareas están tardando mucho, controlar la cantidad de llamados a la api de cada servidor que hace llamadas, decirle a que proceso switchear si está llegando al límite o hay otras prioridades, etc. Siento que está bueno porque me da más control.
En fin, como ven estoy en un quilombo, pero que a mi al menos me resulta interesante. Cualquier ayuda que me puedan dar es bienvenida.
Si no estuvieses en un quilombo con esto te buscaría y felicitaría :)
Lidiar con las políticas de uso de la API, penalidades específicas según sus códigos, que te corten el chorro sin tener una clara idea del por qué, etc esun desafío interesante para resolver.

Si te interesa algo de esto avisa que seguramente uno que otro gist podemos tirar.

Saludos

Marcos Chicote

unread,
Apr 24, 2014, 3:05:45 PM4/24/14
to rub...@googlegroups.com
Gracias por la respuesta Manuel!! 
Me resultan muy interesantes los comentarios que haces, pero me llama particularmente la atención el de "Si seguis las reglas de FB no vas a necesitar engañarlos utilizando varias IPs.". Como resuelven entonces hacer más de 600 llamadas cada 600 segundos? Se puede conocer un poco la arquitectura que manejan? Si les resulta pesado escribir mucho y no les molesta (y están en BsAs o alrededores) también podemos juntarnos a charlar un rato.

Gracias!!

Manuel Garcia

unread,
Apr 24, 2014, 3:28:07 PM4/24/14
to rub...@googlegroups.com
On Apr 24, 2014, at 4:05 PM, Marcos Chicote <totoc...@gmail.com> wrote:

Gracias por la respuesta Manuel!! 
Me resultan muy interesantes los comentarios que haces, pero me llama particularmente la atención el de "Si seguis las reglas de FB no vas a necesitar engañarlos utilizando varias IPs.". Como resuelven entonces hacer más de 600 llamadas cada 600 segundos?
En el contexto donde lo usamos, cada requests va con su debido token, de aplicación o usuario. A cada token se le aplica el control de quota.

Se puede conocer un poco la arquitectura que manejan? Si les resulta pesado escribir mucho y no les molesta (y están en BsAs o alrededores) también podemos juntarnos a charlar un rato.
Debo tener por ahí algo dibujado a mano, sino se puede hacer rápido.
Estamos en Santa Fe + Mendoza :)
Hangout?

Marcos Chicote

unread,
Apr 24, 2014, 5:11:30 PM4/24/14
to rub...@googlegroups.com
Dale, yo estoy dedicado 100% a este emprendimiento, así que cuando a ustedes les quede cómodo. Si queres terminamos de organizar esto en privado. 

Me sorprende que siendo un limite relativamente bajo el impuesto por FB puedan hacer todo lo que hacen con una sola IP, buenas magias deben tener ahi!

Para el resto de la lista que le interese como sigue el tema me comprometo a escribir unos posts cuando haya algo para escribir.

Gracias a todos! Los que quieran seguir sumando ideas, sugerencias, criticas, adelante por favor!
Reply all
Reply to author
Forward
0 new messages