Phillip Pearson - web + electronics notes

tech notes and web hackery from a new zealander who was vaguely useful on the web back in 2002 (see: python community server, the blogging ecosystem, the new zealand coffee review, the internet topic exchange).

2007-6-5

Semi-synchronous replication for MySQL (courtesy Google)

Very nice - Google has implemented semi-synchronous replication for MySQL, so you can get high availability solely through replication.

The detail: MySQL replication is good for scalability, but being asynchronous, it lacks one important feature that would make it more or less a complete high availability solution. If a transaction succeeds on the master, then the master dies and takes its disk with it, the transaction may not have been fully replicated to any slaves.

One way around this is to use DRBD, which blocks fsync() until the data has been replicated. However DRBD has the opposite problem - it's good for HA but doesn't help you scale!

Semi-synchronous replication gives you the transaction replication guarantee by blocking transaction commits until the transaction has been replicated to at least one slave, i.e. gives you high availability *and* scaling.

Code here. Here's the patch for MySQL 5.0.37.

... more like this: [, , , ]

Getting up to date with Python

I haven't paid much attention to what's been happening to the Python Programming language since v2.3. Reading through the What's New in Python 2.5 document, though, it looks like they're rounding off a few more of the sharp edges - excellent. A couple of the syntax alterations will save me much code in future. All we need now are convenient anonymous functions, like what you get with function(args) { code } in Javascript, sub { code } in Perl, or { |args| code } in Ruby.

Some highlights:

- with foo(x) as bar: do_something(bar) calls bar.__enter__() before and bar.__exit__() after the do_something(bar) call - similar to C#'s using statement. @contextlib.contextmanager turns generators into classes, so foo(x) can be a function rather than a constructor.

- you can now send data back to an iterator with it.send(value) (which otherwise behaves like it.next()).

- try/except/else/finally can now be used together; no need to nest a try/except block inside a try/finally block.

- the fragile 'a and b or c' syntax now has a Perl/Ruby-like alternative: b if a orelse c. (Thanks to Mike for the correction here)

- 'http://example.com/'.partition("://") == ('http', '://', 'example.com/')

- startswith/endswith now save you from looping in this common use case: 'foo.jpg'.endswith(('.jpg', 'png', '.gif'))

- defaultdict is a dictionary that provides a default value when you don't supply one. So now instead of mydict = {}; mydict.setdefault(key, []).append(value), you can use mydict = defaultdict(list); mydict[key].append(value)

- msilib lets you create MS Installer .msi files.

- ctypes, which lets you load DLLs / shared libraries and call arbitrary functions in them, is now in the standard distribution.

- ElementTree is now in the standard distribution, as xml.etree.

- new hashlib module: lots o' hashes. md5, sha1, sha{224, 256, 384, 512}.

- sqlite3 is in the standard distribution!

- wsgiref, including basic http server, is now in the standard distribution!

... more like this: []