-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stepper: calypso_signup_start
event can be triggered multiple times, despite tests saying otherwise
#94175
Comments
cc @daledupreez @gabrielcaires can you please confirm? If I'm misreading things or you see anything that I don't. Is this on your plate to fix otherwise? |
@chriskmnds It is an issue we should fix. As far as I know, we will only have one calypso_signup_start event. We also have an issue here: #93950 to fix it. Let me know if you want to fix it, or I can fix it. I think you found the root cause. |
Coming up with a right/wholistic solution seems rather difficult. I've outlined the same issue elsewhere here: #93983 (comment) Can you reply there or here with your thoughts? There may other causes, but these are indicative of at least one issue that exists (some state being updated in the hooks being consumed) |
I totally agree; we have conflicting ideas. Idea 1: Expectation of having events triggered once by flow I think the "ideal" solution really involves the concept of a session and enabling a flow to add parameters without necessarily triggering the event. Something like:
const {session} = useFlowAnalyctisSession();
session.set('anyCustomParams', 'anyValue') // New Prop will be used by all subsequent track events;
// or
session.set('anyCustomParams`, 'anyValue', 'calypso_signup_start') // New Prop will be used only when stepper trigger the `calypso_signup_start` . It is something similar Google Analytics does with the user-scoped dimensions. https://www.analyticsmania.com/post/user-scoped-custom-dimensions-in-google-analytics-4/ It is just my first thought about the problem. What do you think? |
@gabrielcaires I like where you are going with this. I think the difficulty lies in the details. I think the problem is not how we get the data, but when and from where. If the data/props originate from state, then one way or another changes in that state would need to be reflected at the point where we trigger the event (if this is what we want - so, unless we purposefully ignore). This is the main problem (as well as whether we do indeed want the latest state to be recorded always).
I'm not sure if "session" will be any different in this case, but I may not have understood your idea in full. Unless we intend to delay the triggering of
Ok. If I understand correctly, you may be looking at some form of queuing service? Not sure how we'd solve this. We could develop something like that, but I'm not sure I see where "session" comes in. For example, instead of calling
Feel free to clarify with more details. I may have misunderstood something :-) p.s. I mentioned above:
I think this is also critical, but may be "overthinking". For example, |
@chriskmnds I think I didn't expose the idea well; let me try to prepare a POC to see how it works. Before that, I prepared a PR fixing the issue only for this event |
@gabrielcaires Can you not explain with a bit of pseudo code? Just as long as we don't start investing into some implementation that we'll have a hard time backing out of. As you like though - happy to discuss. :-)
I replied in a review there. I might be missing something, but see no difference from just ognoring the dependencies? I can take a closer look tomorrow, but pls feel free to clarify. |
Hello @gabrielcaires @chriskmnds 👋 I apologise for the random interjection, I stumbled on this PR while chatting with Travis and Seah about the overall Stepper/better Tracks initiative. I was struck by:
I was wondering whether the expectation of having events triggered only once is a hard one or can be relaxed for the next version of Stepper to allow the dust to settle on the various other aspects of the rollout across the various steps that will be replaced? As a (bit rusty) developer it feels like it might get quite complicated to handle all kinds of corner cases where events should or shouldn't fire twice, which might also depend on the semantics of the specific step/flow, user actions, etc. so I thought I might bring this up in case given all you learnt so far it makes sense to step back and reassess the pros and cons of this particular requirement. |
Hello @MicBosi
This is quite a solid observation and I'd be thinking the same. You summarised it pretty well. I too find it unlikely to be able to control everything and all edge cases. I'd leave it on the data folks to tell us why the limitation needs to exist. It sounds like something we should be able to control on the analysis side. If we intentionally let events be logged multiple times so that whatever semantics are in place (e.g. async queries or whatever) are allowed to settle on their final values. @travisw what's your take on the above, what @MicBosi mentioned? |
I think it depends on exactly what we're trying to control and when, which I'm not entirely clear about. If we're trying to ensure a particular event is only fired once at all costs, like even if the page is refreshed or the user clicks the back button, then I don't personally think that's necessary. It could even make the data less intuitive and the flow events more difficult to test. If we're talking about not firing an event more than once when it seems like it shouldn't actually fire, like on some random step of the flow (like firing a start event after the flow has started), or multiple times for a single step, then I think it's worth trying to minimize that. For example, imagine this was a simple old-skool, non-JS application, that ran everything synchronously and every page required a full page load. Intuitively, I'd expect it to work similar to this. If you load a page the event fires. When you load the next page the event for that page fires. If you click back the first event fires again. If you refresh the page the event also fires again. Each step just fires the events they're supposed to at the appropriate time. Anything more, like trying to keep track of which events have fired in the context of the entire flow and then not fire them in some cases seems overly complex and not necessary. |
@travisw Thanks for the follow-up above. It makes sense. Stepper is a full React-based framework, and almost always any scenario is simpler when it stays close to the regular life cycles enclosed. I'll comment with a question on one point from above to help orient myself better:
If we have a Stepper step firing off the same The guarantee is that the step will record everything that exists within its life cycle, and not beyond. The same would hold for I'm just asking - I know it may look weird for analysis if you have However, if we relax the condition, then the
As anything else based on the internal state in the hook. It's a dreadful design if this hook is ignored from dependencies internally. |
Hey @chriskmnds - thanks for the added details. One thing that's on my mind is that in order to get unique instances of events per user, we'll often limit queries to the first occurrence that's fired for a user within some time windows. If that first event has incomplete props then we might not be getting all the details we need. Off the top of my head I'm not sure how we'd determine that a particular record is the final version of the event that might be more complete. Especially if the user refreshes or goes through another flow. Since we're talking in somewhat abstract terms it's a little hard to tell if this all matters. Maybe the multiple events won't actually be a problem. Do you have a more concrete example of what prop values these multiple events might contain? Say we're expecting the event and props: If we get first occurrence of the event for this user, do you think there's a good chance that that record won't have the values for those props that we expect? At least for the core signup events, we're not so concerned with all the extra props that flows might choose to include in an event. We'd mostly want the common ones like those mentioned above and probably a couple others. |
@travisw I think my perspective is roughly summarised in a couple of comments I made elsewhere: #94248 (comment)
I used
The core of the idea though is to "allow" flows to be "silly" - meaning, let flows attach any variable value as a prop to events that are really meant to be momentary (like
These will log correctly irrespective of relaxing the restrictions or not. They are mostly either static or immediately compiled when called (no state-changing anywhere on I will start a couple of PRs where these will be recorded multiple times:
The order won't matter / stay the same. So if you target the first instance given a step or flow (however you do that - as you mentioned), then you get exactly same results as now. cc @Automattic/vertex @gabrielcaires @MicBosi |
Closing this as agreed to allow events to be recorded multiple times if that's what the flows define. The direction is summarised in the comment here: #94175 (comment) |
Details
In Stepper, the
calypso_signup_start
event is supposed to be recorded once per signup flow. The logic for handling the tracking lives in use-sign-up-start-tracking, with accompanying tests.One of the tests specifically tests for "does not trigger the event on rerender", which is kinda odd seeing that
useSignupStartEventProps
returns a new reference{ extra: 'props' }
on every rerender, and there's no logic for blocking or ignoring that dependency inuseSignUpStartTracking
.The test is misleading/wrong.
toHaveBeenNthCalledWith
checks that we have that set of arguments on the "Nth" call. We have more than one calls here though.Here's a PR where I've updated the tests to show the true number of times the event gets recorded (it's
2
, and3
if we also passsignup
param): #94174cc @Automattic/dotcom-stepper
Checklist
calypso_signup_start
onceRelated
No response
The text was updated successfully, but these errors were encountered: