2010-07-01 6 views
42

J'ai réfléchi à l'implémentation de badges (tout comme les badges ici sur Stack Overflow) et je pense que ce serait difficile sans les services Windows, mais j'aimerais éviter cela si possible.Comment implémenter des badges?

je suis venu avec un plan pour mettre en œuvre quelques exemples:

  • Audobiographer: Vérifiez si tous les champs du profil est rempli.
  • Commenteur: Lorsque vous faites un commentaire, vérifiez si le nombre de commentaires est égal à 10, si c'est le cas, attribuez le badge.
  • Bonne réponse: Lors du vote up vérifier pour voir si le score de vote est de 25 ou plus.

Comment cela pourrait-il être implémenté dans la base de données? Ou est-ce qu'une autre façon serait meilleure?

+0

Vous voudriez mettre en cache une certaine utilisation de la valeur de réputation sur le serveur Web sans avoir à appeler constamment les services Windows. – Russell

Répondre

41

Une implémentation similaire à Stackoverflow est en réalité beaucoup plus simple que ce que vous avez décrit, sur la base de bits d'information déposés par l'équipe de temps en temps.

Dans la base de données, vous stockez simplement une collection de paires BadgeID - UserID pour suivre qui a quoi (et un nombre ou un rowID pour autoriser plusieurs récompenses pour certains badges).

Dans l'application, il existe un objet de travail pour chaque type de badge. L'objet est dans le cache, et lorsque le cache expire, le travailleur exécute sa propre logique pour déterminer qui doit obtenir le badge et faire les mises à jour, puis il réinsère se 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 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); } 
    } 
} 
+0

wow. C'est une bonne idée. Comment savez-vous quand le cache expire? Y at-il une fonction de rappel que vous pouvez appeler lorsque le cache expire? – Luke101

+0

@ Luke101 voir l'exemple de code –

+1

@ Luke101: c'est une fonctionnalité de l'infrastructure de mise en cache .NET: lorsque le délai expire (et que l'objet est sur le point de disparaître du cache), le runtime appelle automatiquement votre callback. –

4

Travaux. C'est la clé. Des tâches hors processus qui s'exécutent à intervalles réguliers pour vérifier les critères que vous mentionnez. Je ne pense pas que vous ayez besoin d'un service Windows, à moins qu'il ne nécessite des ressources externes pour définir les niveaux. Je pense en fait que StackOverflow utilise aussi des jobs pour leurs calculs.

+2

Je devrais également ajouter que pour éviter de vérifier manuellement chaque utilisateur chaque fois que vous voudriez probablement garder une table d'activité afin que vous puissiez avoir votre liste de personnes que vous voudriez vérifier.Vous ne voulez évidemment pas gaspiller des ressources en traitant des utilisateurs qui n'ont pas eu d'activité récente. – spinon

+0

Les travaux sont-ils exécutés automatiquement? Où puis-je trouver plus d'informations sur les emplois? – Luke101

+0

Les tâches peuvent être planifiées pour s'exécuter sur la base de données. Vous les construisez et ensuite définissez leur intervalle pour lequel ils doivent être exécutés. Vous remarquerez sur SO qu'une fois que vous avez terminé une action, elle ne vous récompense pas nécessairement tout de suite. Donc, j'imagine qu'ils ont des choses à exécuter toutes les quelques minutes ou plus. Mais je n'en ai vraiment aucune idée. Mais un peu de retard n'est pas une grosse affaire mais j'attendrais jusqu'à la fin de la journée pour le traitement. – spinon

0

Vous pouvez utiliser des déclencheurs et vérifier lors de la mise à jour ou de l'insertion, puis si vos conditions sont remplies, insérez un badge. Cela le traiterait plutôt moins. Commencer le bashing de déclenchement dans 3, 2, 1 ...

+6

C'est exactement le genre de déclencheurs de raison (valides) qui sont bombardés. –

+0

Je suis d'accord qu'il existe de nombreux inconvénients des déclencheurs, mais à mon humble avis, ils tournent autour de ne pas inclure la logique métier dans une couche de données/base de données. Y a-t-il des problèmes de performance ou de validité qui découlent des déclencheurs, s'ils sont écrits et mis en œuvre correctement? –

+0

problèmes de performance et de validité ont tendance à provenir de déclencheurs, car ils sont, relativement parlant, très difficile à gérer. Ils sont orientés sur les effets secondaires, alors qu'en général il est communément accepté que le code avec des effets secondaires est une recette pour le désastre. Il est difficile de présenter des arguments solides en faveur d'une seule opération (par exemple, insertion) pour avoir, du point de vue de l'appelant, une quantité inconnue d'effets secondaires supplémentaires sur le système. –

0

Les commentaires doivent être stockés dans la base de données n'est-ce pas? alors je pense qu'il y a deux manières principales de faire ceci.

1) lorsqu'un utilisateur se connecte, vous obtenez le nombre de commentaires. 2) quand un utilisateur publie un commentaire, vous pouvez soit faire un compte puis stocker le compte avec les détails d'utilisation ou vous pouvez faire un déclencheur qui ne peut pas être utilisé. s'exécute quand un commentaire est ajouté. le déclencheur obtiendrait alors les détails du commentaire nouvellement créé, saisirait l'identifiant d'utilisateur, obtiendrait un compte et le stockerait contre l'utilisateur dans une sorte de table. J'aime l'idée d'un déclencheur car votre programme peut retourner sans attendre que le serveur sql fasse son travail.

Questions connexes