我在几天前列出的 Shopify 应用上遇到了一个大问题。我的应用程序的核心功能是访问 Shopify API 端点以多次编辑 draft_orders 的端点。我完全清楚每分钟 40 个请求的速率限制和每秒 2 个请求的刷新率。
奇怪的是这些失败请求的时间戳:
PUT https://****.myshopify.com/admin/draft_orders/124016722005.json [429] 09:09:16
PUT https://****.myshopify.com/admin/draft_orders/124016722005.json [429] 09:09:18
PUT https://****.myshopify.com/admin/draft_orders/124016722005.json [429] 09:09:23
PUT https://****.myshopify.com/admin/draft_orders/124016722005.json [429] 09:09:31
PUT https://****.myshopify.com/admin/draft_orders/124016722005.json [429] 09:09:47
PUT https://****.myshopify.com/admin/draft_orders/124016722005.json [429] 09:10:19
所有这些都返回:
Error code: 429 (Too many request)
Error message: REASON: Exceeded 2 calls per second for api client. Reduce request rates to resume uninterrupted service.
Copy
如您所见,第一个失败的请求和最新的请求之间有超过 1 分钟的时间。所以我完全不知道是什么导致了这个问题。
编辑
我想我可能发现了问题。我(错误地)假设用户只会发出一个请求并等待该请求完成,然后再发送另一个请求。因此,这是我在端点中的代码:
const handleGetRequest = async (req, res) => {
const {shop, accessToken} = await Shopify.Utils.loadCurrentSession(
req,
res
);
const client = getShopifyClient(shop, accessToken);
// do stuff with Shopify client
}
在哪里getShopifyClient
:
const getShopifyClient = (shopName, accessToken) => {
const shopify = new Shopify({
autoLimit: { calls: 1, interval: 1100, bucketSize: 30 },
shopName: shopName,
accessToken: accessToken,
});
shopify.on("callLimits", (limits) =>
console.log(
`CURRENT API LIMIT STATE: ${util.inspect(
limits,
false,
null,
true /* enable colors */
)}`
)
);
shopify.on("callGraphqlLimits", (limits) =>
console.log(
`CURRENT API LIMIT STATE: ${util.inspect(
limits,
false,
null,
true /* enable colors */
)}`
)
);
return shopify;
};
现在我意识到,每次我收到新请求时,这段代码都会创建一个 Shopify 类的新实例(尽管来自同一个用户,具有相同的商店名称和访问令牌)。
如果是这种情况,getShopifyClient
如果我发送相同的商店名称,是否可以记住返回相同的实例?像这样的东西:
let memoizedClient = {}
const getShopifyClient = (shopName, accessToken) => {
if (memoizedClient[shopName]) {
return memoizedClient[shopName]
}
const shopify = new Shopify({
autoLimit: { calls: 1, interval: 1100, bucketSize: 30 },
shopName: shopName,
accessToken: accessToken,
});
shopify.on("callLimits", (limits) =>
console.log(
`CURRENT API LIMIT STATE: ${util.inspect(
limits,
false,
null,
true /* enable colors */
)}`
)
);
shopify.on("callGraphqlLimits", (limits) =>
console.log(
`CURRENT API LIMIT STATE: ${util.inspect(
limits,
false,
null,
true /* enable colors */
)}`
)
);
memoizedClient[shopName] = shopify
return shopify;
};
你怎么看?