Un semblable-à-Stackoverflow mise en œuvre est en fait beaucoup plus simple que vous avez décrite, basée sur des morceaux de l'info lâchée par l'équipe à chaque fois dans un certain temps.
Dans la base de données, il vous suffit de stocker une collection d' BadgeID
-UserID
des paires de piste qui a de quoi (et un comte ou un rowID pour permettre à de multiples récompenses pour certains badges).
Dans l'application, il est un travailleur de l'objet pour chaque badge type. L'objet est dans le cache, et quand le cache expire, le travailleur exécute sa propre logique pour déterminer qui devrait recevoir le badge et de faire les mises à jour, et puis il ré-insère lui-même dans le cache:
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);
}
}
Et une mise en œuvre concrète:
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); }
}
}