处理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;
}