January 3, 2012

In Go, is your terminal a console or a pipe? isatty golang

Posted in Software at 18:08 by graham

Is my terminal connected to the console, or to a pipe?

// Is given File a terminal?
func isatty(file *os.File) bool {
    stat, _ := file.Stat()
    return !stat.IsFifo()
}

if ! isatty(os.Stdin) {
  // read what was piped in
}

For example:

$ ./myprog                # isatty = yes
$ echo "boo" | ./myprog   # isatty = no

Mirrors the behaviour of Python’s isatty.

December 22, 2011

Proxy socket.io and nginx on the same port, over SSL

Posted in Software at 23:32 by graham

My current project has a realtime part, using socket.io on nodejs, and a web part using django on nginx / gunicorn. Here’s a setup to put them both on the same port, and make them both go over SSL. I’m assuming you’re on Ubuntu.

Disclaimer: I got this working last night, so no promises. You’ll certainly want to tweak haproxy’s config for performance. I also only tested it with socket.io’s web socket transport.

Overview

  • stunnel decrypts the ssl, so everything after that doesn’t know about it. It decrypts both web traffic (HTTPS to HTTP), and web socket traffic (WSS to WS).
  • haproxy sends web socket traffic to node and web traffic to nginx.
  • node runs socket.io, handling the web socket traffic.
  • nginx serves static content.
  • gunicorn runs python / django, and there’s a database out back somewhere, but that’s not relevant here.

Currently nginx doesn’t Read the rest of this entry »

November 16, 2011

Pretty command line / console output on Unix in Python and Go Lang

Posted in Software at 02:17 by graham

There are lots of easy ways to improve the output of your command line scripts, without going full curses, such as single-line output, using bold text and colors, and even measuring the screen width and height.

The examples are in Python, with a summary example in Go (golang) at the end.

Single line with \r (carriage return)

Instead of printing a \n (which most ‘print’ methods do by default), print a \r. That sends the cursor back to the beginning of the current line (carriage return), without dropping down to a new line (line feed).

import time, sys
total = 10
for i in range(total):
    sys.stdout.write('%d / %d\r' % (i, total))
    sys.stdout.flush()
    time.sleep(0.5)
print('Done     ')

Read the rest of this entry »

November 3, 2011

On why hackers don't work on large teams

Posted in Society, Software at 01:05 by graham

We’ve know for over 35 years that “adding manpower to a late software project makes it later”. Amazon has it’s two-pizza team heuristic: “If a project team can eat more than two pizzas, it’s too large”. The excellent Code Complete has a detailed explanation of how communication costs increase with team size. Yet we still need reminding.

Dhanji R. Prasanna has an excellent retrospective on his time on the Google Wave team. He sums up the problem with big teams very well:

And this is the essential broader point–as a programmer you must have a series of wins, every single day. It is the Deus Ex Machina of hacker success. It is what makes you eager for the next feature, and the next after that. And a large team is poison to small wins. The nature of large teams is such that even when you do have wins, they come after long, tiresome and disproportionately many hurdles. And this takes all the wind out of them.

For me, that’s really the crux of it. As a programmer, it kills you to not get stuff done. Large teams necessarily involve more communication, more complexity, and less getting stuff done. Large teams are a programmers equivalent of retirement.

October 25, 2011

Ad-blocking your iPad

Posted in Software at 01:01 by graham

Monitoring iPad network traffic, and blocking advert download.

An article on monitoring iPhone traffic by Craig Dunn got me wondering what the iPad is sending over the wire. That led me to blocking many of the adverts apps show. Here’s how.

1. Setup a proxy (squid on ubuntu)

First you need to setup a proxy, and send all your iPad’s network traffic through that. On Ubuntu squid is easy to setup: sudo apt-get install squid

Read the rest of this entry »

September 27, 2011

Finding memory leaks in Python with objgraph

Posted in Software at 01:37 by graham

After a frustrating time trying to find a memory leak in my Python code with guppy / heappy hpy, I tried objgraph and, wow, it makes it so easy! Here’s what you do:

pip install objgraph

At the relevant point in your code, add an import pdb; pdb.set_trace() to drop into the debugger. Then just follow the docs on finding memory leaks with objgraph. In short you do:

>> import objgraph
>> objgraph.show_growth(limit=10)   # Start counting

Ignore that output. Call the function that leaks memory, iterate once through you loop, whatever you need to do to make your program consume more memory. Now call show_growth again:

>> my_leaky_func()
>> objgraph.show_growth(limit=10)   # Stop and show change

This time it shows the difference between now and the last time you called it. Those extra objects are the problem.

Finally you need to find where the reference to those leaky objects is being held:

>> import inspect, random
>> objgraph.show_chain(
...     objgraph.find_backref_chain(
...         random.choice(objgraph.by_type('MyBigFatObject')),
...         inspect.ismodule),
...     filename='chain.png')

That generates a lovely graph in your current directory, showing the ownership chain. Now wasn’t that easy? Thanks Marius Gedminas!

September 16, 2011

Cleaning up old git branches

Posted in Software at 20:14 by graham

After a while working with git, you end up with lots of branches, especially if you use git-flow inspired feature branches. Here’s one way to clean them up.

For any branch, I want to know whether it has been merged, when the last commit was, and ideally if the matching ticket in our tracker has been closed.

Switch to your main branch, usually develop or master: git checkout develop

List all the branches which have been fully merged into it:

git branch -a --merged

Read the rest of this entry »

September 15, 2011

Profiling Django for CPU bound apps

Posted in Software at 20:24 by graham

For most Django apps, indeed most webapps, the bottleneck is the database. The biggest gains usually come from reducing the number of queries used, and adding database indexes. django-debug-toolbar helps a lot here. After that, caching and de-normalization also help reduce database queries.

But what if your app is CPU bound? How do you find out where it’s spending it’s time? It’s easy with the runprofileserver from django-extensions – here’s how:

Read the rest of this entry »

August 11, 2011

Unicode in Python 2: Decode in, encode out

Posted in Software at 00:24 by graham

In Python 2 you need to convert between encoded strings and unicode. It’s easy if you follow these three simple rules:

Decode all input strings

name = input_name.decode('utf8', 'ignore')

You need to decode all input text: filenames, file contents, console input, database contents, socket data, etc. If you are using Django, it already does this for you, as much as it can.

Read the rest of this entry »

August 3, 2011

git: Resolving 'git gc' error: cannot lock ref

Posted in Software at 17:37 by graham

If you get an error like this from git::

Auto packing the repository for optimum performance. You may also
run "git gc" manually. See "git help gc" for more information.
error: cannot lock ref 'HEAD (xyz's conflicted copy 2011-06-02)'
error: cannot lock ref 'refs/heads/master (xyz's conflicted copy 2011-06-02)'
error: failed to run reflog

You just need to delete the offending files from .git/logs/ and run your operation again.

« Previous entries Next Page » Next Page »