Как реализовать значки? - PullRequest
42 голосов
/ 02 июля 2010

Я немного подумал о реализации значков (как и здесь, в «Переполнении стека») и думаю, что это будет сложно без служб Windows, но я бы хотел этого избежать, если это возможно.

Я разработал план реализации нескольких примеров:

  • Audobiographer: Проверьте, заполнены ли все поля в профиле.
  • Комментатор: при создании комментария проверяйте, равно ли количество комментариев 10, если это так, присваивайте значок.
  • Хороший ответ: При голосовании проверьте, является ли счет для голосования 25 или выше.

Как это можно реализовать в базе данных? Или другой путь будет лучше?

Ответы [ 4 ]

41 голосов
/ 02 июля 2010

Реализация, аналогичная реализации Stackoverflow, на самом деле намного проще, чем вы описали, на основе битов информации, сбрасываемых командой каждый раз в какое-то время.

В базе данных вы просто сохраняете коллекцию пар BadgeID - UserID, чтобы отслеживать, у кого что есть (и количество или rowID, позволяющие получить несколько наград за некоторые значки).

В приложении есть рабочий объект для каждого типа значка. Объект находится в кеше, и когда срок его действия истекает, рабочий запускает собственную логику для определения, кто должен получить значок и делать обновления, а затем снова вставляет себя в кеш:

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);
    }
}

И конкретная реализация:

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); }
    }
}
4 голосов
/ 02 июля 2010

Работа.Это ключ.Вне процессных заданий, которые выполняются с заданными интервалами для проверки упомянутых вами критериев.Я не думаю, что вам даже нужно иметь службу Windows, если для установки уровней не требуются внешние ресурсы.Я действительно думаю, что StackOverflow также использует задания для своих расчетов.

0 голосов
/ 02 июля 2010

комментарии должны храниться в базе данных, верно? тогда я думаю, что есть два основных способа сделать это.

1) когда пользователь входит в систему, вы получаете количество комментариев. это явно нежелательный подход, так как подсчет может занять много времени

2) когда пользователь публикует комментарий, вы можете либо выполнить подсчет, а затем сохранить счет с подробными данными об использовании, либо создать триггер, который выполняется при добавлении комментария. затем триггер получит сведения о недавно созданном комментарии, захватит идентификатор пользователя, получит счетчик и сохранит его для пользователя в некоторой таблице.

Мне нравится идея триггера, поскольку ваша программа может возвращаться без ожидания, пока sql-сервер выполнит свою работу.

0 голосов
/ 02 июля 2010

Вы можете использовать триггеры и проверять после обновления или вставки, а затем, если ваши условия выполняются, добавить значок.Это справится, кажется, меньше.Начните активацию триггера через 3, 2, 1 ...

...