Browsed by
Tag: node.js

Who do we write code for?

Who do we write code for?

Recently, while reviewing some code, I came across the snippet below.

Now a keen mind can spot many issues with this.

The ones I am referring to are something specific and relevant to the business though. The code is supposed to fetch all active clients, loop through, get job specifications from some DataSources defined for those clients, build a config object and return those values to calling function so that those jobs can be fired. Interestingly DataSourceInstance, DataSourceOriginConfig and DataSourceJobConfig definitions have nothing named as triggers, report or client_id_internal! Moreover, destination_params is a property of Client object, not of DataSourceJobConfig. I could not make heads or tails of it. To top it, I was told the code is already working and tested, review is just a formality (like it usually is in many places).

When I started digging through the code further, I found that getDataSourceJobConfig, was accepting list of dsConfigs, but instead of returning a list of jobConfigs it was enriching objects in dsConfigs and returning the same list. Further digging revealed that the same was being done in both the methods above. Effectively, all these variables were the exact same list of exact same objects, mutated in every call, were actually the list of Clients!

Now, I understand that JavaScript is loosely typed, you can modify objects on the fly without adhering to any defined structure. But because one can, does not mean one should. This code was so cryptic that I was forced to ask the question: “Who have you written this code for”, and the answer was unexpected, “the clients who are paying for it”. I gathered courage and asked again, “What do you hope to achieve specifying these steps in code”, this time the answer was expected: “So the program does so and so”.

This is a question I always loved when I first read Clean Code by Robert Marin (Uncle Bob). The answer takes some thought, but once you realise it, it all makes sense. We write code to tell our team members what we are trying to instruct the machine to do. The primary consumers of the code, even before the destined machine are the author and the peers who see, read, understand, refactor and maintain the code. If all one wants is for the machine to get the message, then one can talk in binary, computer languages are for people to convey to each other what they want the machines to do, along with instructing the machines.

To prove this point I have built a small snippet (and a cryptic language) and compiler. Here it is, can you guess what this code does:

Before you say it is invalid, gibberish and would just fail, let me assure you that every word in that snippet is useful, and has an appropriate meaning for what it is doing. If I were to compile this and execute it, it will work. In fact I used this snippet in a presentation to make this very point, when it worked, the output was even more confusing. Now I would be lying if I said that the compiler just compiled the java like file, it also did some transformations, like ‘afdrukken’ (Google Translate says that is dutch for ‘printing’) was being replaced with System.out.println, as if it was a function similar to python’s print.

The point I am trying to make is that instructions to a computer can be given is many ways, we use ‘Computer’ languages, with meaningful constructs and words so we understand what others are trying to instruct the computer to do.

Even before it executes, the code is read first by the writer, is read often by peers and so the goal of the code is to get the intent correctly across not only to the computers but also to other humans.

We code first for humans and then for machines.

Yet another packager for node

Yet another packager for node

Yet another packager for node

There are so many packaging systems for node already, or maybe not as many, so here I am presenting another way to package your applications into an self extracting executable that has no dependencies. Ah well, a few dependencies, like the processor architecture, and Linux operating system may be, but that is all.

What is it?

It is a modified shell script originally used to create self-extracting and installing applications for Linux platforms. What it does is, it creates a tarball which includes your code, the modules it depends on, the specific node binary it uses, and appends it to a script with the command to execute your code. It is essentially a binary merge of the files, the shell script and the tar.This is not something new, people have used such a system in the past to deliver applications for Linux, every time you see an obscenely large ‘.sh’ file (for being that, a shell file) that can install or execute an application without requiring any other files, know that this is the packaging system being used.This script is merely an adaptation of it for delivering node.js programs. And to give where credit is due, is pulled and compiled from a few sources.

What all can it do?

  1. I have been hoping you would ask that, it is interesting:
  2. Creates a single file that starts your code when executed.
  3. Does so without requiring even node or node_modules installed on the target system.
  4. No knowledge of any framework required, develop your code just as you normally would.
  5. Allows you to name the process it starts. Well, it at least helps you to do so.
  6. Allows you to have environment specific overrides for any configuration you might want.

What can it not do?

  1. It requires to be bundled for the target platform, but this is expected, is it not?
  2. Does not work well when if module has binary/native dependencies, for when things like node-gyp or build-essential come into picture.
  3. Cannot make you fly (but it can make you look smart!)

Where is it? How do I use it?

Here. It is a simple command. To package, run:
./selfXpackager.sh -s node-bin/launcher.sh -n selfExeSample -b node-bin/node -m mymodule/ -o dist/
And to run the package:
../dist/selfExeSample_launcher.sh
That easy. The repository also has a sample project to try it out.

Where should I use it?

Well, how can I comment on that, it would be for you to decide! But I can tell how we use it. The company I work for, is primarily a java shop. Our system is quite distributed, composed of many services (I dare not say microservices, it is easy to start flame wars these days) that talk to each other. But ever since we realized the power of node especially in quick new developments that we do, we have leveraged it. We have much code in the form of monitoring and mock servers, automation and code generation tools and fault injection systems built in node. These systems are delivered, they do their job and are removed when no longer required.This is where the script comes in, a no dependency delivery of a tool wherever we need it. Instead of requiring node installed on all servers, we bundle our tool with this script and deliver to the servers we need them on, when the job is done they disappear without a trace. Well almost without a trace, it’s not some stealth tool anyway.