Как архитектора кэш веб-сервиса в C #
-
28-09-2019 - |
Вопрос
Я работаю над веб-службой, чтобы прочитать данные из 3-го вечеринки, немного изменить его и хранить его, а затем вернуть его к своим клиентам. Это нужно только периодически обновлять с 3-го сайта вечеринки. Он будет работать как служба WCF в веб-роли в Azure.
Сначала я подумал, что я просто позвонюю моим методом Parsefeed, но сделаю этот возврат звонка, если последнее обновление было слишком рано ...
public void ParseFeed()
{
if (DateTime.Now > lastrun.AddMinutes(1))
{
//Fetch updated data into something shared here.
//thedata is a public static in Global class
thedata = fetchdata();
lastrun=DateTime.Now;
}
}
Но я думаю, что в качестве приема может занять 1-2 секунд (его веб-сервис), что несколько пользователей ударит этот код одновременно.
от http://support.microsoft.com/default.aspx?scid=kb;en-us ;q312607.Поскольку статические элементы любого класса, включая класс приложения, не являются безопасными потоками, пользовательский код должен предоставить соответствующую блокировку для доступа к статическим элементам. Это относится к любому статическому элементу, которое вы добавляете в класс приложений.
Я мог бы использовать блокировку (не уверен, как) редактировать: много информации здесь
Я мог бы избежать статического var и использовать кэш, и поместите в нее свои данные (но это будет удалено по истечении срока действия и несколько пользователей попытаемся получить данные)
Я мог бы использовать кэш с поддельным элементом данных в нем (в основном как таймер) и обновить, когда истек, но это будет обновляться, даже если никто не ударил на сайт. (Также не может быть без потока)
Я не могу использовать выходные кэш-память, потому что клиенты запрашивают данные, которые я возвращаю таким образом, который, вероятно, делает каждый запрос уникальным: мои сервисные сортировки и фильтры в соответствии с запросом
Кстати, я не беспокоюсь о консистенции результатов над несколькими экземплярами на Azure. Каждый может принести свои собственные, поэтому мне не нужно делиться состоянием по нескольким серверам.
Я получаю чувство, что есть простое решение, что я полностью пропустил. Идеи?
Решение
С твоего вопроса похоже:
- Неприемлемо подавать данные, которые больше минуты устарели
- Допустимо, если два сервисных экземпляра возвращают разные данные из-за того, что время обновления не синхронизации
- Это приемлемо для абонентов заблокировать на 1-2 секунды, когда данные обновлены
Предполагая, что все это правда, то самое простое решение - это просто использовать статическую переменную для хранения данных, с помощью lock
построить вокруг всего блока проверки / обновления. Я бы даже не хотел бы попытаться сделать что-нибудь умное, как двойной проверки замка; Соотношение замка просто не будет проблемой, поскольку время, проведенное в критическом регионе, бледнется на незначительность по сравнению с накладными расходами эксплуатации веб-службы, за исключением случаев, когда он блокируется, и все должны блокировать все равно.
Другие советы
Поскольку вы, вероятно, будете читать с кеша больше, чем вы будете писать, я бы использовал ReaderWriterLockSlim. Чтобы гарантировать, что данные могут быть прочитаны несколькими потоками одновременно, но не написаны. Я также бы также убедился, что кэшированные данные неизменны, чтобы убедиться, что она не изменена потребителями.