Open josephrocca opened 7 months ago
Also, minor point - in watcher
default options: "match": ["**/_._"]
- is this underscore syntax standard? I haven't seen that before - but it could just be due to my inexperience. I actually thought that "**/*.*"
would do the same thing. If it's special / non-standard syntax then it might be worth considering sticking to standard syntax if only for the benefit of e.g. IDE code autocompletion (but also for user expectations of course). If there are reasonable use cases that the standard syntax doesn't support, then maybe picking a different standard syntax would be better than extending an existing one with custom syntax.
(But again, maybe I just haven't seen this underscore syntax before - I'm not very experienced in this stuff.)
A lot of thanks for your support and this detailed feedback!!
I've focused very much on "getting it to work" and never really sat down and looked at the big picture, so this is exactly what i need to get it ready for 1.0!
Lots of great points here, and I especially agree with separating the system service from the processes in the way you described as "apps" vs "ecosystems" vs "processes", I will have a look at this asap 👍
About the ground truth for config, i reckon a ~/.pup
folder in the home directory could be used, with a ~/.pup/global.json
which could be used to track each configuration.
I'll review your feedback in detail and make changes as i find time. Thanks again!
Changes connected to next release are tracked in https://github.com/Hexagon/pup/pull/51
Generally speaking, in my context, I have been using a lot about deploy
feature.
https://pm2.io/docs/runtime/guide/easy-deploy-with-ssh/
From dev machine, we can deploy the code to the remote machine. This simplifies the use of a more robust deploy pipeline.
Just my two cents. Thanks for the efforts.
when I try exiting with Ctrl+C, sometimes it hangs
Let me tackle this one. I'll also refactor some code.
I'm not actually sure how I'm supposed to use
pup run
, since it runs in the foreground instead of starting all the app's processes in the background like I expected.
I saw that Hexagon has just renamed pup run
to pup foreground
. I'd like to propose this: revert back to pup run
, but make it run in the background by default. Only run in the foreground with argument -a
, like pup run -a
or pup run --attach
. That's how Docker works. I find run
prettier than foreground
as a command name. What do we think about that? FWIW, currently I run Pup in the background with $ nohup pup run > /dev/null 2>&1 &
.
Actually, i agree that pup run
is a better option... But had to give it a go :)
pup run
is back in it's original form from 1.0.0-rc.19
Open question; Should an instance have a name? The name could be pup by default, but could be set by passing --name to init or by being specified in pup.json through name:
.
The name would be used to ...
pup enable-service
~/.pup/global.json
pup <action>
anywhere without specifying --config
or --cwd
(by finding the configustion automatically though global.json)LGTM.
Just a few questions/remarks/drawbacks below. Basically my only concern is that I like to use Pup without installing it as a service sometimes and without the new global.json
. I'd like to still be able to do that because it's so simple, stateless, portable and unintrusive.
~/.pup/global.json
will only be created/updated the moment you run pup enable-service
pup --instance
if you don't install the servicename
in pup.json
after installing it as a service, the already installed service name is not changed, and pup --instance
is not changed either: they keep the old name from when you ran enable-service
. You have to reinstall the service in order to apply the new nameid
instead of name
so that it aligns with processes' id
? Not sure, thoughI'm not sure if this is already available, or on the roadmap, but just in case: one thing I use regularly in pm2 is pm2 reload
, which restarts processes in a cluster one-by-one for zero-downtime restarts.
(One slightly annoying thing is that it always restarts one-by-one, even if you've e.g. got 100 nodes in the cluster - so it can be much slower than it needs to be. I think it should be a percentage, like e.g. 10% at a time by default would make sense for my use cases, at least.
Also, I don't really like the naming reload
, since I always forget whether it's restart
or reload
that does one-by-one. Though I haven't thought about what a better name would be. Maybe just an option on restart
command.)
Awesome project! Thanks for your work on this. I'm in the process of attempting to switch from
pm2
topup
, and I thought it might be useful to share some thoughts given that it looks like you're heading towardv1.0
. Please take each of these suggestions with a grain of salt. And I'll pre-apologise here for any suggestions/thoughts that have stemmed from misunderstandings in the way Pup works.Confusion around
pup run
vspup start
andpup terminate
vspup stop
- and "apps" vs "ecosystems" vs "processes"Intuitively, here's how I think pup should work:
pup
sudo pup startup enable
or somethingpup.json
file in your app/server directorypup start
in the same directory to start app (and causes pup to track that config file - e.g. for startup stuff)pup stop
in that directory (or runpup stop the-app-id
), and it stops all the processes for that app/ecosystem (and untracks config file)Controlling individual processes within an app is something that should be possible, but (at least in my experience) is not as common, so it should not use up the precious/intuitive
start
andstop
commands. By far the most common commands I use withpm2
are start/stop/restart/logs, and they all apply to apps, not processes within an app.I think this is the most important change that should be made for
v1.0
. If the current CLI design decisions were made to support more complex use cases that I'm not considering here, then I think "simple things should be simple, complex things should be possible" might be worth applying here. Need to avoid making simple things unsimple in order to make complex things simple-ish. Instead, move the burden to people doing complex things, because there are far fewer of them, and they (basically by definition) have the time + skill to go a little deeper in the config docs, or whatever.The other huge advantage of this is that I think 90% of people will be migrating here from
pm2
, and IIUC this is basically howpm2
does it: https://pm2.keymetrics.io/docs/usage/application-declaration/ It's much easier to adopt new software if things work just like you expect - both intuitively, and from experience with related, popular software. Diverging from that is a cost that would need to give significant returns to be justified (Deno team realized this recently withdeno install
, for example). It's probably only worth diverging frompm2
in aspects where it's kinda confusing/bad.Also perhaps worth mentioning: With the current CLI commands, I'm not actually sure how I'm supposed to use
pup run
, since it runs in the foreground instead of starting all the app's processes in the background like I expected. Also, when I try exiting with Ctrl+C, sometimes it hangs:and I need to close the terminal to actually stop it. Other times it exits fine. But in both cases the
pup status
tells meNo running instance found.
.Where is Pup's "ground truth" for config?
IIUC, the
pm2 save
command snapshots the configs and uses that saved snapshot to e.g. determine whether an app should start on machine startup. I'm wondering howpup
handles this? Thepm2 save
command was always a little bit confusing/annoying to me. Ideally, in my mind, pup would use the actual config files in the app directories as ground truth. Sopup start
would just add that config file's path to pup's internal "known config files" list, which it uses at machine startup to fetch the actual config file contents, and determine whether the app should be started. And I thinkpup stop
should remove the config file from pup's internal "known config files" list.There are tradeoffs here, but I think I would prefer if
pup
held as little "internal state" as possible - so I can just e.g. edit the config file and runpup restart
in the same directory, and I know that I'm editing the actual "ground truth" that Pup is using.I think there's a temptation here to, for example, not bundle pup's untracking of a config file with
stop
-ing the app because that's not always what would be desirable - but I'd appeal to the "simple things should be simple" principle again here - it's easy to add some extra (more "granular") commands likepup track
andpup untrack
, or whatever, which can be used in cases where devs are heading off the beaten path.Document a few of the most common/useful commands in readme
E.g.
pup status
,pup logs
- a quick dot-point list of these in the readme as part of the "quick start" would have been handy for me to quickly get the rough idea. And maybe add a final dot point linking them to e.g. https://github.com/Hexagon/pup/blob/main/docs/src/usage/index.md for the rest of the commands.Document configuration defaults
This page: https://pup.56k.guru/usage/configuration/#general should have the defaults for all options documented. This one is pretty important I think. It'd also be worth mentioning a few of the most important defaults in the readme I think.
Related: I love opinionated defaults that make it easy for people to get started, but I'm a little bit weary of "overly specific" defaults like
watcher.exts = ["ts", "tsx", "js", "jsx", "json"]
which might not be very future proof. E.g. could probably add yaml, json5, etc. to that - there's a long tail. It might be best to just watch all extensions by default, but I'm not confident what the best approach is here. Current defaults are not unreasonable, but worth thinking about in terms of forward compatibility and future breaking changes.pup logs
should stream by defaultI use
pm2 logs <all|app-id>
on a daily basis - it's very handy to have logs streaming in my console as I'm coding, so I can e.g. see errors during startup after saving the file, or see live logs on a production server.Can
console.warn
be made orange in logs?I've wished for a long time that
pm2
did this. It sounds like a small thing, but I really appreciate that Chrome's devtools does this when I'm remotely inspecting a Deno/Node process. I just wish it were possible for terminal logs to make a visual distinction between warnings and errors. That said, I'm guessing it might not be possible due toconsole.warn
maybe just being a stderr log without any distinction fromconsole.error
at the level at whichpup
"sees" those logs.A log file with errors and normal logs interspersed
Another annoying thing with pm2 is that (AFAIK) I'm not able to see a log file that has errors and logs interspersed. The reason this is annoying is because the logs that came before an error are often quite relevant to the cause of the error. So, while debugging, I end up needing to switch back and forth between them and rely on timestamps for aligning them.
Switch from JSONC to JSON5, or support both
I hadn't heard of JSONC before - maybe I'm just out of the loop on that. I have used JSON5 before though, and seems to be more commonly used?
JSON5 is nice because you don't need quotes around keys like with JS POJO declarations - makes config files really clean.
Move
.pup.jsonc-tmp
,.pup.jsonc-data
, etc. into.pup
This reduces clutter - especially if more pup-related files are needed in the app directory in the future.
Densify
pup status
, add colors for skimming, and num restarts + uptimeFor
pup status
, "number of restarts" and "uptime" would be handy, and pm2-style density with skimmable (green=good) would be awesome:Rather than having a separator between rows, I mean. I also think
pm2 status
could be made a lot more dense - e.g. by using emojis (which work fine in terminal, of course) for boolean/enum fields like status, watch, etc. The denser the better imo.Also, I think
pm2
's "cpu" column is kind of useless since IIUC it's the CPU usage at that exact instant - it'd be much more useful for me to see average or total CPU usage over the last 30 minutes, or something.Please don't feel the need to reply to all/any of the above points. I just hope that these thoughts have been at least somewhat useful. Thanks again for all your work on this!