server.js: Add optional <profile> cmd line arg#4452
Conversation
Codecov ReportPatch coverage has no change and project coverage change:
Additional details and impacted files@@ Coverage Diff @@
## main #4452 +/- ##
==========================================
+ Coverage 88.70% 88.73% +0.03%
==========================================
Files 285 284 -1
Lines 25682 25643 -39
Branches 6914 6898 -16
==========================================
- Hits 22780 22755 -25
+ Misses 2698 2684 -14
Partials 204 204
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
|
I see, so the use case here is:
That seems like a fine use case to make easier. FWIW, |
|
That doesn't mean that samply can't be modified to support unsymbolicated profiles, but I did get the impression that samply was mainly an internal tool. I don't really expect a profiler user to have much trouble compiling samply though, even with the out-of-date rustc in Ubuntu 22.04. |
|
That doesn't mean that samply can't be modified to provide source code for unsymbolicated profiles ... sorry about the confusion |
For now at least, and because a development build is good enough for me right now. This pr might or might not be abuse of a dev server. |
|
Just to clarify, what I meant to say is that I approve of the approach in this PR. (But I'll leave the code review to Julien or Nazim.) As for making the source view work for JS profiles in a secure way, I'm curious about your solution, and we can discuss it later in a separate PR about it. |
Thanks! Admittedly, it was hard to determine whether you were being sarcastic or not 😅
It probably will just involve the user ensuring that the server is on 127.0.0.1 and not 0.0.0.0 or a public IP address. |
julienw
left a comment
There was a problem hiding this comment.
Thanks for the patch!
I'm not a big fan of the approach but if that makes your life easier I'm not against it.
It would be good to update the contributing doc, for example part 2 in this paragraph could be the right location.
Looking at your initial description I'm thinking that because you're using a shell script already, maybe you could expose your local directory directly using either python's http.server or the local-web-server node module (that we already have installed in the profiler project as node_modules/.bin/ws) in background, then start our server in background too, and finally open the firefox window using the URL from this server.
But maybe another vision is that it's what our server.js should do for an easier development environment, and that's why, again, I'm not against this PR. So happy to move it forward!
| y18n "^5.0.5" | ||
| yargs-parser "^21.0.0" | ||
|
|
||
| yargs@^17.6.2: |
There was a problem hiding this comment.
By running npx yarn-deduplicate this merges the too yargs 17.x entries, so this reduces the amount of new packages.
| ); | ||
|
|
||
| const argv = yargs(hideBin(process.argv)) | ||
| .command('* [<profile>]', 'Open Firefox Profiler, on <profile> if included.') |
There was a problem hiding this comment.
I believe we don't need the * because this is useful to run the command by default -- but that's not the case here. (although the doc is misleading so I'll let you double check my affirmation).
Also, specifying both [] and <> which both have some specific behavior is recipe for future disaster when they'll change their internal iomplementations, so I'd suggest to use just [] which seems to be the one we want really here. Tell me if I'm wrong here too :-)
| .command('* [<profile>]', 'Open Firefox Profiler, on <profile> if included.') | |
| .command('[profile]', 'Open Firefox Profiler, on [profile] if included.') |
There was a problem hiding this comment.
On yargs 17.6.2, omitting the * doesn't work -- without it, yargs refuses to process a profile arg that is given on the command line. I did think about using open instead of the default command, but I don't see any other function for server.js other than to (eventually) open profiles.
Sorry about the <>, initially the profile arg was required, and I just slapped on the [] as it seemed the natural thing to do, without looking at the documentation. Thanks for the catch!
| express.static(path.resolve(path.dirname(argv.profile))) | ||
| ); | ||
| return middlewares; | ||
| }; |
There was a problem hiding this comment.
I'm not a big fan of this solution, because 1/ this exposes a full directory (even though you're doing some filtering), 2/ this plugs into the dev server which might not work anymore in the future, 3/ this moves away from my longterm wish that we get rid of server.js at all in favor of using webpack serve directly (not sure if that will be possible though).
What about creating a separate server using node's http.createServer that would serve just this profile data?
This could look something like this:
if (argv.profile) {
// Spin up a simple http server serving our file.
const profilePort = 4241;
const profileHostname = "127.0.0.1";
const server = http.createServer((req, res) => {
const fileStream = fs.createReadStream(argv.profile);
fileStream.pipe(res);
});
server.listen(profilePort, profileHostname);
const profileFromUrl = `${profilerUrl}/from-url/${
encodeURIComponent(`http://${profileHostname}:${profilePort}/`)
}`;
// Close the server on CTRL-C
process.on("SIGINT", () => server.close());
process.on("SIGTERM", () => server.close());
// Keep the rest of your code
....
}Then in the future we can easily extract this to another file and use it elsewhere.
What do you think?
There was a problem hiding this comment.
I think that any reduction in dependency on the (possibly capricious) internal behavior of webpack-dev-server is a good thing, and I've integrated the code above (279453c). Changes include:
- The port for the profile server is OS-allocated instead of fixed.
- The host for the profile server is the same as for the webpack server.
- CORS handling.
- The
openpackage is now an explicit dependency.
For consistency, the options in serverConfig.open are honored. Theoretically, the port for the webpack server can be OS-allocated as well but that should be in a different PR since it might be complicated.
Co-authored-by: Julien Wajsberg <felash@gmail.com>
b8d494d to
f44d606
Compare
3b0f0c9 to
279453c
Compare
I have added the shell script I'm using to |
…nto server.js-profile-arg
|
Okay I think that's it. |
…nto server.js-profile-arg
|
Hey! Just a quick note that we've seen your update but just didn't have the chance to look at it during this week. It's still on our radar, thanks for your patience! |
|
No worries :) I see that you have a lot on your plate. |
julienw
left a comment
There was a problem hiding this comment.
Thanks for your patience!
I'm still not 100% convinced to have this as part of the server.js file. Indeed this would work only when the server isn't running yet; if it's already running, this would just fail. I feel like that a standalone nodejs script that would:
- spawn a local server like you did already
- open the profiler with a
from-urlURL properly filled in
would be more interesting.
This would have the following features:
- support --release and --dev to decide whether to open profiler.firefox.com or localhost:4242
- in the case of --release, we need a https server. So maybe a first implementation wouldn't support this case.
- In the case of --dev, it would be good to check if the server runs already; if it doesn't run then in that case launch
yarn startin the background first.
that said I'm fine with landing your patch as it is with the small comments fixed :-)
| @@ -0,0 +1,16 @@ | |||
| #!/bin/sh | |||
| # This script is primarily for running Firefox Profiler on a saved profile. | |||
There was a problem hiding this comment.
Can you please add a few examples about how to use it in the comments here?
There was a problem hiding this comment.
Also what do you think about naming this file launch-fp.sh so that it's more obvious about what it does?
There was a problem hiding this comment.
| > `https://profiler.firefox.com/from-file/` | ||
|
|
||
| When you're on [the home page](https://profiler.firefox.com) files can be loaded by either dragging over the profiler.firefox.com client, or using the file upload input. | ||
| When you're on [the home page](https://profiler.firefox.com) files can be loaded by either dragging over the profiler.firefox.com client, or using the file upload input. On Linux, the provided [fp.sh](../bin/fp.sh) script can load files. |
There was a problem hiding this comment.
I feel like this addition should be in another paragraph though. Indeed we're really talking about the from-file datasource here.
What about moving this doc in the URL part above, below the part Here is an example profile server written in Node.js::
Note that if you have a copy of the project locally, you can simply add the file path as a parameter to
yarn startand a server serving this file will be spawned for you. On Linux, the provided launch-fp.sh script can do this for you as well, from any working directory.
There was a problem hiding this comment.
Not sure whether I should have been pestering you lol.
The plan is to put down somewhere a port-specific flag file when the server starts and then to check that file on script start to see whether a server is running. Since the file might not be cleaned up if the server crashes, the user should be informed whenever a relevant flag file is detected.
This might cause code duplication but it apparently makes it easier to switch dev servers if needed so sgtm. |
It seems a bit tricky to pull out the following code: Lines 94 to 108 in 69ed07f into that standalone nodejs script since it might require modifying the local |
|
"by this week" unfortunately has become "delayed indefinitely" but not losing hope that the above will eventually be resolved |
This pr adds a one-shot way via server.js to run Firefox Profiler with a local profile file. It can be used in tandem with a shell script like the following:
I have seen and run samply and I think that:
webpack.local-config.js.Note that I have nothing against samply, Rust, or the people working on them. I am quite happy with putting all this in a private fork or unmaintained public fork. If this pr was accepted, it would be somewhat harder to switch to a dev server from another package e.g. Vite, though probably not impossible.
Future work for this would include:
If you have read this far, thanks for the attention!