Elixir and (A)mnesia

I’ve recently written a small website based on Phoenix and Amnesia. Amnesia is an Elixir wrapper around the built-in Mnesia database.

Specifying the mnesia dir from the the shell can be done easily this way:

elixir --erl '-mnesia dir "path/to/db"' -S mix phoenix.start

Installing Elixir on WebFaction

This is a short guide on installing Elixir on a WebFaction shared server. Overall it is fairly easy: first we will install Erlang, then Elixir proper.

Installing Erlang

We will first install erlang in our home directory. The installation itself will be in $HOME/lib/erlang, and all binaries will be aliased in $HOME/bin.

  1. Download the latest erlang release in a temporary folder
wget http://www.erlang.org/download/otp_src_17.3.tar.gz
  1. Extract the archive
tar xvzf otp_src_17.3.tar.gz
cd otp_src_17.3
  1. Compile and install erlang
./configure --prefix=$HOME
make
make install

Installing Elixir

We will now install elixir in a similar fashion by installing it inside $HOME/lib/elixir, and then aliasing all binaries inside $HOME/bin.

  1. Download the latest elixir release in a temporary folder
wget http://s3.hex.pm/builds/elixir/v1.0.2.zip
  1. Extract the archive directly in the destination folder
unzip -d $HOME/lib/elixir v1.0.2.zip
  1. Alias all binaries
ln -s $HOME/lib/elixir/bin/elixir $HOME/bin/elixir
ln -s $HOME/lib/elixir/bin/elixirc $HOME/bin/elixirc
ln -s $HOME/lib/elixir/bin/iex $HOME/bin/iex
ln -s $HOME/lib/elixir/bin/mix $HOME/bin/mix

Map to Keyword List

I like to write Elixir functions that take a Keyword List as optional arguments. Much like for instance HTTPoison does:

def request(method, url, body \\ "", headers \\ [], options \\ []) do
  timeout = Keyword.get options, :timeout, 5000
  stream_to = Keyword.get options, :stream_to
  ...
end

But sometimes all I have at hand is a Map, usually coming straight from a third party json API. Here is a very simple snippet of code to convert such a Map into a Keyword List:

def to_keyword_list(dict) do
  Enum.map(dict, fn({key, value}) -> {String.to_atom(key), value} end)
end

Of course for this code to work, all keys must be strings!

MySQL table lock with Django

When operating with a relational database like MySQL or PostgreSQL it is sometimes required to use table locks, usually when performing a transaction susceptible to concurrency problems.

As a rule of thumb:

  • a WRITE LOCK on a table is needed when writing to that table while performing a transaction susceptible to concurrency issues,
  • a READ LOCK on a table is needed when reading from that table while performing a transaction susceptible to concurrency issues,
  • when a lock is acquired, all the tables used in the transaction must be locked,
  • all locks must be released when a database transaction is completed.

Django’s ORM doesn’t have support for table locks, which is quite understandable as table locking is database specific.

I wrote a small context manager that can be used to lock tables with MySQL:

import contextlib

from django.db import connection


@contextlib.contextmanager
def acquire_table_lock(read, write):
    '''Acquire read & write locks on tables.

    Usage example:
    from polls.models import Poll, Choice
    with acquire_table_lock(read=[Poll], write=[Choice]):
        pass
    '''
    cursor = lock_table(read, write)
    try:
        yield cursor
    finally:
        unlock_table(cursor)


def lock_table(read, write):
    '''Acquire read & write locks on tables.'''
    # MySQL
    if connection.settings_dict['ENGINE'] == 'django.db.backends.mysql':
        # Get the actual table names
        write_tables = [model._meta.db_table for model in write]
        read_tables = [model._meta.db_table for model in read]
        # Statements
        write_statement = ', '.join(['%s WRITE' % table for table in write_tables])
        read_statement = ', '.join(['%s READ' % table for table in read_tables])
        statement = 'LOCK TABLES %s' % ', '.join([write_statement, read_statement])
        # Acquire the lock
        cursor = connection.cursor()
        cursor.execute(statement)
        return cursor
    # Other databases: not supported
    else:
        raise Exception('This backend is not supported: %s' %
                        connection.settings_dict['ENGINE'])


def unlock_table(cursor):
    '''Release all acquired locks.'''
    # MySQL
    if connection.settings_dict['ENGINE'] == 'django.db.backends.mysql':
        cursor.execute("UNLOCK TABLES")
    # Other databases: not supported
    else:
        raise Exception('This backend is not supported: %s' %
                        connection.settings_dict['ENGINE'])

It works with the models declared in your django application, by simply providing two lists:

  • the list of models to lock for read purposes, and
  • the list of models to lock for write purposes.

For instance, using django tutorial’s models, you would just call the context manager like this:

with acquire_table_lock(read=[models.Poll], write=[models.Choice]):
    pass  # Do something here

MVC with GWT: creating and firing custom events with GWT

GWT is obviously able to handle events, for instance ClickEvent fired by Button, or ResizeEvent fired by Window. Wouldn’t it be nice to be able to create custom events? What I have in mind is to create Models that can be binded to Views. I won’t go that far in this post, but instead will just try to figure out:

  • how GWT2 is handling events,
  • how we can create custom events and use them.

