Een implementatie die lijkt op StackOverflow is eigenlijk een stuk eenvoudiger dan je hebt beschreven, gebaseerd op stukjes informatie die het team af en toe laat vallen.
In de database slaat u eenvoudig een verzameling BadgeID
. op -UserID
paren om bij te houden wie wat heeft (en een telling of een rowID om meerdere onderscheidingen toe te staan voor sommige badges).
In de applicatie is er een worker-object voor elk type badge. Het object bevindt zich in de cache en wanneer de cache verloopt, voert de worker zijn eigen logica uit om te bepalen wie de badge moet krijgen en de updates moet uitvoeren, waarna het zichzelf opnieuw in de cache plaatst:
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);
}
}
En een concrete implementatie:
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); }
}
}