2010-07-29 4 views
13

Stackoverflow tiene un sistema de insignia ingenioso. Una cosa que noté es que las insignias no se conceden de inmediato, pero a veces parecen tener algún tipo de retraso después de cumplir con los criterios. Me he dado cuenta de esto en algunos otros sitios que también tienen insignias.¿Por qué sitios como stackoverflow con insignias usan algún tipo de trabajo retrasado para determinar cuándo otorgar una nueva insignia?

Se supone que esto se debe a que están utilizando un trabajo demorado que escanea periódicamente para ver si se deben otorgar nuevas insignias. Veo este enfoque también aconsejó aquí:
How to implement badges?

Sin embargo, yo no veo por qué esto debería ser necesario, y estoy favoreciendo de mi aplicación simplemente tener un sistema en el que se lleva a cabo después de una acción relevante, por ejemplo, se publica un nuevo comentario, se llama a una función checkAwardBadge, que verifica si el usuario cumple los criterios para una nueva insignia de comentario.

Speedwise, pensaba que todas las estadísticas de usuario relevantes simplemente se guardarían en un submodelo de Usuario, como UserStats, de modo que en lugar de tener que contar el número de comentarios cada vez, sería una simple consulta.

Me parece que el sistema que estoy favoreciendo debe ser rápido y muy simple de entender. ¿Hay algún inconveniente que me falta aquí sobre por qué es necesario complicar las cosas con trabajos retrasados?

Para aclarar: Planeo tener un Logros de clase abstracta, con cada Logro real una implementación de Logros. Cada logro tendrá una función checkAwardBadge, que se puede llamar desde el controlador, o incluso un trabajo retrasado si yo elijo ir por esa ruta, o en cualquier momento realmente, para verificar si un usuario ha obtenido una determinada insignia. Por lo tanto, el código de logro estaría centralizado.

Respuesta

15

Su aplicación puede trabajar en escenarios simples (como el que usted está describiendo), pero si las cosas se vuelve más complejo que tiene una solución que:

  1. realiza comprobaciones innecesarias en cada acción
  2. Añade rendimiento sanción para cada acción
  3. No escala
  4. No tiene un lugar central para todas las reglas.
+0

(1) y (2) la penalización de rendimiento sería muy leve en esto. Solo una consulta simple de una fila a la base de datos, seguida de alguna lógica simple como (X> 30) (3) Podría explicar por qué esto no se escalaría (4) En realidad lo haría. Planeo crear una clase de Logros, con cada Logro una subclase. Entonces, solo necesitaría agregar una sola línea al código del controlador en la mayoría de los casos para hacer una llamada a checkAwardBadge en la insignia correspondiente. –

+2

(3) Solo un ejemplo: supongamos que tiene una acción como eliminar un comentario, que no activa ninguna insignia, pero más adelante necesita otorgar una insignia cuando el usuario borra un comentario, tiene que volver para buscar todo el código que elimine un Comentario y agregue la llamada a checkAwardBadge. Imagínate en escenarios más complejos. –

+2

No escala, porque cuando tienes más de 100,000 usuarios y 10,000,000 de acciones, tienes que golpear la base de datos después de cada acción de cada usuario para consultar. Si, en cambio, descarga el trabajo a un hilo de trabajo (espere), entonces eso puede ejecutarse en segundo plano y actualizar periódicamente las insignias de cada usuario. Puede ser inteligente, por ejemplo, escaneando solo las actividades que se crearon desde que se ejecutó el hilo por última vez, etc. – BryanH

4

Podría ser que si se realiza una acción e inmediatamente se deshace, no se obtenga una insignia.

2

Siempre supuse que la demora se debía a que es más rápido servir contenido estático. Creo que esto es común en los sitios con mucho tráfico, periódicamente actualiza el contenido estático en lugar de generarlo para cada solicitud web.

El trabajo periódico solo generará nuevo contenido estático y se ejecutará con mucha frecuencia, pero con menos frecuencia que cada solicitud de página.

+0

De hecho, el contenido estático solo necesita actualizarse si el contenido (o los componentes de página/widgets) se actualizan. – BryanH

15

Si bien esto va ligeramente paralelo al escenario que está describiendo, creo que hablar sobre lo que hacemos en mi trabajo podría ayudar a iluminar parte del razonamiento de este enfoque.

Trabajo para una empresa comercial algorítmica en tiempo real. Parte de lo que hace nuestro software es procesar los datos del mercado de un proveedor.

Ahora, hay cosas que deben suceder en respuesta a cada tic del mercado individual. Ejecutamos análisis, tenemos activadores de seguridad que entran en vigencia en ciertos casos, etc.Pero lo que evitamos a toda costa es inflar el código que reacciona a los eventos del mercado con toda esta lógica "secundaria".

El razonamiento aquí es que nuestros datos provienen de un proveedor de datos a través de la red, y necesitamos que esta fuente de datos fluya libremente sin ninguna copia de seguridad. Nuestro software puede manejar alrededor de 10,000 tics de mercado por segundo. Si lleva mucho tiempo procesar esos eventos del mercado, la alimentación comienza a obstruirse y nuestra capacidad de reaccionar al mercado lo más rápidamente posible se ve comprometida.

La consecuencia de esto es que nuestro código que maneja los nuevos eventos del mercado es extremadamente delgado. Un evento actualiza un precio y eso es todo. En cuanto a toda la otra lógica que necesita ejecutarse para cada evento: eso ocurre periódicamente, a través de una cola de todos los eventos que aún no han sido examinados por esta lógica.

Esto nos permite tener un hilo que es extremadamente sensible y no tiene una copia de seguridad de los datos, mientras que otro maneja los eventos entrantes y realiza cálculos más significativos con ellos. Dividir el trabajo en dos partes de esta manera mantiene todo funcionando sin problemas.

Admito que esto solo se relaciona tangencialmente con su pregunta, pero me parece que el razonamiento para no verificar la lógica relacionada con la insignia en cada acción del usuario podría ser el mismo. No desea ralentizar cada operación en el servidor mediante la ejecución de una lógica que no sea crítica en el momento preciso en que se realiza la operación. La estrategia general es mantener rápidas sus operaciones rápidas (es decir, básicamente todas las acciones del usuario) y delegar más trabajo que consume mucho tiempo a los procesos secundarios que se ejecutan, quizás a menudo, pero no para cada operación.

+0

+1 estoy absolutamente de acuerdo, y es una muy buena manera de explicar el razonamiento, creo. – Gian

Cuestiones relacionadas