Another Reason Why I Love JavaScript

by Benson Wong

So I wrote this monstrosity, which I’m tickled by, today:

function gaPush(cat, action, label, value) {
    var call = ['_trackEvent'];

    (cat) ? call.push(cat) : call.push('Undefined');
    (action) ? call.push(action) : call.push('Undefined');
    (label) ? call.push(label) : false;
    (!isNaN(parseInt(value))) ? call.push(parseInt(value)) : false;

    _gaq.push(call);
}

It makes pushing custom events into Google Analytics easier. Useful for in game analytics on the cheap.

That code snippet above does two things:

  1. Creates an Array of values
  2. Does it using ternary operators instead of if/else statements

The nice thing about the pattern is that if label or value were not supplied in the function call it won’t be included in the call array.

{ 0 comments }

MongoDB PHP Session Handler

by Benson Wong

A few weeks ago I released (MIT licensed) a MongoDB PHP session handler. You can find it on GitHub at github.com/mostlygeek/MongoSession.

In the process of tweaking I wound up rewriting the whole thing from scratch. Some major and notable changes:

  1. Concurrency safe.
  2. Less code. Simpler code.
  3. Easier to use.
  4. Ties directly into PHP sessions with session_set_save_handler().

The toughest part was making the code concurrency safe. After using PHP for 10+ years I never gave this any thought. Probably because most of the application I’ve written before dimeRocker were synchronous. With more apps using AJAX a concurrency safe session system is important.

This mongo class sacrifices some performance for concurrency. The technique is simple, lock the mongo document on session open (when session_start() is called) and let it go when PHP finishes the request. The good and bad of this is that reads/writes to the session can happen only happen one at a time.

Illustrated:

  1. Request #1 comes in that takes 2 seconds to complete
  2. Request #2 comes in that takes 0.01 seconds to complete
    1. blocked… waiting for session lock … 2 seconds
    2. wait… wait… wait…
  3. Request #1 finishes
  4. Request #2 unblocks, finishes
  5. Total time for both requests: 2.01 seconds

While this certainly limits the performance of an application to essentially synchronous serial requests, it is very safe. So if request #1 writes to the session data, request #2 won’t blow away those changes with a race condition / last writer win’s scenario.

While this seems like an edge case, the memcache session driver does the exact same thing. In fact the locking algorithm in MongoSession is inspired by it. Also the standard file based session system does an flock() so all the most widely used session handlers implement locking.

Even with locking the performance is very good (done on a linux VM on my Macbook Pro):

  • Mongo w/ Locking : 781.86 trans/sec
  • Mongo NO Locking : 944.29 trans/sec (bad!)
  • PHP File based : 1225.49 trans/sec
  • Memcache based : 840.34 trans/sec

Further note, the locking only affects a single session. That means each session, by the above numbers, is limited to 780 transactions/sec. That’s acceptable, even in the most demanding of applications.

(edit)

Why Mongo for PHP sessions when Memcache is awesome?

  1. Mongo is fast.
  2. Sessions are less transient. The loss of a server won’t destroy a session. This matters in online gaming.
  3. More flexible. Easy to extend the class so other applications can query the data.
  4. I couldn’t mind a good Mongo PHP session driver I liked.

{ 5 comments }

Two Commands To Make You A Better Sysadmin

by Benson Wong

Great sysadmins use aliases to avoid repeatedly typing common commands. Everybody knows lazy sysadmins are the best ones.

The Commands:

alias a='cat ~/.bash_aliases'
alias ea='vi ~/.bash_aliases; echo "Refreshing aliases"; source ~/.bash_aliases'

Here’s what they do:

  1. the command ‘a’ now prints out a list of your current aliases
  2. the command ‘ea’ brings up vi to edit your aliases and refreshes them when you’re done

Here’s the work flow:

> ea
... edit edit hack hack
> a
... list of aliases ...

Where to put it:

Using Linux: ~/.bash_aliases. This file gets read when you log in.

If you are using a Mac do this. In ~/.bash_profile add:

source ~/.bash_aliases

Then add everything into that file instead.

Here’s what mine looks like (well a part of it):

unalias -a
alias a='cat ~/.bash_aliases'
alias ea='vi ~/.bash_aliases; echo "Refeshing aliases..."; source ~/.bash_aliases'

# back up the day's work
alias bkup='sudo -i /root/backup.sh'

# ubuntu version
alias uver='cat /etc/lsb-release'

# manage apache configs
alias s='sudo vi /etc/apache2/sites-available/combined.conf'
alias sr='sudo /etc/init.d/apache2 reload'

# git short cuts
alias gb='git branch';
alias gs='git status';
alias gl='git log'
alias gsr='git svn rebase';
alias gsd='git svn dcommit';

# misc short cuts
alias ll='ls -l'
alias zf='zf.sh'
alias vi='vim'

Now go do it!

{ 2 comments }

How To Use SSH to Create a Remote Proxy

January 27, 2010

Most good sysadmins already know how to forward a local port to a remote machine and vice versa. However, sometimes it is useful to open a port on the remote machine to the world and have that traffic forwarded through SSH to your local machine. A practical reason for this is if your web development [...]

Read the full article →

Reducing spam with a simple mail filter

September 5, 2009

I get a lot of commercial email trying to sell me technology services. Even though these are commercial emails with an unsubscribe link it is still annoying to have to filter through them and unsubscribe. A simple email hack that works well is to filter all email into a separate folder that is not coming [...]

Read the full article →

← Previous Entries

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.