Saturday, November 3, 2012

Module Caching in Node.js

There was an interesting question on stackoverflow about whether singletons can be implemented in Node.js  via modules: Singleton pattern in nodejs - is it needed?

Ignoring any discussion about the singleton as anti-patterns, the question comes down to how Node.js caches modules.

The Node.js docs for Module Caching & Module Caching Caveats state:
Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file. Multiple calls to require('foo') may not cause the module code to be executed multiple times. 
Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading from node_modules folders), it is not a guarantee that require('foo') will always return the exact same object, if it would resolve to different files. 
"may not" and "not a guarantee" bother me -- under what circumstances will require('foo') not return the same object?

Turns out to be pretty simple: If the foo in require('foo') resolves to the same file in the filesystem (excluding hardlinked files), the same object is returned. If foo resolves to different files, in different directories, then each would be loaded/executed/cached individually.

Under the hood, fs.realpath is used to resolve the canonicalized absolute pathname to the file -- this means that symlinks to a file all resolve to the same file.

Monday, October 29, 2012

Google Analytics and development/staging/production servers

It's common (best practice, actually) to have multiple copies of a site for development, staging, production, etc. Ideally you want to use the same code on all the sites. This can lead to an analytics problem -- having data from the dev and staging sites pollute the production data. One approach to dealing with this is to add a filter to the analytics profile to remove any data coming from the staging or dev servers.

I've starting modifying my analytics code as follows:
if (!/staging|localhost/.test(window.location.hostname))
 _gaq.push(['_setAccount', 'UA-XXXXX-X']);

In brief, if we're on our staging server, don't set the web property ID . This results in the tracker using a default ID -- something like "UA-99999-9".

Advantages:
  • The analytics code functions normally, but any data is sent to the default web property ID. This is nice because it's possible to verify that the analytics code is working.
Disadvantages:
  • More Javascript (the hostname comparison) that runs on every page.
Note: I used to put the conditional on the _trackPageview call -- The problem with this is that other analytics code (like _trackEvent, etc) will still be sending data.


Saturday, October 27, 2012

Building a Raspberry Pi Cross Compiler: could not retrieve eglibc-2_16

tl;dr svn is required to fetch eglibc-2_16 when building a Raspberry Pi cross compiler with crosstool-NG

The Raspberry Pi is a great little device. While it's possible to do compiles on the platform, because of limited memory/CPU, for bigger binaries it's faster to work on my regular desktop box.

I'm using crosstool-NG to build a toolchain for cross compiling binaries for the Raspberry Pi.
Following along Chris Boot's steps from How to build a cross compiler for your Raspberry Pi, the final build failed during the "Retrieving needed toolchain components' tarballs" step with the error

ct-ng could not retrieve eglibc-2_16

Looks like the the eglibc folk don't provide tarball releases, so svn is required to fetch eglibc.
Installed Subversion, and had a successful build.

Just for the records, the final list of packages needed for building the cross compiler were:
sudo apt-get -y install libssl-dev openssh-server git-core pkg-config build-essential curl gcc g++
sudo apt-get -y install bison flex gperf libtool texinfo gawk automake libncurses5-dev
sudo apt-get -y install subversion

Update: If you're planning on cross compiling Node.js (build time: 10 minutes instead of 2 hours!), make sure to enable C++ from within ct-ng menuconfig (under C-compiler > Additional supported languages)

Saturday, September 15, 2012

Delta Printer Musings...

I've got a new printer in the works -- a Delta robot based on the Rostock by Johann Rocholl.

I wrote this post to help me get my mind around the differences between traditional 3D printers vs Delta robots, and the math involved in figuring out movement.

(tl;dr The resolution of a single arm on the Rostock printer I’m building varies from 11 to 60 steps/mm across the print bed)

What I find interesting is that with a Delta bot, the resolution changes depending on where you are on the print bed.

With printers that use a Cartesian coordinate linear motion system (i.e. X, Y, Z motors), the resolution of the printer is the same no matter where you’re printing. For example, my ORDish Bot printer has a resolution of approximately 53 steps/millimeter on both the X & Y axis, and 2015 steps/millimeter along the Z.
(Both X & Y axis use 20 tooth gears, 3mm pitch belts, and stepper motors with 200 steps/revolution in 1/16 microstepping mode. The Z axis uses 16 TPI threaded rod and the same motors.)

Looking at a single arm of a Delta Bot, one end of the arm moves up and down (attached to some form of linear motion element), and the other end moves horizontally (attached to a print head). This forms a right triangle, with the arm as the hypotenuse. The hypotenuse length is fixed, and the length of either side can be calculated from the other via the Pythagorean theorem.

The printer I’m currently building is based on Johann’s original Rostock dimensions, with an arm length of 250mm. Moving the print head across the platform (but keeping it on the platform) moves the other end of the arm up & down, at heights ranging from 165mm (print head is farthest from the linear motion element), 218mm (middle of platform), and 245mm (closest to linear motion element)

A little playing around with the Pythagorean theorem shows that a 1mm vertical movement at those points results in print head movements of 0.87mm, 1.76mm, & 4.69mm. Using the same pulley/belt/motor combo as my ORDish bot translates to resolutions of 60, 29, 11 steps/mm. The farther away the print head is from the linear motion  element, the higher the resolution.

This is just looking at one arm... When the print head is in an area of higher resolution of one arm, it’s at lower resolution of the other arms, and visa-versa.

If anybody has a good way of describing the resolution, please let me know.

All these numbers are approximate, and should be taken with a grain of salt...

Thursday, June 7, 2012

Node.js instead of make/Ant...

Interesting post on using Node.js as a build script, instead of make/Ant/...
http://blog.millermedeiros.com/node-js-as-a-build-script/

Con: yet another way of doing builds...
Pro: It's Node.js!

I'm on the fence about this, but I think it's worth considering, depending on your environment.

Tuesday, May 29, 2012

Slic3r 0.8.1/0.8.2 is out!

Slic3r is one of several applications that takes a 3D model and converts it to a set of instruction for a 3D printer.

Slic3r 0.8.1 has been released at http://slic3r.org/

Looks like some interesting new features
  • randomize starting points across layers -- preventing a bump when the starting/ending point is the same.
  • automatically adding perimeters as needed -- I've had problems with printing the tops of spheres.
  • improved surface quality

Looking forward to giving it a try!

Update: make that Slic3r 0.8.2