处理webapi中的多个相似请求
Handle multiple similar requests in webapi
在我的 WebApi 控制器中,我有以下(伪)代码接收来自 Instagrams real-time API 的更新通知:
[HttpPost]
public void Post(InstagramUpdate instagramUpdate)
{
var subscriptionId = instagramUpdate.SubscriptionId;
var lastUpdate = GetLastUpdate(subscriptionId);
// To avoid breaking my Instagram request limit, do not fetch new images too often.
if (lastUpdate.AddSeconds(5) < DateTime.UtcNow)
{
// More than 5 seconds ago since last update for this subscription. Get new images
GetNewImagesFromInstagram(subscriptionId);
UpdateLastUpdate(subscriptionId, DateTime.UtcNow);
}
}
如果我几乎同时收到同一个订阅的两个更新通知,这将不会很好地工作,因为 lastUpdate
在处理第一个请求之后才会更新。
解决这个问题的最佳方法是什么?我正在考虑使用某种缓存,但不确定如何使用。对于这类事情,是否有某种最佳实践?我猜这是一个常见问题:"receive notification, do something if something hasn't been done recently..."
恐怕这是个糟糕的主意,但是...也许值得为此方法添加锁?喜欢
private List<int> subscriptions = new List<int>();
然后
int subscriptinId = 1;//add calculation here
int subscriptionIdIndex = subscriptions.IndexOf(subscriptinId);
lock (subscriptions[subscriptionIdIndex])
{
//your method code
}
欢迎批评这种做法)
感谢this answer I went with the following approach, using MemoryCache
[HttpPost]
public void Post(IEnumerable<InstagramUpdate> instagramUpdates)
{
foreach (var instagramUpdate in instagramUpdates)
{
if (WaitingToProcessSubscriptionUpdate(instagramUpdate.Subscription_id))
{
// Ongoing request, do nothing
}
else
{
// Process update
}
}
}
private bool WaitingToProcessSubscriptionUpdate(string subscriptionId)
{
// Check in the in memory cache if this subscription is in queue to be processed. Add it otherwise
var queuedRequest = _cache.AddOrGetExisting(subscriptionId, string.Empty, new CacheItemPolicy
{
// Automatically expire this item after 1 minute (if update failed for example)
AbsoluteExpiration = DateTime.Now.AddMinutes(1)
});
return queuedRequest != null;
}
在我的 WebApi 控制器中,我有以下(伪)代码接收来自 Instagrams real-time API 的更新通知:
[HttpPost]
public void Post(InstagramUpdate instagramUpdate)
{
var subscriptionId = instagramUpdate.SubscriptionId;
var lastUpdate = GetLastUpdate(subscriptionId);
// To avoid breaking my Instagram request limit, do not fetch new images too often.
if (lastUpdate.AddSeconds(5) < DateTime.UtcNow)
{
// More than 5 seconds ago since last update for this subscription. Get new images
GetNewImagesFromInstagram(subscriptionId);
UpdateLastUpdate(subscriptionId, DateTime.UtcNow);
}
}
如果我几乎同时收到同一个订阅的两个更新通知,这将不会很好地工作,因为 lastUpdate
在处理第一个请求之后才会更新。
解决这个问题的最佳方法是什么?我正在考虑使用某种缓存,但不确定如何使用。对于这类事情,是否有某种最佳实践?我猜这是一个常见问题:"receive notification, do something if something hasn't been done recently..."
恐怕这是个糟糕的主意,但是...也许值得为此方法添加锁?喜欢
private List<int> subscriptions = new List<int>();
然后
int subscriptinId = 1;//add calculation here
int subscriptionIdIndex = subscriptions.IndexOf(subscriptinId);
lock (subscriptions[subscriptionIdIndex])
{
//your method code
}
欢迎批评这种做法)
感谢this answer I went with the following approach, using MemoryCache
[HttpPost]
public void Post(IEnumerable<InstagramUpdate> instagramUpdates)
{
foreach (var instagramUpdate in instagramUpdates)
{
if (WaitingToProcessSubscriptionUpdate(instagramUpdate.Subscription_id))
{
// Ongoing request, do nothing
}
else
{
// Process update
}
}
}
private bool WaitingToProcessSubscriptionUpdate(string subscriptionId)
{
// Check in the in memory cache if this subscription is in queue to be processed. Add it otherwise
var queuedRequest = _cache.AddOrGetExisting(subscriptionId, string.Empty, new CacheItemPolicy
{
// Automatically expire this item after 1 minute (if update failed for example)
AbsoluteExpiration = DateTime.Now.AddMinutes(1)
});
return queuedRequest != null;
}