#meteograms-subscription
1 messages · Page 1 of 1 (latest)
BTW my method works fine for a while, keeping metadata to 50 keys, (actually 49 with content and one space for new content with the next update). So the basic idea is fine. But then it suddenly starts failing because I somehow have 50 keys with content on your server.
Hi, I am not aware of such a batched behavior. Can you provide a request Id that failed?
Can you give a code example of what you are doing, like update 49 items and set 1 to blank?
let subscription = await stripe.subscriptions.retrieve(subscriptionItemId); const metadata = subscription.metadata; const maxKeys = 50; const keys = Object.keys(metadata); for (let i = 0; i <= keys.length - (maxKeys - 1); i++) { // can only remove a metadata key-value pair by setting value to ''... not by delete'ing the key... metadata[keys[i]] = ''; } // now add the new key-value pair... metadata[key] = value; subscription = await stripe.subscriptions.update(data.chargeTo.sub, { metadata: metadata } );
I can change the code to avoid the problem, but just trying to understand why it happens even with the above method. I am only ever writing one new key, and if I will be over limit then I also at the same time set the first one to blank. So it should always keep to the limit.
Here is a time sequence of requests when it started going wrong (and stays going wrong because of my incorrect assumptions): req_GtqUWQWTwCCCkm (OK), req_nNGRNBiFe9XgQ5 (OK), req_k8pZYoE0yWrX0k (not OK), req_f5lHUqxJDgLvxi (not OK)... etc
(I can see I can improve the efficiency by only sending two keys... one with the new content and one set to blank... no need to send key-values for all the ones staying the same... but it would still fail for the same reason)
for (let i = 0; i <= keys.length - (maxKeys - 1); i++)
Let's say if keys.length = 50
then you will run this loop from i = 0 to i <= 1, correct?
meanings i = 0 and i = 1
That means you set 2 keys to "", leave 48 keys in place, and add one more key, results in 51 keys as far as I am seeing 🤔
Yes but my assumption is that, with this logic, it will never get to 50 keys in the first place.
Should max out at 49.
Works great, until it doesn't.
Just trying to understand why it suddenly breaks, leaving 50 keys on the server with content... and then as you say it will thereafter always be trying to write 51 keys.
Perhaps it's just that the calls are asynchronous, so two updates in quick succession might both be successful, but leave 50 at the server?
Did you have some 2 calls at nearly the same time
Let's look at the last succeed request req_nNGRNBiFe9XgQ5
Is that the last mbur_1Je9loHkIcPWRyQ1e2dFAyiW is newly set one?
There are the times for the 4 requests I mentioned above
I have found mbur_1Je9loHkIcPWRyQ1FolB1Hfc in response which is not present in request
Looks like mbur_1Je9loHkIcPWRyQ1FolB1Hfc was in the request (and response) for the preceding update.
Looks like there were 2 requests that conflict with each other?
ah yeah
That exactly what happened
How can they conflict? If they are just dealt with in turn, then there is no conflict? E.g. { a: 2 } then { a: '' } isn't a conflict, just a new value.
Both of your requests had const metadata = subscription.metadata; with a same value of 49 metadata keys.
They almost fired at the same time
but when request 1 succeed, they actually append a new key 50, and erased the first key 1.
When request 2 reach Stripe server, they try to append a new key 51, and also erasing the first key 1
but in this time, Stripe server already acknowledged the change from request 1, hence it already had key 1 erased and the new key 50
Key 1 here is mbur_1Je50RHkIcPWRyQ1fmsra9i8
new key 50 is mbur_1Je9loHkIcPWRyQ1FolB1Hfc
Yeh OK. But dealing with this limit is awkward.
new key 51 is mbur_1Je9loHkIcPWRyQ1e2dFAyiW
Yeah what an edge case. TBH I think Stripe server can't know the fact there are multiple requests coming. You might have to dealing with this race condition with some kind of lock mechanism
Yep, will need to put my thinking cap on.
Easiest would be just to not live so close to the edge, and aim for a max of e.g. 40, to build in an overflow buffer, but it still doesn't solve the problem (e.g. if 10 requests are handled around the same time). Hmm.
You would need to constantly check the keys.length to see if it go over 40 and do some cleanup. I also not sure if that's the best idea
Technically you would want 2 requests wait for each other, so locking (semaphore/any similar mechanism) is what you would want. Also you can try to resolve the fact why there are 2 requests happenned
Maybe just wait for a response from stripe before dealing with the next one on my side... a queue of sorts.
Yeah a queue would work
OK I'll try it. Thanks for your patience and insight.