Схема доступа к данным, сочетающая push и pull? - PullRequest
1 голос
/ 14 марта 2010

Мне нужен совет о том, какие шаблоны я должен использовать для добавления / извлечения данных в мое приложение.

Я пишу механизм правил, который должен содержать достаточно большой объем данных в памяти, чтобы быть достаточно эффективным. У меня есть довольно противоречивые требования;

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

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

Упрощенная версия моего текущего «шаблона» выглядит следующим образом (в psuedo-C #, написанном в блокноте):

// This interface is implemented by all classes that needs the data
interface IDataSubscriber 
{
    void RegisterData(Entity data);
}

// This interface is implemented by the data access class
interface IDataProvider
{
    void EnsureLoaded(Key dataKey);
    void RegisterSubscriber(IDataSubscriber subscriber);
}


class MyClassThatNeedsData : IDataSubscriber
{
    IDataProvider _provider;

    MyClassThatNeedsData(IDataProvider provider) 
    {
        _provider = provider;
        _provider.RegisterSubscriber(this);
    }

    public void RegisterData(Entity data) 
    {
        // Save data for later
        StoreDataInCache(data);
    }

    void UseData(Key key)
    {
        // Make sure that the data has been stored in cache
        _provider.EnsureLoaded(key);

        Entity data = GetDataFromCache(key);
    }
}

class MyDataProvider : IDataProvider
{
    List<IDataSubscriber> _subscribers;

    // Make sure that the data for key has been loaded to all subscribers
    public void EnsureLoaded(Key key)
    {
        if (HasKeyBeenMarkedAsLoaded(key))
            return;

        PublishDataToSubscribers(key);

        MarkKeyAsLoaded(key);
    }

    // Force all subscribers to get a new version of the data for key
    public void ForceReload(Key key)
    {
        PublishDataToSubscribers(key);

        MarkKeyAsLoaded(key);
    }

    void PublishDataToSubscribers(Key key)
    {
        Entity data = FetchDataFromStore(key);

        foreach(var subscriber in _subscribers)
        {
            subscriber.RegisterData(data);
        }
    }
}

// This class will be spun off on startup and should make sure that all data is 
// preloaded as quickly as possible
class MyPreloadingThread 
{
    IDataProvider _provider;

    MyPreloadingThread(IDataProvider provider)
    {
        _provider = provider;
    }

    void RunInBackground()
    {
        IEnumerable<Key> allKeys = GetAllKeys();

        foreach(var key in allKeys) 
        {
            _provider.EnsureLoaded(key);
        }
    }
}

У меня есть ощущение, что это не обязательно лучший способ сделать это ... Просто тот факт, что объяснение этого занимает две страницы, выглядит как указание.

Есть идеи? На какие модели мне стоит взглянуть?

Ответы [ 2 ]

1 голос
/ 15 марта 2010

Однозначно, должно быть

  • один из шаблонов параллелизма ( активен объект , например)
  • шаблон производитель-потребитель (очередь)
  • ленивая нагрузка (данные по запросу)
  • Ленивый шаблон выгрузки
  • шаблон стратегии (для реализации алгоритмов доступа к данным)
  • многопоточный доступ защищен ресурс (кеш)

Мой голос - активный объект с общей очередью (шиной) + ленивые шаблоны + кэш

0 голосов
/ 14 марта 2010

Вы можете начать с чего-то простого, например, решения, основанного на Шаблон шлюза . Тогда вы можете попытаться повысить производительность, добавив Cash.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...