Eine Stackoverflow-ähnliche Implementierung ist tatsächlich viel einfacher als Sie beschrieben haben, basierend auf Informationen, die das Team hin und wieder fallen lässt.
In der Datenbank hinterlegen Sie einfach eine Sammlung von BadgeID
-UserID
Paare, um zu verfolgen, wer was hat (und eine Anzahl oder eine Zeilen-ID, um mehrere Auszeichnungen für einige Abzeichen zu ermöglichen).
In der Anwendung gibt es für jeden Ausweistyp ein Arbeiterobjekt. Das Objekt befindet sich im Cache, und wenn der Cache abläuft, führt der Worker seine eigene Logik aus, um zu bestimmen, wer das Badge erhalten und die Aktualisierungen vornehmen soll, und fügt sich dann selbst wieder in den Cache ein:
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);
}
}
Und eine konkrete Umsetzung:
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); }
}
}