Перед нами стоит задача конвертировать службу REST на основе пользовательского кода в Web API. Услуга имеет значительное количество запросов и работает с данными, которые могут потребоваться некоторое время для загрузки, но после загрузки их можно кэшировать и использовать для обслуживания всех входящих запросов. В предыдущей версии службы был бы один поток, ответственный за загрузку данных и попадание в кеш. Чтобы предотвратить запуск IIS из рабочих потоков, клиенты получат ответ "вернуться позже", пока кеш не будет готов.
Мое понимание веб-API заключается в том, что он имеет асинхронное поведение, основанное на работе над задачами, и в результате количество запросов напрямую не связано с количеством удерживаемых физических потоков.
В новой реализации службы я планирую, чтобы запросы дождались, пока кеш не будет готов, а затем сделайте правильный ответ. Я сделал очень грубый эскиз кода, чтобы проиллюстрировать:
public class ContactsController : ApiController
{
private readonly IContactRepository _contactRepository;
public ContactsController(IContactRepository contactRepository)
{
if (contactRepository == null)
throw new ArgumentNullException("contactRepository");
_contactRepository = contactRepository;
}
public IEnumerable<Contact> Get()
{
return _contactRepository.Get();
}
}
public class ContactRepository : IContactRepository
{
private readonly Lazy<IEnumerable<Contact>> _contactsLazy;
public ContactRepository()
{
_contactsLazy = new Lazy<IEnumerable<Contact>>(LoadFromDatabase,
LazyThreadSafetyMode.ExecutionAndPublication);
}
public IEnumerable<Contact> Get()
{
return _contactsLazy.Value;
}
private IEnumerable<Contact> LoadFromDatabase()
{
// This method could be take a long time to execute.
throw new NotImplementedException();
}
}
Пожалуйста, не придавайте слишком большого значения дизайну кода - он создан только для иллюстрации проблемы и не так, как мы это сделали в реальном решении. IContactRepository регистрируется в контейнере IoC как однотонный и вводится в контроллер. Lazy с LazyThreadSafetyMode.ExecutionAndPublication гарантирует, что только первый поток/запрос запускает код инициализации, следующие rquests блокируются до завершения инициализации.
Может ли веб-API обрабатывать 1000 запросов, ожидающих завершения инициализации, в то время как другие запросы, не попавшие в этот Lazy, являются службами и без IIS заканчиваются рабочие потоки?