Jira UI in Nodejs

Problem statement

See the problem statement in this post.

This post is about using NodeJS to write a program that implements a shell (REPL) to JIRA’s servers.

Implement the REPL

I implemented this REPL the same way the C version was made. I opted to not go for the “eval” option (as I did in Tcl) since it allows way too much flexibility for the end-user.

Code

Available here.

This code does as much as the C code does, but in 74 lines of code, compared to Ruby’s 60 lines of code. I didn’t stick to their standard library because even the nodejs website uses the “axios” library in their official howtos. I think this is ridiculous since nodeJS was built for networked programs, but it’s not too bad in the grand scheme of craziness from the JS community.

Thoughts and impressions

Nearly twice the RAM of Ruby

The C program used ~12MB of RAM. The Ruby program used ~25MB of RAM. The Nodejs program used ~43MB of RAM. Just like the other implementations, CPU usage was insignificant. I don’t understand why it needs to gobble up that much RAM. It bugs me, but it’s not the biggest fish to fry that’s come out of JS-land.

Amazing programmer productivity

I’m pleasantly surprised by how quickly this got built. And that’s including the random work I had to put in with figuring out that using STDIN and STDOUT involved some voodoo with “readline.CreateInterface”. JS is definitely not a language built for interacting with the standard POSIX interfaces. Still, plugging in ~5 lines of code to make that happen is pretty reasonable. Good job, Nodejs.

Promises

My intro to NodeJS was back in 2013 when it was truly the wild-west, and I was a very junior dev, and I couldn’t grok this stuff. NodeJS seems a lot easier now. I had to look up the promises API on MDN
for 5 minutes to figure out how to make this program behave the way I wanted it to. I was having trouble with the async nature of JS, and the prompt was showing up before the data was completely pulled from Jira. I was essentially have a race condition.

I slapped on a few Promises and that was sorted out. I think this is more a problem of me using Nodejs in a way it wasn’t intended to be used than a problem of Nodejs itself.

A consequence of using Promises because the async is in my face was that I couldn’t implement the main “event loop” like I did in Tcl, C, or Ruby. I instead called “get-command” recursively upon the completion of a Promise. This will eventually result in a stack overflow.

I know that async/await is a way to get JS programs to look sequential instead of async, but I’m not entirely ready to pull that veil in front of my eyes yet. I get the heebie-jeebies when I see code in language A (like Ruby) that has the feel or the flow of language B (like Java). I’ve seen this too many times in the last decade and never seen that be a pleasant experience. It’s better to accept and embrace the quirks of a language than pretend it’s something else.

Event-driven programs

I don’t have a problem with event-driven programs. Even Ousterhout (of Tcl fame) thought that events are a better tool than threads for most purposes. I like not having to deal with my program being pre-empted at any random time (more than it already does on modern OSes). I like the idea of cooperative multitasking as exemplified by Nodejs and basic Forth. I like not having to deal with deadlocks and shared-state synchronization.

But even event-driven programming is overkill for this program. A single-threaded non-concurrent system satisfies the needs of this program quite well, and I’ve got to write callback or Promise or async/await fluff to coerce the system to run sequentially. JS in general and Nodejs in particular, and their async paradigm, are well suited for networking and UIs, and I can see myself using Nodejs quite productively for a small networked application in the future.

Leave a Reply