This year, I wanted to work remotely for a day or two in the week leading up
to Christmas. I went through the trouble of getting an RSA dongle and setting
up the terrible VPN software on my machine, only to discover that I couldn’t
access some resources that were within my company’s DMZ.
When I asked about this, the “official” response was that it was expected for
users to connect to an intermediary machine first, then connect to the desired
(restricted access) resource. Whiskey Tango Foxtrot! The problem here is that
I don’t have an intermediary machine.
This situation can be (mostly) solved by using SSH tunneling, which can take
network traffic directed at a local port, and send it to a remote port via
a man-in-the-middle server. In my case, I have access to an internal-only
webserver, which itself has access to the DMZ. The two tasks that I needed
to do on restricted server were HTTPS access (port 443) and SFTP access (port
22).
The -L option means we want to do local port forwarding, and -N specifies
that no command should be executed on the remote server. You could also add
-f if you want to put the ssh process in the background.
Run this command, and load localhost:3000 in your browser. Unfortunately, you’ll
see a “certificate mismatch” error message, because the SSL certificate doesn’t
match the URL. A hacky way to fix this is to modify your /etc/hosts file, and
add an alias (on a new line):
127.0.0.1 <inaccessible_server_url>
Then you can hit <inaccessible_server_url> as (almost) normal, the only difference
being that you have to specify port 3000 instead of the normal HTTPS port 443.
SFTP
Basically do the same thing as with the HTTPS setup, except change the remote
port to be 22:
Add your hosts alias, then modify your SFTP connection to hit port 3000, and
connect as normal.
(Note that adding the DNS alias only matters if you’re accessing the server via
URL; if you’re connecting via IP, you’ll have to change the server to localhost.)
A naive approach to running a Node application would be to start the process and
put it in the background. But what happens when it (inevitably) crashes? Give
PM2 your application configuration, and it will start the app and ensure it
respawns after a crash.
Normally you’d have to write your app specifically to take advantage of clustering,
but with PM2, you can just specify whether you want a single process or multiple processes. By default, it’ll spin up as many
workers as your CPU has cores.
While there are a number of sophisticated logging solutions for Node, at this point
in my usage of it I really only care about getting console.log statements and
stack traces written out to external files. By default, Node outputs these messages
to stdout/stderr, which PM2 will watch and write off to log files. You can easily
get a stream of logs using pm2 logs, or limit to one application using pm2 logs <appname>.
As with any web application that generates log files, after a while the files get too large and
unwieldy. PM2 has a command that will automatically generate a logrotate config
file that targets the default PM2 log location.
When developing, you have to restart your Node server in order to see changes.
Frameworks like Rails have a “development” mode they can use to re-load code
before each request, but with Node you’ll probably rely on something like supervisor,
which watches the filesystem of your project for changes, then kills/respawns
your Node process. Or you can just use PM2, which does the same thing.
This is a necessary evil that I’d wager many developers don’t think about,
similar to log rotation. Unless you create a custom init script, if your server
ever reboots, you will have to log in and restart the PM2 daemon. PM2 can generate
a startup script for you!
I haven’t used this aspect of PM2, but am hoping to soon. Instead of manually
SSH’ing to your server in order to do deploys, just use the functionality
built in to PM2, which will check out code from your VCS and (re)start the Node
process. It supports multiple server targets, as well as rollbacks.
When learning the code base of a new project, there are always places where
you look at what’s been written, and have a “WTF” moment. Normally, it’s best
to leave written code in place – if it ain’t broke, don’t fix it. However,
I let myself get a bit carried away with a recent project, and rewrote the
bulk of the server-side component. I thought I’d pull out a small example of
how you can take some verbose code, and condense it down to something more
readable.
In this example, we have an array of email addresses, some of which may be
prepended with the string "coordinator-". Why the original developer didn’t
just create two database columns, user_emails and coordinator_emails, I
can’t imagine. In any case, we want to send a message to the “non-coordinator”
email addresses.
Here was the original code:
var to = "";
for(var i=0; i<emails.length; i++) {
var email = emails[i];
if(email.indexOf('coordinator') == -1) {
to += email;
if(i != emails.length-1) to += ",";
}
}
to = to.slice(0, -1);
Straightforward enough, right? Create an empty string, and concatenate the
appropriate email addresses (include a separating comma), then remove the final
comma. So, if the emails array looks like ['bob@gmail.com', 'larry@gmail.com', 'coordinator-joe@gmail.com'],
the final output is the string "bob@gmail.com, larry@gmail.com".
But there’s an easier way to do this, and it involves being knowledgeable about
common Array manipulation methods. The first thing we want to do is remove any
email addresses that contain "coordinator-". Filter them out, if you will.
By Jove, there just happens to be an Array method named filter that we can use!
Next, we want to join the resulting email addresses together, with a comma between
them. What do you know? join is an Array method as well!
The whole thing boils down to one (long) line (pardon the ES6 syntax):
Recently I took the plunge and purchased a Happy Hacking Keyboard Professional 2.
Design
The first thing you notice about the HHKP is its small footprint. It is approximately
the size of a laptop keyboard, but the keys are full size. I purchased the
black version, which uses a dark grey plasic for the board/keys, with black
lettering on the key tops. Taken as a whole, it looks very attractive and minimalistic.
One thing to note is that the contrast between the keys and labels is very
slight, which might make it difficult to see in a darkened room. The textured
plastic also seems to attract lint, which mars the overall appearance.
Feel
The keys feel great; if you’re used to typing on modern Apple keyboards, the
key travel will feel almost excessive at first. I wasn’t sure what I would
think about Topre switches, but I think that I like
them; they aren’t really noisy, but have a deep, satisfying “thunk” when they
bottom out. The keycaps have a textured plastic on the top which is also very
pleasant to feel. I think that overall, the switches fulfill the requirement
I had for them, which was to provide moderately deep travel and not be too
loud for a cramped office space.
Compromises
Of course, the reason why the HHKP is so polarizing is that the designers
made some choices that not everyone will agree with. Probably the most obvious
is that there are no dedicated arrow keys; you have to press a modifier key
plus one of the [, ;, ' or / keys. If you’re a visual text editor
power user, this may very well be a dealbreaker for you. The only other real
annoyance I’ve found is the placement of the tilde (~) key, which is on the
upper right side of the board, above the Delete key. It’s very commonly used
in Unix-flavored systems (e.g. cd ~ will take you to your home directory), and
I have not gotten used to its placement yet.
Conclusion
Although it will only appeal to a subset of keyboard enthusiasts, I have
enjoyed using the HHKP. If you use a computer professionally, it’s definitely
worth your time to investigate other keyboards besides the one baked into your
laptop.
Finally getting around to making note of this here: I finished another simple
puzzle game a few weeks ago. It’s a hashi wo kakero implementation, called
“Let’s Build Bridges.” Check it out on the Ganbaru Games site.
It works great on mobile (Chrome/Safari) as well, so you can save it to your
device’s homescreen for fast access. Alternately, I put an IAP-enabled version
on iTunes,
so plz give me pennies.
Also, since trashing the Ganbaru Games dev blog, I needed something to put
there, so ended up making a faux smartphone-type interface.
It’s a bit spartan now, but will be fleshed out a bit as I slowly convert some
of my Javascript games over to using Arcadia.