technology from back to front

Publishing your mercurial-server repositories to the Web

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

  • unlike CGI, it doesn’t fork a new handler on every request
  • unlike mod_python, it keeps your Mercurial handler separate from your web server
  • unlike SCGI, it will automatically start the service for you if it’s not already running, which is a massive convenience
I’m not aware of any other way of working that offers all three advantages.

As soon as a version of lighttpd with this bug fixed makes it into Debian, I’ll add my recipe for that.

by
Paul Crowley
on
05/03/10

Installing Visual Studio AddIns for All Users

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.

Read more…

by
paulj
on

Memory matters - even in Erlang

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!

Read more…

by
marek
on
28/02/10

WebGAC: Minding your .NET Dependencies

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.

Read more…

by
paulj
on
27/02/10

A simple web application in Clojure using ring and enlive

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.

Read more…

by
tim
on

RabbitMQ-shovel: Message Relocation Equipment

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…

by
matthew
on
01/02/10

Validating whole forms with WPF Data Binding

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:

  1. Perform validation of business object obtained from data binding.
  2. Interpret validation results.
  3. Flag multiple fields as being incorrect.

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.

  1. Make sure the fields that the fields that need to show binding errors have a mode of TwoWay or OneWayToSource in their binding expression.
  2. Make sure the fields that need to show binding errors have the ValidatesOnDataErrors set to true in their binding expressions.
  3. Force the validation errors when the form is submitted like this
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.

by
tim
on
31/01/10

Plugin exchange types for RabbitMQ

An obvious extension point for an AMQP broker is the addition of new types of exchange. An exchange type essentially represents an algorithm for dispatching messages to queues, usually based on the message’s routing key, given how the queues are bound to the exchange — it’s a message routing algorithm.

At a minimum, supporting new exchange types requires only some scaffolding to plug in to (an exchange type registry) and a hook for routing messages. However, this wouldn’t support some more interesting use cases, and in particular it didn’t support our motivating use case. Exchange types that want to keep their own state need to be initialised, and be notified about other lifecycle events. Read more…

by
mikeb
on
22/01/10

Upgrading your disk with LVM

I’ve just had my most pleasant move from a smaller to a larger disk ever thanks to LVM, with vastly reduced downtime, and I thought I’d share my happy experience. Read more…

by
Paul Crowley
on
15/01/10

Network server programming with SML/NJ and CML

My experience with SML/NJ has been almost uniformly positive, over the years. We used it extensively in a previous project to write a compiler (targeting the .NET CLR) for a pi-calculus-based language, and it was fantastic. One drawback with it, though, is the lack of documentation. Finding out how to (a) compile for and (b) use CML takes real stamina. I’ve only just now, after several hours poring over webpages, mailing lists, and library source code, gotten to the point where I have a running socket server.

Download source code, building, and running

The following example is comprised of a .cm file for building the program, and the .sml file itself. The complete sources:

Running the following command compiles the project:

ml-build test.cm Testprog.main

The ml-build output is a heap file, with a file extension dependent on your architecture and operating system. For me, right now, it produces test.x86-darwin. To run the program:

sml @SMLload=test.x86-darwin

substituting the name of your ml-build-produced heap file as necessary.

On Ubuntu, you will need to have run apt-get install smlnj libcml-smlnj libcmlutil-smlnj to ensure both SML/NJ and CML are present on your system.

The build control file

The test.cm file contains

Group is
    $cml/basis.cm
    $cml/cml.cm
    $cml-lib/smlnj-lib.cm
    test.sml

which instructs the build system to use the CML variants of the basis and the standard SML/NJ library, as well as the core CML library itself and the source code of our program. For more information about the SML CM build control system, see here.

The example source code

Turning to test.sml now, we first declare the ML structure (module) we’ll be constructing. The structure name is also part of one of the command-line arguments to ml-build above, telling it which function to use as the main function for the program.

structure Testprog = struct

Next, we bring the contents of the TextIO module into scope. This is necessary in order to use the print function with CML; if we use the standard version of print, the output is unreliable. The special CML variant is needed. We also declare a local alias SU for the global SockUtil structure.

open TextIO
structure SU = SockUtil

ML programs end up being written upside down, in a sense, because function definitions need to precede their use (unless mutually-recursive definitions are used). For this reason, the next chunk is connMain, the function called in a new lightweight thread when an inbound TCP connection has been accepted. Here, it simply prints out a countdown from 10 over the course of the next five seconds or so, before closing the socket. Multiple connections end up running connMain in independent threads of control, leading automatically to the natural and obvious interleaving of outputs on concurrent connections.

fun connMain s =
    let fun count 0 = SU.sendStr (s, "Bye!\r\n")
          | count n = (SU.sendStr (s, "Hello " ^ (Int.toString n) ^ "\r\n");
                       CML.sync (CML.timeOutEvt (Time.fromReal 0.5));
                       count (n - 1))
    in
        count 10;
        print "Closing the connection.\n";
        Socket.close s
    end

The function that depends on connMain is the accept loop, which repeatedly accepts a connection and spawns a connection thread for it.

fun acceptLoop server_sock =
    let val (s, _) = Socket.accept server_sock
    in
        print "Accepted a connection.\n";
        CML.spawn (fn () => connMain(s));
        acceptLoop server_sock
    end

The next function is the primordial CML thread, responsible for creating the TCP server socket and entering the accept loop. We set SO_REUSEADDR on the socket, listen on port 8989 with a connection backlog of 5, and enter the accept loop.

fun cml_main (program_name, arglist) =
    let val s = INetSock.TCP.socket()
    in
        Socket.Ctl.setREUSEADDR (s, true);
        Socket.bind(s, INetSock.any 8989);
        Socket.listen(s, 5);
        print "Entering accept loop...\n";
        acceptLoop s
    end

Finally, the function we told ml-build to use as the main entry point of the program. The only thing we do here is disable SIGPIPE (otherwise we get rudely killed if a remote client’s socket closes!) and start CML’s scheduler running with a primordial thread function. When the scheduler decides that everything is over and the program is complete, it returns control to us. (The lone end closes the struct definition way back at the top of the file.)

fun main (program_name, arglist) =
    (UnixSignals.setHandler (UnixSignals.sigPIPE, UnixSignals.IGNORE);
     RunCML.doit (fn () => cml_main(program_name, arglist), NONE);
     OS.Process.success)

end
by
tonyg
on
01/01/10

Older Posts »

2000-9 LShift Ltd, 1st Floor Office, Hoxton Point, 6 Rufus Street, London, N1 6PE, UK +44 (0)20 7729 7060