#emgee_schedule-update
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1304224867268300941
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
emgee_schedule-update
We've also updated the code to include all phase (even the ended ones) up to the current phase then our renewal phase. And we drop any future phases (or at least that is the intent), because right now we only want one future phase.
@bright marlin if it's a "race" then you would retry the request again with a new updated phase. No real way around it that I can think of if you are changing a past phase because of that race condition
It's unfortunately a known limitation of that API where you have to "re-pass" all the information instead of editing a specific phase and keeping the rest "as is"
I don't really get what you are doing and what race condition you are talking about exactly. I looked at that SubscriptionSchedule and you seemed to change the start_date from what it was no?
We are maintaining an explicit future phase for renewal purposes.
Customer can schedule a change in quantity or product.
Sorry that's a bit cryptic, you are talking about the future phase and I am talking about the current phase 0 you passed on update
We are not changing phase 0 as that is the current phase we need to pass in along with our future phase.
Phase 0 we get by fetching the schedule, getting the current phase from it and passing it along.
However, it appears that Stripe's engine has modified the schedule while we fetched the schedule.
It has injected some short lived phases.
So the schedule we fetched, extract current phase from is now stale and we're trying to update a schedule with a "current phase" that is no longer current.
I feel like you are changing phase 0 though. Look at https://dashboard.stripe.com/test/logs/req_tF3t4fD2gtWh0t though which is your first update. Phase 0 has start_date: "1731019525" but then you update again in https://dashboard.stripe.com/test/logs/req_cira0I9AWqmflu and it has a different start_date?
Take a look at this schedule: sub_sched_1QIeUTCi2Sw6UZ9JQpCgJFwl
I'm sorry, SubscriptionSchedules are the bane of my existence because they are so subtle and painful to debug. So if we talk in abstract, it won't really work. We need to focus on exact raw JSON response and what you pass back in
My current read is that you set start date to X and later update again and set to X+5
If you can pause and provide exact details like this that will help me debug further
That phase was extracted from the schedule
I feel you! I dislike schedules and phases immensely ๐
I am fairly sure you are not passing the right start_date. I see the exact "let's pass a new start date 5 minutes into the future from what it was" which is surprising me. You also seem to touch both the Subscription and SubscriptionSchedule in parallel which is confusing
Just to add, I can't reliably reproduce this error. The same sequence of actions doesn't always create the error. Hence me suspecting a race/resource contention related issue.
So the flow is: update the subscription to have a new quantity.
If that succeeds we then update the subscription's schedule with an explicit phase for renewal purposes.
Hence the two calls.
All good let's do this together. So you have that SubscriptionSchedule you did a create, one update, one failed update, one other update
In parallel of all of that you also updated the Susbcription itself in between those requests, which could totally cause phases to be created to reflect this
Ah, so we're also responding to webhooks which also modify the subscription. Usually it's wiping metadata.
TBH this is rather messy on our side and I've been trying to move things to be simpler and not relying on using Stripe as our database.
That's why you're seeing subscription updates interweaved as well. Sigh.
yeah but this likely explains the issue. You should be able to reproduce the problem more reliably if you are not just doing the SubscriptionSchedule update
I've seen this before. Like you are adding or removing a TaxRate id in one of those requests
Yep we are
and this could in turn cause the current phase to change because of it
Ah.
Yeah, our workflow is not great imo.
Ok, so we're shooting ourselves ๐
Got it.
Like imagine you have this:
- Subscription to $10/month with tax
- Create a Schedule
- Update the Schedule to keep that phase and add an extra phase to $33/month
- Update the Subscription to remove the tax
=> What โo you expect us to do here? Change phase 0? Change phase 0 and phase 1? Undefined behaviour?
that's the part that is so hard, because clearly we make a decision here, and I think that decision depends on what's changing which is likely why you weren't able to reproduce this each time. I don't even know myself what we really do.
I understand now. I didn't know that other subscription updates also affect (indirectly) schedule phases.
I always tells devs 2 things
- Don't rely on our magic behaviour, ask the behaviour you want -> so don't update the Subscription and hope the right phase(s) will be reflected on the Schedule
- Do your best to not touch the Subscription whatsoever if it has a SubscriptionSchedule attached to it
But saw the results in the phases being modified when I wasn't expecting them to.
Now this is still all an educated guess, but we can likely confirm quickly together if you are game to try, I can show you how I would do this
Yeah, I spoke to the team today about moving renewals out of schedule/phases as they are complex and magical. We don't control it either.
Yes please, if you have the time. Happy to learn.
Okay so what you started with is "someone is adding/changing my phases between the moment I retrieve and the moment I update". At first I assumed it was you (it almost always is) so the first thing I did was look up all the API Requests that touched that SubscriptionSchedule. I have my own tools internally but they mirror what's in the Dashboard. So I found the 4 requests I mentioned (creation, update, failed update, update) but that didn't add up to what you described
At first I assumed it was you (it almost always is)
I appreciate the candor here ๐
Now if something else is modifying the SubscriptionSchedule and changing its phases, it should generate a subscription_schedule.updated Event that shows exactly what changed in it. That's when it clicked for me. My tool shows
- 1
subscription_schedule.created - 5
subscription_schedule.updated - 1
subscription_schedule.released
Clearly there were more updated that I expected at first. That's when I went "huh" and I looked at each Event to figure out where they come from. I have tools for this (which I thank my teammate for building every day) and I noticed request ids req_123 that didn't match the request ids I saw above
That's where I then realized you were updating the Subscription in parallel
So now, we clearly see "something" is changing the SubscriptionSchedule. What we need to do is 2 things
- Look at each Event individually, check its JSON and find one where you go "a-ha, here someone changed that first phase!!!!"
- Once you have that Event (or multiple), find what caused the Event. In the Dashboard there's usually a
Sourcesection that points to the API Request causing it. We kinda changed a lot of this with Workbench and such so I don't really know what you see but if you share some screenshots we can get to what we need quickly
Thanks! I took a look and it's our webhook handler that's releasing the subscription. Like you said, it's us not you ๐
But I am pushing for us to move away from schedules/phases; at least for renewal handling purposes.
yeah the release is fine, but I am just explaining it all. What you were afer was one of those 5 subscription_schedule.updated and I want to show you how to read them and find them
They are too complex and we've been hit with issues (due to our integration with them).
(yeah I feel you, they are powerful, but too painful in my personal opinion :p)
I appreciate your help and input on this. Thank you
If you want to share a screenshot of those Events you see I can show you how to narrow it down quickly
This what you need?
yes okay so you have Workbench or the shell
So first at the top on the right you see that "source"
if you click on it it should open the API request log that caused that Event.
And second, that right panel has the "raw JSON" of the Event's content. So it has the raw SubscriptionSchedule's JSON. So you can look at it, and look at the previous_attributes hash that would be at the bottom. It's telling you what changed in that Event. And you can visually diff it to try and pinpoint "here, it changed phases[0].start_date, it was X before like I wanted and now it's X+5 minutes"
Yep got it. And from that I can see its our webhook event processor that triggered that API call based on the IP address attached to the API call ๐
So we shot ourselves in the foot. Nice.
and to be clear: this is almost everyone using Schedules, so definitely not just your mistake. It is not easy to handle "future updates" ๐ฆ
Thank you. I really do appreciate your help and directness. Thank you.
I want to move renewal handling into our service and not rely on Stripe's schedules. Too complex indeed.
I'm glad I could help!