We will start with a very simple Model, and fire an event whenever its property, called field, is modified.

Here is our simple model:

public class SimpleModel
{
    private String field;

    public SimpleModel(String field)
    {
        this.field = field;
    }

    public String getField()
    {
        return field;
    }

    public void setField(String field)
    {
        this.field = field;
    }
}

How is GWT handling events?

If we look all the way up to the Widget class, we notice that GWT is able to handle two kinds of events.

  • DOM events, that are native events fired by the underlying html elements:
/**
 * Adds a native event handler to the widget and sinks the corresponding
 * native event. If you do not want to sink the native event, use the
 * generic addHandler method instead.
 *
 * @param <H> the type of handler to add
 * @param type the event key
 * @param handler the handler
 * @return {@link HandlerRegistration} used to remove the handler
 */
protected final <H extends EventHandler> HandlerRegistration
        addDomHandler(final H handler, DomEvent.Type<H> type) {
    assert handler != null : "handler must not be null";
    assert type != null : "type must not be null";
    sinkEvents(Event.getTypeInt(type.getName()));
    return ensureHandlers().addHandler(type, handler);
}
  • “other” events:
/**
 * Adds this handler to the widget.
 *
 * @param <H> the type of handler to add
 * @param type the event type
 * @param handler the handler
 * @return {@link HandlerRegistration} used to remove the handler
 */
protected final <H extends EventHandler> HandlerRegistration addHandler(
        final H handler, GwtEvent.Type<H> type) {
    return ensureHandlers().addHandler(type, handler);
}

Custom events are what we are looking for! The problem is that, well, our simple model does not by any stretch of the imagination qualify as a Widget. So we cannot have our model inherit from the Widget class.

If we look a bit more at the two methods above, we notice they are both calling a method called ensureHandlers().

/**
 * Ensures the existence of the handler manager.
 *
 * @return the handler manager
 * */
HandlerManager ensureHandlers() {
    return handlerManager == null ?
        handlerManager = new HandlerManager(this) : handlerManager;
}

This method is returning a HandlerManager. If you go look in the code or the documentation, a HandlerManager is “responsible for adding handlers to event sources and firing those handlers on passed in events.”. That’s precisely what we were looking for. So all we have to do is to add a HandlerManager to our SimpleModel.

Creating a BaseModel class that is able to fire events

In order to handle events in BaseModel, we basically need two methods :

  • a method to add handlers to the handler manager,
  • a method to fire events.
public class BaseModel
{
    private HandlerManager handlerManager = new HandlerManager(this);

    public <H extends EventHandler> HandlerRegistration
        addHandler(GwtEvent.Type<H> type, final H handler)
    {
        return handlerManager.addHandler(type, handler);
    }

    public void fireEvent(GwtEvent<?> event)
    {
        handlerManager.fireEvent(event);
    }
}

Perfect. Now all we need to do is to extend the SimpleModel so that it fires events.

Adding an event handler and firing events from SimpleModel

At first we need to define what the EventHandler will be. We want to know when the value of field is changed, so it should be something like :

public interface FieldChangedHandler extends EventHandler
{
    public void onFieldChanged(String newValue, String oldValue);
}

Here is the final SimpleModel class, firing a GwtEvent whenever any of its field is changed:

public class SimpleModel extends BaseModel
{
    private String field;

    public String getField()
    {
        return field;
    }

    public void setField(String field)
    {
        String oldValue = this.field;
        String newValue = field;
        this.field = field;
        this.fireEvent(new FieldChangedEvent(oldValue, newValue));
    }

    public HandlerRegistration addFieldChangedHandler(FieldChangedHandler handler)
    {
        return addHandler(handler, FieldChangedEvent.getType());
    }

    public interface FieldChangedHandler extends EventHandler
    {
        public void onFieldChanged(String newValue, String oldValue);
    }

    public static class FieldChangedEvent extends GwtEvent<FieldChangedHandler>
    {
        private final String oldValue, newValue;

        public FieldChangedEvent(String newValue, String oldValue)
        {
            this.newValue = newValue;
            this.oldValue = oldValue;
        }

        /**
         * The event type.
         */
        private static Type<FieldChangedHandler> TYPE = new Type<FieldChangedHandler>();

        /**
         * Handler hook.
         *
         * @return the handler hook
         */
        public static Type<FieldChangedHandler> getType()
        {
            if (TYPE == null)
                TYPE = new Type<FieldChangedHandler>();
            return TYPE;
        }

        @Override
        protected void dispatch(FieldChangedHandler handler)
        {
            handler.onFieldChanged(newValue, oldValue);
        }

        @Override
        public com.google.gwt.event.shared.GwtEvent.Type<FieldChangedHandler> getAssociatedType()
        {
            return TYPE;
        }
    }
}

In order to observe this simple model, just add something like this where needed in your code:

mySimpleModel.addFieldChangedHandler(new FieldChangedHandler()
{
    @Override
    public void onFieldChanged(String newValue, String oldValue)
    {
        // TODO Something
    }
});

That’s great, now we have a SimpleModel firing events whenever its unique property is changed. But as you can imagine, defining an EventHandler and a GwtEvent for each and every field of a model can quickly become tedious work…