about:benjie

Random learnings and other thoughts from an unashamed geek

NodeJS: Express/Socket.io/RedisStore Headache

| Comments

If you’re trying to access a session from a socket.io socket, I recommend following these instructions which work great for MemoryStore. However for RedisStore you need to do a little more work because the object returned is just a JSON object - not a Session object as it should be. I’ve hacked around it by adding the following (CoffeeScript) to convert it to a Session object if required:

.coffee.jsMake sure ‘session’ is a Session object
1
2
3
4
5
if session and not session.prototype?.reload
    req =
        sessionStore: sessionStore
        sessionID: data.sessionID
    session = new express.session.Session req, session

immediately inside the sessionStore.get callback.

Node.JS: Clean Restart and Faster Development With Nodemon

| Comments

If you’re using nodemon to automatically restart your node/coffee server process when the source code changes (and if you’re not, why not?), you may find (as I did) that it can kill the script quite abruptly. If you want to do something when the code shuts down (close connections, flush to database/disk/redis/memcached, etc) then you can do so by intercepting the SIGUSR2 signal that nodemon uses to kill your script, and then setting up these actions. Once these actions are complete, you can exit but nodemon will see that as a crash and stop restarting. So you then have to kill your app again with SIGUSR2. Here’s the solution I use in CoffeeScript (click Toggle for JavaScript):

.coffee.jsCleanly restart on nodemon SIGUSR2 (.coffee)
1
2
3
4
5
6
7
8
9
10
11
12
# Alias for setTimeout that reorders parameters to look neater in CoffeeScript
delay = (ms, cb) -> setTimeout cb, ms
# Handle SIGUSR2, but only once
process.once 'SIGUSR2', ->
  console.log 'Doing shutdown tasks...'
  delay 5000, ->
    console.log 'All done, exiting'
    # Kill ourself with the SIGUSR2 signal again
    process.kill process.pid, 'SIGUSR2'
# This next line just to prevent the app exiting in case you want to use this as a demo
delay 99999999, ->
  console.log 'App exiting naturally'

By the way, to install nodemon globally: sudo npm install -g nodemon

Manually Migrating FileVault

| Comments

DISCLAIMER: As always, you follow this at your own risk - keep good backups, I take no responsibility for you doing anything whatsoever - you’re a big boy/girl now, take responsibility for your own actions!

So you can’t use MigrationAssistant because you already have an account (Alice) on the new machine (New) and don’t have the disk space on the old one (Old) to turn FV off? Fear not! Let’s assume the username you want to move is steve:

  1. As Alice, create (admin) account on New with same username, steve, and same password, and enable FileVault.
  2. Replace /Users/steve/steve.sparsebundle on New with /Users/.steve/steve.sparsebundle from Old. (you could use scp, rsync, an external hard drive, or any other method to transfer these files) (I did this with steve logged in, but you can do it logged out though the path may be different)
  3. As Alice, fix the permissions on New: chown -R steve /Users/steve
  4. Log in as steve on New (unlocks the sparsebundle and mounts it at /Users/steve)
  5. Fix permissions again: either as Alice or steve, sudo chown -R steve /Users/steve
  6. Log out an in again Voila!

If this helps you, please drop me a comment :)

JavaScript: Defining a Window Level Function With Eval()

| Comments

You know the old mantra: eval is evil! Well, maybe, but I hate writing lots of code, and I like my debugging to be simple. I wanted to write a shorter way to extend a parent class into a child class. Long way (too much repeated code/risk of copy & paste errors):

Long winded: manually creating each class from scratch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Root class
function MyClass() {
  return this;
}

// Create first subclass
function MyChildClass1() {
  return this;
}
MyChildClass1.prototype = new MyClass();
MyChildClass1.prototype.parent = MyClass.prototype;
MyChildClass1.prototype.constructor = MyChildClass1;

// Create second subclass
function MyChildClass2() {
  return this;
}
MyChildClass2.prototype = new MyClass();
MyChildClass2.prototype.parent = MyClass.prototype;
MyChildClass2.prototype.constructor = MyChildClass2;

// Create an instance
var instance = new MyChildClass2();

Shorter way (gives wrong output on console.log()):

Backup Your Logs to S3

| Comments

We’ve got an auto-scaling EC2 setup, so servers can appear and disappear at will, each with random IP addresses. We want to store the apache error/access logs (or system logs) from these servers for later debugging and analysis, but nothing else on them matters (they’re basically read only, except the logging). How should we store these?

Seems like a simple problem, there must be a simple solution? Here are the existing options:

Dear Virgin Media…

| Comments

I think I do have fibre optic at my house already, even though it does not show up on your system. The previous resident had V+HD, and they left their equipment, so I’ve plugged it in to show the system working:

iPhone Music and Sound Effects in Parallel

| Comments

I was trying to find out how to use [MPMusicPlayerController iPodMusicPlayer] and AVAudioPlayer in parallel. I’d read before that I’d need Audio Sessions, but the documentation for that was huge and confusing. Fortunately Andrew pointed me at this post from Mark at Sputnik Games which solved my issue immediately just by copying and pasting 14 lines of code into the applicationDidFinishLaunching method of my application delegate (see below). Sputnik Games’ blog doesn’t seem to support comments, so I thought I’d buy his latest game, Aerolite, and write this post to show my appreciation. Thanks Mark!

Add to applicationDidFinishLaunching to enable music & sound effects at the same time
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
OSStatus result = AudioSessionInitialize(NULL, NULL, NULL, self);
if (result) {
  // Init error, handle error here
} else {
  UInt32 category = kAudioSessionCategory_AmbientSound;
  result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                                    sizeof(category), &category);
  if (result) {
      // set audio session error, handle error here
  } else {
      result = AudioSessionSetActive(true);
      if (result) {
          // Set audio session active error, handle error here
      }
  }
}

N900: First Impressions

| Comments

This post is part 2 of a three part series. You may also be interested in: Part 1: N900: the tale of the indestructible box Part 3: N900: a phone for hackers? (coming soon…)

After conquering the indestructible box and charging the N900 I decided to have a quick play. I watched the getting started video which I found to be both beautifully smooth, showing off the high definition of the N900 screen immediately, and somewhat slow content-wise.

G1 (top), N900 (left), iPhone 3GS (right)

The N900 is similar in width and height to the iPhone but