【问题标题】:Handle multiple similar requests in webapi在 webapi 中处理多个类似的请求
【发布时间】:2015-03-19 15:19:46
【问题描述】:

在我的 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 直到处理第一个请求之后才会更新。

解决这个问题的最佳方法是什么?我正在考虑使用某种缓存,但我不确定如何。这类事情有一些最佳实践吗?我猜这是一个常见的问题:“收到通知,如果最近没有做某事,就做一些事情......”

【问题讨论】:

  • lastUpdate 是否包含某种 id,可用于检查是否已收到该更新?如果是这样,请将其放入静态变量中,并在收到更新时始终对其进行检查。

标签: c# asp.net-mvc asp.net-web-api instagram


【解决方案1】:

感谢this answer 我采用了以下方法,使用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;
}

【讨论】:

    【解决方案2】:

    恐怕这是个糟糕的主意,但是……也许值得给这个方法加锁?喜欢

     private List&lt;int&gt; subscriptions = new List&lt;int&gt;();

    然后

     int subscriptinId = 1;//add calculation here
                int subscriptionIdIndex = subscriptions.IndexOf(subscriptinId);
    
                lock (subscriptions[subscriptionIdIndex])
                {
                    //your method code
                }

    请随意批评这种方法)

    【讨论】:

    • 是的,我真的不想锁定任何东西。我宁愿拥有某种对所有请求都是“全局”的缓存,并且我可以在收到更新通知后立即进行更新。然后我可以用它来检查我是否应该处理下一个通知。
    猜你喜欢
    • 2021-01-08
    • 2013-01-18
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多