Una implementación similar a Stackoverflow es en realidad mucho más simple de lo que ha descrito, según los fragmentos de información que el equipo arroja de vez en cuando.
En la base de datos, simplemente almacena una colección de BadgeID
-UserID
pares para rastrear quién tiene qué (y un conteo o ID de fila para permitir múltiples premios para algunas insignias).
En la aplicación, hay un objeto trabajador para cada tipo de credencial. El objeto está en la memoria caché y, cuando la memoria caché caduca, el trabajador ejecuta su propia lógica para determinar quién debe obtener la insignia y realizar las actualizaciones, y luego vuelve a insertarse en la memoria caché:
public abstract class BadgeJob
{
protected BadgeJob()
{
//start cycling on initialization
Insert();
}
//override to provide specific badge logic
protected abstract void AwardBadges();
//how long to wait between iterations
protected abstract TimeSpan Interval { get; }
private void Callback(string key, object value, CacheItemRemovedReason reason)
{
if (reason == CacheItemRemovedReason.Expired)
{
this.AwardBadges();
this.Insert();
}
}
private void Insert()
{
HttpRuntime.Cache.Add(this.GetType().ToString(),
this,
null,
Cache.NoAbsoluteExpiration,
this.Interval,
CacheItemPriority.Normal,
this.Callback);
}
}
Y una implementación concreta:
public class CommenterBadge : BadgeJob
{
public CommenterBadge() : base() { }
protected override void AwardBadges()
{
//select all users who have more than x comments
//and dont have the commenter badge
//add badges
}
//run every 10 minutes
protected override TimeSpan Interval
{
get { return new TimeSpan(0,10,0); }
}
}