Skip to content
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

chore(cli-storybook): Add telemetry #8803

Merged
merged 8 commits into from
Jul 20, 2023
Merged

Conversation

Josh-Walker-GM
Copy link
Collaborator

Instruments the storybook command with telemetry. I had forgot about it since it lives in it's own package now.

WIP
I had to add an empty SIGINT listener for execa to exit and the process.on exit to trigger. I'll need to understand why...

I had to add an empty SIGINT listener for execa to exit and the process.on exit to trigger. I'll need to understand why.
@Josh-Walker-GM Josh-Walker-GM added the release:chore This PR is a chore (means nothing for users) label Jul 1, 2023
@Josh-Walker-GM Josh-Walker-GM added this to the v6.0.0 milestone Jul 1, 2023
@jtoar
Copy link
Contributor

jtoar commented Jul 4, 2023

@Josh-Walker-GM I know we tested it locally, but I'm not sure that registering on process.on('exit') is enough for SIGINT; the Node.js docs say...

The 'exit' event is emitted when the Node.js process is about to exit as a result of either:

  • The process.exit() method being called explicitly;
  • The Node.js event loop no longer having any additional work to perform.

Source: https://nodejs.org/dist/latest-v18.x/docs/api/process.html#event-exit.

We could call process.exit in process.on('SIGINT')'s handler. But I also don't like calling process.exit explicitly if we don't hae to. I know it was somewhat necessary for deeply nested functions, but I'm not sure if that's the case here yet

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious why we record attributes twice?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to record the command name inside the middleware because it might not have been recorded in the handler is if the check had throw an error.

We probably don't need the command: 'storybook' in the handler recordTelemetryAttributes since it'll be set by the middleware. I kept it there mainly to just be consistent that all handlers set the command name.

Trade off here. Checks must work but when they do we get no automatic indication on the telemetry that the command failed.
@Josh-Walker-GM
Copy link
Collaborator Author

Josh-Walker-GM commented Jul 4, 2023

@Josh-Walker-GM I know we tested it locally, but I'm not sure that registering on process.on('exit') is enough for SIGINT; the Node.js docs say...

The 'exit' event is emitted when the Node.js process is about to exit as a result of either:

  • The process.exit() method being called explicitly;
  • The Node.js event loop no longer having any additional work to perform.

Source: https://nodejs.org/dist/latest-v18.x/docs/api/process.html#event-exit.

We could call process.exit in process.on('SIGINT')'s handler. But I also don't like calling process.exit explicitly if we don't hae to. I know it was somewhat necessary for deeply nested functions, but I'm not sure if that's the case here yet

Thanks @jtoar this was definitely something I was coming back to since this PR highlighted the weird SIGINT behaviour.

I've read over more of the node docs and this was particularly helpful:

'SIGTERM' and 'SIGINT' have default handlers on non-Windows platforms that reset the terminal mode before exiting with code 128 + signal number. If one of these signals has a listener installed, its default behavior will be removed (Node.js will no longer exit).

I tested to ensure that the default exit causes by SIGINT does not trigger the process exit event - it does not.

Taking a step back and looking at our requirements might be useful. We must have the telemetry shutdown fire before the process exits. This is achieved by having it called on the process exit event. We know now that we must ensure node's other mechanisms of termination trigger the process exit event.

It would seem to me then that the best course of action would be to provide listeners on the SIGINT and SIGTERM which call process.exit. However, I agree that this is not optimal since we may have circumstances where we don't want SIGINT to immediately call process.exit. My suggestion then would be to have these default listeners for SIGINT/SIGTERM only call process.exit when no other listeners are registered on those events. Something like:

process.on('SIGINT', () => {
  if(process.listenerCount('SIGINT') > 1){
    return
  }
  process.exit()
})

That means we're free to have custom behaviour for these events where we need them. If we do this then I can't think of a way in which node exits without a call to process.exit or just gracefully when it's got no other work left.

There are still some signals where we don't have the power to intervene on like SIGKILL.

Lastly, also from the docs:

'SIGHUP' is generated on Windows when the console window is closed, and on other platforms under various similar conditions. See signal(7). It can have a listener installed, however Node.js will be unconditionally terminated by Windows about 10 seconds later. On non-Windows platforms, the default behavior of SIGHUP is to terminate Node.js, but once a listener has been installed its default behavior will be removed.

We'll probably want to include this default exit behaviour for SIGHUP too. Making sure we exit within the roughly 10s grace period windows would give us - likely not a problem.


EDIT: Pushed up what I was talking about for an example.

@Josh-Walker-GM Josh-Walker-GM marked this pull request as ready for review July 19, 2023 23:27
@Josh-Walker-GM
Copy link
Collaborator Author

Okay I think this is ready now @jtoar but I'll take another look over this with fresh eyes tomorrow to check.

Copy link
Member

@Tobbe Tobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested this code, but just reading it it looks good to me

@jtoar jtoar merged commit d14432b into main Jul 20, 2023
@jtoar jtoar deleted the jgmw-cli/storybook-telemetry branch July 20, 2023 19:07
jtoar pushed a commit that referenced this pull request Jul 20, 2023
Instruments the storybook command with telemetry. I had forgot about it
since it lives in it's own package now.

**WIP**
I had to add an empty SIGINT listener for execa to exit and the
process.on exit to trigger. I'll need to understand why...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release:chore This PR is a chore (means nothing for users)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants