Tags

bytiness

9:53am on Jan 03, 2017

Coworker Greg said something about the "bytiness" of files, when he was talking about their sizes. He was talking about file sizes, but my mind wandered a little bit down the rabbit hole of defining "bytiness" clearly.

So here's my interpretation interpretation of what that means, implemented in Go. Because sometimes I like Go. No, really.

in the queueueueueueue

4:53pm on Jun 12, 2012

Recently, I've been playing with message queue-based interprocess communication in Python. I've got an application idea which uses a client / worker-pool distributed processing concept, and wanted to test out a few of the options available. Teested libraries/services include:

Yes, I know that ZooKeeper isn't really an MQ, but it's pretty easy to implement one with it.

0MQ

0MQ is exactly what they say: "sockets on steroids". There's no 0MQ "daemon", no extra processes, just sockets and a library to talk via them. This is both good and bad.

Without a daemon, it means that there's no extra point of failure to rely upon, you get full control over your queues and how they're used. But also, you don't get clustering unless you do it yourself, you don't get any administration tools unless you do them yourself, no access control unless you do it yourself, &c.

Working with 0MQ

It took me a while to figure out how many queues I needed for my concept, and how to route them. I designed separate client and worker processes, with a single broker to manage the worker pool. This setup was a bit complex, with client having an output to the broker's input queue, and an input queue for responses from workers. The broker has a single input queue, with various outputs to each of the workers in the pool. The workers each had an input queue.

Actual code for 0MQ is reasonably simple. I ended up making a few objects to wrap the low-level stuff, but it's not like 0MQ is overly verbose. There's a lot of different queue options, all of which do things slightly differently, I ended up using PULL for the worker and client input, PUSH for client -> broker, and PULL into the broker and PUSH out of the broker.

Results

Decent. A bit limited. Not very robust unless you want to do your own heartbeat stuff, it's a little hard to tell that you've actually connected and sent a message and that message was definitely received. I probably won't use it for this.

Celery

Celery is a task/job queue built on message passing, which uses one of a handful of MQ systems. I used RabbitMQ via amqp, because I had it installed already.

I do like that it uses a backend MQ system, and that there's a method and library for integrating it with Pylons (even though I've moved on to Pyramid now).

Working with Celery

Celery is a very high-level library, which uses decorators to indicate task procedures. You can do a lot with very minimal code.

Results

I ended up stopping work on Celery, I just didn't like how the system works. For one, I'm not really a fan of decorators which do a lot behind the scenes, because it's not really obvious what is going on at a glance.

Also, there's no clear way to have a callback when a task is complete, you can only check on the status of jobs from the caller. You can chain tasks, but the subtasks will run in the worker process, not the caller, which just isn't going to be useful for me.

Apache ZooKeeper

As I said, ZooKeeper isn't really a MQ system, it's more of a shared storage system for maintaining configuration, naming, synchronization, and the like, but it's easy to make a message queue. You just make a node for the queue, and therein make a sub-node for each message, letting ZooKeeper name them sequentially. Your worker can process them in order.

ZooKeeper is designed from the start to be robust and distributed, which allows the application developer to not really worry about these things.

Working with ZooKeeper

The python library included in the ZooKeeper source is a bit low-level, so I wrote a basic wrapper library to provide object-oriented access to ZNodes, then built a "ZQueue" object on top of my ZNode class. I found that treating the ZooKeeper tree as a tree of objects works very well when building higher level applications.

My method of making a ZNode for the queue and then ZNodes for each message means ZooKeeper acts as the broker, and there's no need to write a middle layer.

Results

I like ZooKeeper. It's not really a MQ, so I probably won't use it as such, but I'm glad I tried it out, I can think of lots of other uses for it.

Pika and RabbitMQ

Pika is a pure-Python implementation of AMQP 0.9.1, the standard MQ protocol used by various MQ brokers, including my choice here, RabbitMQ.

RabbitMQ is a robust message broker with a management interface and bindings for many languages.

Pika is reasonably flexible, not too low-level but not too high. RabbitMQ is quite full-featured, including a full management interface which lets you inspect queues, and a full access-control system which is entirely optional.

Working with Pika 0.9.5

The Pika library is a little lower level than say, Celery, but it's still reasonably easy to work with. Doing blocking work is rather easy, but doing anything asynchronous or CPS is a little more complex, you have to define mutliple callbacks. I just created objects for both my client and worker.

With RabbitMQ acting as the broker, there's no need to build a broker layer like we did with 0MQ.

Results

Pika has lots of nice features. You can create named, permanent queues, temporary unnamed queues, full message exchanges, tag messages with types and filter on those types, require or discard ACKs, &c. I see lots of possibilites there.

