It's the future now

time to read 7 min | 1302 words

For various reasons, I had to implement the Future pattern in two completely different settings in three different ways today.

A future is a place-holder for the undetermined result of a (concurrent) computation. Once the computation delivers a result, the associated future is eliminated by globally replacing it with the result value. That value may be a future on its own.

The last implementation was the explicit one, it was simply:

public class Future<T>
{
	private T value;
	private bool hasValue;
	private string error;

	public void SetValue(T value)
	{
		this.value = value;
		hasValue = true;
	}

	public void SetError(string error)
	{
		this.error = error;
	}

	public bool HasError
	{
		get { return error != null; }
	}

	public T Value
	{
		get { return value; }
	}

	public bool HasValue
	{
		get { return hasValue; }
	}

	public string Error
	{
		get { return error; }
	}
}

This is the simplest approach, primitive, you would say. It requires active collaboration from the code that uses it, and it requires that the method would return a future value. It is a good approach for a very small API, but this is often something that you want to handle in a cross cutting fashion. First, we need a more robust future implementation. (This is wasteful in that it doesn't lazily allocate the reset event).

public class Future<T>
{
	private ManualResetEvent resetEvent = new ManualResetEvent(false);
	private T value;
	private bool hasValue;
	private Exception error;

	public void SetValue(T value)
	{
		this.value = value;
		hasValue = true;
		resetEvent.Set();
	}

	public void SetError(Exception error)
	{
		this.error = error;
		resetEvent.Set();
	}

	public bool HasError
	{
		get { return error != null; }
	}

	public T Value
	{
		get
		{
			resetEvent.WaitOne();
			resetEvent.Close();
			if (error != null)
				throw new FutureInvocationException(error);
			return value;
		}
	}

	public bool HasValue
	{
		get { return hasValue; }
	}

	public Exception Error
	{
		get
		{
			resetEvent.WaitOne();
			return error;
		}
	}
}

Now that we have that, we still have to deal with changing the interfaces and an explicitly concurrent programming model. There is a better way, I got the idea from watching a future / active objects implementation in Python, from Ronnie Maor. The ability to subvert the return value there allows for really nice things.

We will start with the easiest version to grasp, we will define the code that we want to work with:

public class WorkFlowController
{
    public virtual int LongRunningTask()
    {
        Console.WriteLine("Starting long running");
        Thread.Sleep(5000);
        Console.WriteLine("Completed long running");
        return 42;
    }
}

Now, we want to make this into something that will return a future, and we want to do it in a way that wouldn't be too awkward. Here is a simple usage:

WorkFlowController controller = new WorkFlowController();
Future<int> future = InThe.Future<int>(delegate { return controller.LongRunningTask(); });
Console.WriteLine("After calling long running");
Console.WriteLine(future.Value);

Executing this code produces:

After calling long runnning
Starting long running
Completed long running
42

The InThe.Future part is simply:

public class InThe
{
    public delegate T Proc<T>();
    public static Future<T> Future<T>(Proc<T> futureAction)
    {
        Future<T> future = new Future<T>();
        ThreadPool.QueueUserWorkItem(delegate
        {
            try
            {
                future.SetValue(futureAction());
            }
            catch (Exception e)
            {
                future.SetError(e);
            }
        });
        return future;
    }
}

This is pretty straightforward, but I don't like the syntax that we have here (even with C# 3.0, it is still ugly). What I would like to get is this:

WorkFlowController controller = With.Future<WorkFlowController>();
Future<int> future = InThe.Future(controller.LongRunningTask());
Console.WriteLine("After calling long runnnig");
Console.WriteLine(future.Value);

Suddenly I have a saner model, and the model to support futures is explicit. The implementation is fairly trivial as well:

public class FutureInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        InThe.lastInvocation = invocation;
        if (invocation.Method.ReturnType.IsValueType)
            invocation.ReturnValue = Activator.CreateInstance(invocation.Method.ReturnType);
    }
}

public static class With
{
    private readonly static ProxyGenerator generator = new ProxyGenerator();

    public static T Future<T>(params object[] args)
    {
        return (T)generator.CreateClassProxy(
            typeof (T), 
            new IInterceptor[] {new FutureInterceptor()}, 
            args);
    }
}

public class InThe
{
    public static IInvocation lastInvocation;

    public static Future<T> Future<T>(T ignored)
    {
        Future<T> future = new Future<T>();
        IInvocation invocation = lastInvocation;
        lastInvocation = null;
        ThreadPool.QueueUserWorkItem(delegate
        {
            try
            {
                invocation.Proceed();
                future.SetValue((T)invocation.ReturnValue);
            }
            catch (Exception e)
            {
                future.SetError(e);
            }
        });
        return future;
    }
}

I like this best, and it is very easy to implement and work with. Return value woes has been overcome, horray!