There were days when computers had 16-bit registers and 20-bit addressable memory. That is a total of 1MB memory - some claimed that it ought to be enough for anybody. Memory address space was flat and not protected by anything, now it’s known as the real mode. How was it possible to address 20-bit memory with only 16-bit registers?
Read more…
A worker pool is a very common pattern, and they exist in the standard libraries for many languages. The idea is simple: submit some sort of closure to a service which commits to running the closure in the future in some thread. Normally the work is shared out among many different threads and in the absence of anything fancier, one assumes a first-come-first-served queue of closures.
Erlang, with its light-weight process model is not a language which you would expect would require such an approach: processes are dirt cheap, and the scheduler maps processes onto threads when they are ready to be run — in many ways, the ErlangVM is a glorified implementation of a worker pool, only one that does pre-emption and other fancy features, in a very similar way to an OS kernel. However, we recently found in RabbitMQ a need for a worker pool. Read more…
People tend to like certain software packages to be scalable. This can have a number of different meanings but mostly it means that as you throw more work at the program, it may require some more resources, in terms of memory or CPU, but it nevertheless just keeps on working. Strangely enough, it’s fairly difficult to achieve this with finite resources. With things like memory, the classical hierarchy applies: as you use up more and more faster memory, you start to spill to slower memory — i.e. spilling to disk. The assumption tends to be that one always has enough disk space.
Other resources are even more limited, and are harder to manage. One of these is file descriptors. Read more…
I got a couple of queries recently on how to make your mercurial-server repositories publically readable over HTTP. Happily this isn’t hard to do, and doesn’t really touch on mercurial-server itself. Here’s how we do it on our Debian systems; in what follows I assume that you have installed mercurial-server on hg.example.com, and that you’re not already using that machine as a web server for anything else. First install these packages; note that they tend to have a lot of stuff you don’t need marked as recommended, so don’t install those things:
apt-get --no-install-recommends install apache2 libapache2-mod-fcgid python-flup
Create the following four files:
/etc/mercurial-server/hgweb.config:
[collections] /var/lib/mercurial-server/repos = /var/lib/mercurial-server/repos
/etc/mercurial-server/hgweb.hgrc:
[web] style = gitweb allow_archive = bz2 gz zip baseurl = http://hg.example.com/ maxchanges = 200
/etc/mercurial-server/hgwebdir.fcgi:
#!/usr/bin/env python
from mercurial import demandimport; demandimport.enable()
import os
os.environ["HGENCODING"] = “UTF-8″
os.environ["HGRCPATH"] = “/etc/mercurial-server/hgweb.hgrc”
from mercurial.hgweb.hgwebdir_mod import hgwebdir
from mercurial.hgweb.request import wsgiapplication
from flup.server.fcgi import WSGIServer
def make_web_app():
return hgwebdir(”/etc/mercurial-server/hgweb.config”)
WSGIServer(wsgiapplication(make_web_app)).run()
/etc/apache2/sites-available/hg:
<VirtualHost *>
ServerName hg.example.com
AddHandler fcgid-script .fcgi
ScriptAlias / /etc/mercurial-server/hgwebdir.fcgi/
ErrorLog /var/log/apache2/hg/error.log
LogLevel warn
CustomLog /var/log/apache2/hg/access.log combined
</VirtualHost>
Finally run these commands as root:
chmod +x /etc/mercurial-server/hgwebdir.fcgi mkdir -p /var/log/apache2/hg cd /etc/apache2/sites-enabled rm 000-default ln -s ../sites-available/hg /etc/init.d/apache2 reload
Your files should now be served at http://hg.example.com/ . Sadly because of a design flaw in hgwebdir, there’s no easy way to get Apache to handle the static files it needs, but these are pretty small so there’s no harm in letting hgwebdir handle them. The “rm 000-default” thing seems pretty undesirable, but without it I can’t seem to get this recipe to work.
I’ve chosen FastCGI as the connector. This has the advantage that
As soon as a version of lighttpd with this bug fixed makes it into Debian, I’ll add my recipe for that.
Whilst writing the installer for WebGAC, I was faced with some challenges trying to make the Add-In install for all users on the system. The MSDN documentation for Add-In registration generally recommends placing the files into the user’s My Documents directory. It’s All Users solution is to place it into the Shared Documents directory. The problem I faced was that that directory has moved drastically on Windows 7 - to the point where as far as I can tell, Visual Studio (2008 at least) is no longer searching there by default.
It turns out, though, that there is an easy solution.
Some time ago we got an interesting bug report for RabbitMQ. Surprisingly, unlike other complex bugs, this one is easy to describe:
At some point basic.get suddenly starts being very slow - about 9 times slower!
Managing binary dependencies in .NET can be a complicated task. For small projects, checking the dependencies into source control tends to work just fine. So does requesting that all developers have various binaries available in their GAC. Grow much bigger, or add more projects, and managing that starts to get very difficult.
The Java world has had a solution to this problem for a long time, in the form of Maven and Ivy. Remote servers store the binaries, and the build tool automatically downloads them on demand. WebGAC adds the core of this functionality to .NET, but without requiring you to switch build tools, or maintain a separate configuration file. Dependencies are specified just the same way as normal, but if you don’t have them when building your project, WebGAC will fetch them for you automatically.
WebGAC is available at http://github.com/paulj/webgac. Browse over there for more information and installation instructions, or continue reading here for more details.
This post walks through the steps for using Clojure to write an extremely simple web application. The web application will use the Ring and Enlive libraries.
Firstly install Leiningen, this is a simple build tool for Clojure, follow the instructions on the web page and place the lein somewhere on your executable path.
In several applications, it’s very useful to be able to take messages out of one RabbitMQ broker, and insert them into another. Many people on our mailing list have being asking for such a shovel, and we’ve recently been able to devote some time to writing one. This takes the form of a plugin for Rabbit, and whilst it hasn’t been through QA just yet, we’re announcing it so people who would like to play and even suggest further features for inclusion can do so sooner rather than later.
The shovel is written on top of the Erlang client. It supports both direct and network connections to nodes, SSL support, the ability to declare resources on nodes it connects to, basic round-robinrabbit balancing of both source and destination nodes, and allows you to configure many parameters controlling how messages are consumed from the source, and how they’re published to the destination. Multiple shovels can be specified, their statuses queried, and shovels can repeatedly reconnect to nodes in the event of failure.
The plugin is available from http://hg.rabbitmq.com/rabbitmq-shovel/, and is released under the MPL v1.1. There is a README included which contains full documentation. This is replicated below. Read more…
Microsoft WPF includes a data binding framework that provides a simple declarative mechanism to associate and validate data with UI components - read some good tips and tricks here.
This works well very well for simple form validation but sometimes you may want to perform a more complex series of validations and reflect the failures back to the user in a similar manner to the field level validation. For example, a particular combination of fields may result in breaking a business rule for that particular user and the client has asked you to highlight all of these fields with a similar message. In this situation additional validation when the form is submitted may be the simplest solution, so we need to carry out some process like this:
To perform the last step you need to know how to programmatically force binding errors. I googled and binged for ages trying to find this information so here is the simple recipe.
ValidationError validationError = new ValidationError(emptyValidationRule,
textBox.GetBindingExpression(TextBox.TextProperty), "Error message", null);
Validation.MarkInvalid(textBox.GetBindingExpression(TextBox.TextProperty), validationError);
I am using an emptyValidationRule just to satisfy the type signature here. It is never actually used because my business validation is carried out elsewhere. The emptyValidationRule is a simple implementation of a ValidationRule that always fails.
To remove a validation error from a field
Validation.ClearInvalid(textBox.GetBindingExpression(TextBox.TextProperty));
This approach can also help if you need to validate that a ComboBox value is actually selected when no default value has been provided. Validation rules only fire automatically if data binding actually occurs, that means the ComboBox must actually be used. You could force databinding to occur like this:
comboBox.GetBindingExpression(ComboBox.SelectedItemProperty).UpdateTarget();
when the ComboBox loses focus. However, if the user just uses the mouse to press the form submit button, the combobox will never gain or lose focus so no validation will take place. To work around this you can validate in the way I have shown above or perform UpdateTarget operations on all of the ComboBox controls in the form when submit is pressed.