RabbitMQ servers can be clustered to form a single logical broker, and you can mirror queues across machines in a cluster to provide high availability.

In fact, Pika/Rabbit seems to have far more features than I'll actually need for the project I have in mind - which is good, really.

Conclusion

So far, as should be obvious, I'm going to use Pika and RabbitMQ. I've only been playing with the combo for a day, so expect more to come here.

pong is not a physics problem

10:13am on Mar 28, 2012

So my friend Don has been learning iPhone/iPad programming lately, and he decided to implement a pong game to learn how to do game and graphics programming. He'd done this before, years ago in DOS, which makes it a good task to learn the new API.

He kept showing me code... and of course that got me thinking.

So I put together a quick pong demo for Android using AndEngine and the box2d physics engine.

You may now be saying, "But wait! Pong doesn't need a physics engine!" Yes, yes, you're right. The world doesn't need yet another pong game either. But I did want to learn to use box2d anyway, so I'd call this a success.

And here is a test program

10:42am on Mar 20, 2012

I just whipped up a little multitouch bug tester program for Android. As noted in my previous post, lots of Android phones running 2.3.7 and earlier have buggy multitouch. In this example, I show the pointers (up to 5) with pointer numbers. You should be able to see at least two, and if the bug is not present, they should work properly. If you have the bug, you'll notice 1 and 2 swapping back and forth as you touch 1, touch 2, lift 1, then tap 1.

Enjoy.

multitouchbugtest.apk

quit tryin' to be clever

4:16pm on Feb 22, 2012

I was trying to be clever, using the filename portion of the image URLs fed by Plus for the thumbnail images. Yeah, should know better. Now I'm just generating a filename from a UUID, ignoring what the Plus service provides.

So the images are showing up in the right column again. Huzzah!

The stars at night

2:49pm on Jan 11, 2012

I've been working on an Android program which uses 2D graphics over the past few days, and since it's always nice to have sample code to start from, I dug up my old Android starfield simulation.

I wrote this thing back in 2008, not that long after Android first came out, as an introduction to doing 2D graphics. I've written starfields before, first in C (and modeX) back in 1996, then in Flash's ActionScript around 2002.

I just compiled the Android version, and discovered that nothing has changed in the API since 2008 - a very good thing. I did speed up the animation a little and add more stars, since modern phones are a lot faster, and there were odd gaps in the animation.

You can find all of these versions, with source code, right over here.

Naturally, all source is copyright (c) me, and released under the Creative Commons by-nc-sa license.

Finally, a plus API.... well... almost

1:06pm on Oct 20, 2011

So now there's a Google Plus API for Python. You will notice I've added +1 buttons.

However, the sidebar on the right is gone for the moment, because there's a rather major bug in either the Plus API, or the image resizer Google use for the thumbnail images. So right now I can't actually pull thumbnails from Plus, I'd have to pull them down myself.

I'm pondering that, sure, but it seems the wrong way to do it.

Anyway, here's the bug I've submitted to the Plus bug tracker. I suspect that'll languish there for a year or so in the 'new' state, and by that time, I'll have stopped caring.

You know, like most of the Android bugs I've cared about.

cool

5:57pm on Oct 06, 2011

I finally quit being lazy and updated my first Android app, calCOOLator. It was semi-broken because it was using standard java.lang.Double numbers, now I'm using java.math.BigDecimal and dealing with precision much better.

Maintaining old applications, especially when it's been years since you even looked at the code, is a little annoying.

I'm sure I'll still get comments about how it doesn't handle percentages correctly. "50 + 10% = 55" - wtf kind of math is that?

everyone's an amateur

2:04pm on Aug 18, 2011

Yep, I'm doing it again. I'm trying to fix poorly-written libraries. This time it's the python bindings for net-snmp, the most popular SNMP library for unix.

Libraries should never, just print error messages when they can instead throw an exception. Throwing an exception means the application developer using your library has an opportunity to handle the error gracefully, rather than having the library just crash, or in this case, not being able to determine an error condition even exists.

Bad practice.

Here's a link to my bug report. Until they fix it, just edit netsnmp/client.py and replace the 'print stderr...' line with one that throws a useful exception.

Stock quotes, currency, and airports

11:59pm on May 25, 2011

For a recent project, I had need of simple Python libraries for currency conversion, stock quotes, and airport code lookup. In the past, I was using perl for this, so I used Finance::Currency::Convert::XE and Finance::Quote.

But since I'm using Python here, those aren't available to me. And unfortunately, I couldn't find anything on the web either.

And for the airport codes, I got a list and stuck it in a database. But then I have to maintain that... and that's annoying.

So.... here you are. airportcodes.py, googlequote.py and xecurrency.py.

[RSS] [atom]
Tags