Inspect Node.js With Grunt-SWATCH (!watch) And Fiveo

I know, I know… the socket in the cover picture isn’t really the type of socket we’re talking about in this post, but I’ve been preoccupied lately with the idea of building a new workstation and the ThreadRipper is a monster! I mean it might actually be the solution to never feeling like my computer is never fast enough no matter what I upgrade to using (right now it’s an Intel I7 8th Gen CPU). Every desktop/workstation I’ve ever used over the years (well there was one) has always left a lot to be desired. Waiting on your computer to COMPUTE sucks! Screen glitches, seemingly never ending progress spinners, lag time, and the like really break up productivity and workflow. Anyway on to the topic and away from the…

NodeBB (Node.js Forum) Hacking

As I’ve written about recently, my hacking time of late has been spent on the forum software NodeBB. The build process that the developers of NodeBB put into place relies on the Grunt task runner, which itself is also build with Node.js. It’s great when you can work within an ecosystem built primarily upon the frameworks you enjoy the most (for example Node.js ❤️) However when it comes to debugging, and when your build tooling and other layers of software are all built with Node.js, sometimes things get a little tricky. Like when you want to pass the --inspect flag to node executable to start a debugging session, having the intent of debugging your plugin code, and not the layers above it (Grunt, NodeBB). I am not aware of any command line options specific to the Grunt cli that can be used to pass your intent to start a Node debugging session down to the task level. I tried several things to no avail, however there were still a few options to get it done:

  1. Start the Node Inspector programmatically using the still experimental Inspector API
  2. Start the Node Inspector after the fact using Linux signals, SIGUSR1 to be exact.

Trade-offs

Of course, each of these solutions provided obstacles of there own, and as with most things included both positive and negative aspects! In this post I’ll talk about each of these solutions, detailing the issues I faced using each one. We will see how leveraging the Inspector API made the NPM module fiveo possible, and how that tool makes using Linux signals with Node.js even more powerful. And finally I will show how in the scenario presented herein, option #3 proved to be the best solution. And how choosing option #3 served as a catalyst to write the grunt-swatch plugin, what that plugin currently does, and what it could do with a little more work.

NodeBB’s Build Setup

I can’t completely explain the WHY of the Grunt flow that makes up NodeBB’s Gruntfile:

  • Further as we are working on a remote server, how do we handle port forwarding?
  • Do we really care about the intermediate inspector sessions?

Last Night!

So last night while I was writing this, I was starting to write that to be quite honest, I hadn’t given the inspector module much of a look before. And while doing so in the effort to write this post in the most informed manner possible, I was sent down a bit of a rabbit hole. One of which I emerged having written a tiny library that adds some sugar on top of the core inspector module, which as it turns out is pretty cool. Now, after having written said tiny library, I would recommend that instead of requiring the inspector module, one would be better off using fiveo which in turn does that for you, while adding some nifty features such as using a port other than 9229 sort of like this GitHub issue is about.

The Plan

The overall idea is that we can deliver the SIGUSR1 signal to the Node process specific to our code at the time we need it, and not before then, thus eliminating all the noise that we don’t care about. Noise like what NodeBB is doing during the init phase (remember it forks a bunch of stuff), or what the Grunt code is getting into, etc. The point that we’re ready to start the debugger is the point after Grunt does it’s init tasks, starts the NodeBB server, and the forum can be reached via the port it’s configured to run on tcp/45670. At that time we need to determine the process id that NodeBB is listening on, because we need a process id in order to deliver our signal to the appropriate place. Upon receiving the SIGUSR1, Node will start the inspector process and we can begin debugging!

grunt.loadNpmTasks('grunt-swatch')
pid=`netstat -lnp|grep 45670|awk 'BEGIN {FS=" "}{print $7}'|cut -f1 -d"/"'` kill -SIGUSR1 $pid