Category Archives: Software development

The Sorry State of the Web in 2016

When I republished my article “Bypassing a Login Form using SQL Injection“, it received a mixed reception. While some applauded the effort to raise awareness on bad coding practices leading to serious security vulnerabilities (which was the intent), others were shocked. Comments on the articles and on Reddit were basically variants of “That code sucks” (of course it sucks, that’s exactly what the article is trying to show) and “No one does these things any more”.

If you’ve had the luxury of believing that everybody writes proper code, then here are a few things (limited to my own personal experience) that I ran into during 2016, and in these first few days of 2017.

SQL Injection

I was filling in a form on the website of a local financial institution a few days ago, when I ran into this:

It was caused by the apostrophe in my surname which caused a syntax error in the SQL INSERT statement. The amateur who developed this website didn’t even bother to do basic validation, let alone parameterised queries which would also have safeguarded against SQL injection.

Airlines and Apostrophes

My experience with airlines is that they tend to go to the other extreme. In order to keep their websites safe, they simply ban apostrophes altogether. This is a pain in the ass when your surname actually has an apostrophe in it, and airlines stress the importance of entering your name and surname exactly as they show on your passport.

United Airlines, for instance, believe that the surname I was born with isn’t valid:

Virgin America, similarly, takes issue with my whole full name:

We’re in 2017. Even shitty Air Malta accepts apostrophes. All you need to do is use parameterised queries or a proper ORM. Using silly and generic error messages doesn’t help avoid customer frustration.

Plagiarism

Speaking of Air Malta, here’s a classic which they ripped off from some other US airline:

US Federal law? In Malta? Go home, Air Malta. You’re drunk.

Don’t Piss People Off

I’ve had a really terrible experience with booking domestic flights with US airlines. There is always some problem when it comes to paying online with a VISA.

United Airlines, for instance, only accepts payments from a specific set of countries. Malta is not on that list, and there is no “Other” option:

Delta gives a variety of billing-address-related errors depending on what you enter.

Southwest provides fields to cater for payments coming from outside the US:

And yet, you need to provide a US State, Zip Code and Billing Phone Number.

The worst offender, though, is Virgin America. While the overall experience of their AngularJS website is quite pleasant, paying online is a hair-ripping experience. If you choose a country where the State field does not apply (such as Malta, or the UK), a validation error fires in JavaScript (it doesn’t appear in the UI) and does not let you proceed:

It’s almost like the developers of this website didn’t quite test their form. Because developers normally do test their code, right? Right?

Well, when I reported the error to Virgin, and offered to provide a screenshot and steps to reproduce, the support representative gave me this canned bullshit:

“So sorry for the web error. Can recommend using one of our compatible browsers chrome or safari. Clearing your cookies and cache.  If no resolve please give reservations a ring [redacted] or international [redacted] you’ll hear a beep then silence while it transfers you to an available agent.  Thanks for reaching out.~”

I had to escalate the issue just so that I could send in the screenshot to forward to their IT department. Similarly, I was advised to complete the booking over the phone.

Over a month later, the issue is still there. It’s no wonder they want people to book via telephone. Aside from the international call rate, they charge a whooping $20 for a sales rep to book you over the phone.

Use SSL for Credit Card And Personal Details

In July 2016, I wanted to book a course from the local Lifelong Learning unit. I found that they were accepting credit card details via insecure HTTP. Ironically, free courses (not needing a credit card) could be booked over an HTTPS channel. When I told them about this, the response excuse was:

“This is the system any Maltese Government Department have been using for the past years.”

It is NOT okay (and it’s probably illegal) to transmit personal information, let alone credit card details, over an insecure channel. That information can be intercepted by unauthorised parties and leaked for the world to see, as has happened many times before thanks to large companies that didn’t take this stuff seriously.

To make matters worse, Lifelong Learning don’t accept cheques by post, so if you’re not comfortable booking online, you have to go medieval and bring yourself to their department to give them a cheque in person.

I couldn’t verify if this problem persists today, as the booking form was completely broken when I tried filling it a few days ago – I couldn’t even get to the payment screen.

Update 8th January 2017: I have now been able to reproduce this issue. The following screenshots are proof, using the Photo Editing course as an example. I nudged the form a little to the right so that it doesn’t get covered by the security popup.

Update 9th January 2017: Someone pointed out that the credit card form is actually an iframe served over HTTPS. That’s a little better, but:

  • From a security standpoint, it’s still not secure.
  • From a user experience perspective, a user has no way of knowing whether the page is secure, because the iframe’s URL is hidden and the browser does not show a padlock.
  • The other personal details (e.g. address, telephone, etc) are still transmitted unencrypted.

Do Server Side Validation

When Times of Malta launched their fancy new CMS-powered website a few years ago, they were the object of much derision. Many “premium” articles which were behind a paywall could be accessed simply by turning off JavaScript.

Nowadays, you can still access premium articles simply by opening an incognito window in your browser.

Let’s take a simple example. Here’s a letter I wrote to The Times a few years ago, which is protected by the paywall:


Back in 2014, I used to be able to access this article simply by opening it in an Incognito window. Let’s see if that still works in 2017:

Whoops, that’s the full text of the article, without paying anything!

Like those critics of my SQL injection article, you’d think that people today know that client-side validation is not enough, and that it is easy to bypass, and that its role is merely to provide better user experience and reduce unnecessary roundtrips to the server. The real validation still needs to be server-side.

Conclusion

Many people think we’re living in a golden age of technology. Web technology in particular is progressing at a breathtaking pace, and we have many more tools nowadays than we could possibly cope with.

And yet, we’re actually living in an age of terrible coding practices and ghastly user experience. With all that we’ve learned in over two decades of web development, we keep making the same silly mistakes over and over again.

I hope that those who bashed my SQL injection article will excuse me if I keep on writing beginner-level articles to raise awareness.

Drawing Lines with SDL2

We’ve seen before how we can draw pixels using SDL2, similar to a basic Paint application. The next step is to draw lines. To do this, we can reuse our pixel drawing code with something like Bresenham’s line algorithm, or we can use SDL_RenderDrawLine(), which SDL2 gives us out of the box.

The source code for this article is available at the Gigi Labs BitBucket repository.

Let’s start with the following code, which gives us a basic empty window:

#include <SDL.h>

int main(int argc, char ** argv)
{
    // variables

    bool quit = false;
    SDL_Event event;

    // init SDL

    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window * window = SDL_CreateWindow("SDL2 line drawing",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);

    // handle events

    while (!quit)
    {
        SDL_Delay(10);
        SDL_PollEvent(&event);

        switch (event.type)
        {
            case SDL_QUIT:
                quit = true;
                break;
            // TODO input handling code goes here
        }

        // clear window

        SDL_SetRenderDrawColor(renderer, 242, 242, 242, 255);
        SDL_RenderClear(renderer);

        // TODO rendering code goes here

        // render window

        SDL_RenderPresent(renderer);
    }

    // cleanup SDL

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

A line is usually drawn between two endpoints: (x1, y1) and (x2, y2). When the user presses the left mouse button, we’ll store the place he clicked as (x1, y1), and then draw a line to the current cursor position (x2, y2). When he lets go of the left mouse button, we’ll store that line.

Thus, we need an integer variable for each coordinate, and a boolean that indicates whether a line is being drawn (i.e. whether the left mouse button is pressed):

    int x1 = 0;
    int y1 = 0;
    int x2 = 0;
    int y2 = 0;
    bool drawing = false;

We can now add handlers for when the left mouse button is pressed and released. At a basic level, this involves toggling the drawing flag. However, when the left mouse button is pressed (i.e. when a new line is started), we also need to record the current cursor position as (x1, y1), and reset the value of (x2, y2).

            case SDL_MOUSEBUTTONDOWN:
                switch (event.button.button)
                {
                    case SDL_BUTTON_LEFT:
                        x1 = event.motion.x;
                        y1 = event.motion.y;
                        x2 = event.motion.x;
                        y2 = event.motion.y;
                        drawing = true;
                        break;
                }
                break;
            case SDL_MOUSEBUTTONUP:
                switch (event.button.button)
                {
                    case SDL_BUTTON_LEFT:
                        drawing = false;
                        break;
                }
                break;

An additional event handler, this time for mouse movement, updates the value of (x2, y2) while the left mouse button is pressed, giving a feel that the line is being dragged:

            case SDL_MOUSEMOTION:
                if (drawing)
                {
                    x2 = event.motion.x;
                    y2 = event.motion.y;
                }
                break;

We can now add code to actually draw the line, before the call to SDL_RenderPresent():

        // draw current line

        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        if (drawing)
            SDL_RenderDrawLine(renderer, x1, y1, x2, y2);

Great, we now can draw lines by left-clicking and dragging the mouse:

…but the lines disappear whenever the left mouse button is released!

In order to keep the drawn lines in the window, we’ll need to store them, and draw them on each iteration of the game loop. We first need to declare a struct that represents each line we draw:

struct Line
{
    int x1;
    int y1;
    int x2;
    int y2;
};

We then need a simple data structure to store the lines, such as a list from the C++ standard library:

#include <list>

Let’s declare a variable for the list that will hold our lines:

std::list<Line> lines;

Then, we’ll add some code so that when the left mouse button is released, the new line is added to the list:

            case SDL_MOUSEBUTTONUP:
                switch (event.button.button)
                {
                    case SDL_BUTTON_LEFT:
                        drawing = false;
                        Line line = { x1, y1, x2, y2 };
                        lines.push_back(line);
                        break;
                }
                break;

Finally, before the code that draws the new line, let’s add some code that draws all the old ones:

        // draw stored lines

        SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);

        for (std::list<Line>::const_iterator i = lines.begin(); i != lines.end(); ++i)
        {
            Line line = *i;
            SDL_RenderDrawLine(renderer, line.x1, line.y1, line.x2, line.y2);
        }

Now, all the lines you draw will remain in the window:

SDL2 Bounding Box Collision Detection

One of the most basic and fundamental pieces of logic in a game is to check whether an object hit another object. This is known as collision detection. You can use it to check whether a bullet hit the player or an enemy, or to see if the player bumped into an impassable barrier, etc.

The source code for this article is available at the Gigi Labs BitBucket repository.

Although objects in a 2D game may have various shapes, it’s usually easiest to check for collisions by assuming a rectangular boundary (i.e. a bounding box) around each object, and testing those rectangles for intersections. This is both easy to write and efficient to compute, and although it may not be 100% faithful to the shape of the object, in most cases it’s good enough.

To see how this works, we’ll draw two rectangles, and test whether they intersect. We’ll start off with the following code, which is quite similar to what we had in earlier SDL2 articles here:

    // variables

    bool quit = false;
    SDL_Event event;
    int x = 288;
    int y = 208;

    // init SDL

    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window * window = SDL_CreateWindow("SDL2 Bounding Box Collision Detection",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_Rect rect1 = { x, y, 100, 100 };
    SDL_Rect rect2 = { 50, 50, 100, 80 };

    // handle events

    while (!quit)
    {
        SDL_Delay(10);
        SDL_PollEvent(&event);

        switch (event.type)
        {
            case SDL_QUIT:
                quit = true;
                break;
            // TODO keyboard input handling goes here
        }

        // TODO rendering & collision detection goes here
    }

    // cleanup SDL

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;

This doesn’t do anything other than render an empty window. We can draw a couple of rectangles by using SDL_RenderFillRect(). Add the following code in the place of the rendering and collision detection comment:

        SDL_SetRenderDrawColor(renderer, 242, 242, 242, 255);
        SDL_RenderClear(renderer);

        SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
        SDL_RenderFillRect(renderer, &rect1);

        SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
        SDL_RenderFillRect(renderer, &rect2);

        SDL_RenderPresent(renderer);

First we’re clearing the window to a light grayish colour with SDL_RenderClear(), and then we’re drawing two rectangles (one blue, one green) using SDL_RenderFillRect(). Before each of these calls, we must set the drawing colour using SDL_SetRenderDrawColor(). Finally, SDL_RenderPresent() will render everything to the window.

Now we have two rectangles:

Adding some simple keyboard handling code (as per “Handling Keyboard and Mouse Events in SDL2“) will allow us to move the green rectangle with the arrow keys on the keyboard:

        switch (event.type)
        {
            case SDL_QUIT:
                quit = true;
                break;
            case SDL_KEYDOWN:
                switch (event.key.keysym.sym)
                {
                    case SDLK_LEFT:  rect1.x--; break;
                    case SDLK_RIGHT: rect1.x++; break;
                    case SDLK_UP:    rect1.y--; break;
                    case SDLK_DOWN:  rect1.y++; break;
                }
                break;
        }

Now we can work on the actual collision detection: if you move the green rectangle such that it hits the blue one, we’ll change the colour of both to red. We could write the code to check whether the rectangles overlap (e.g. as in Lazy Foo’s collision detection tutorial), but why bother? SDL2 gives us a handy SDL_HasIntersection() function that we can use out of the box. Our rendering and collision detection code changes thus:

        SDL_bool collision = SDL_HasIntersection(&rect1, &rect2);

        SDL_SetRenderDrawColor(renderer, 242, 242, 242, 255);
        SDL_RenderClear(renderer);

        if (collision)
            SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        else
            SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
        SDL_RenderFillRect(renderer, &rect1);

        if (collision)
            SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        else
            SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
        SDL_RenderFillRect(renderer, &rect2);

        SDL_RenderPresent(renderer);

This code simply decides what colour to draw for each rectangle based on whether a collision occurred. Sure enough, when you drive the green rectangle into the blue one, both change to red:

Sweet! In this article, we learned how to draw rectangles and check whether they intersect using functions that SDL2 provides. Rectangle intersection is a simple way of checking for collision detection between the bounding boxes of objects in a 2D game. This is a simple and fast approach that works well enough for most situations. Sometimes though, you may need to use more appropriate geometry (e.g. a bounding circle works best for a ball).

The Dangers of async void Event Handlers

When using async/await, you’ll want to use async Task methods most of the time, and use async void methods only for event handlers (see “Async/Await – Best Practices in Asynchronous Programming“, by Stephen Cleary, MSDN Magazine, March 2013).

This conventional wisdom works great if you’re building something like a WPF (GUI) application, and event handlers are invoked occasionally as a result of user interaction (e.g. user presses a button, and an event fires). However, there is another class of event handlers that are invoked as part of a dispatcher loop in a third-party library. async void can be pretty dangerous in these cases.

async void Event Handlers in RabbitMQ

Let’s take the example of RabbitMQ. We’ll set up a basic publisher and consumer. A fundamental property of message queues is that messages are delivered in order, and that’s what we expect to happen.

First, install the RabbitMQ Client library via NuGet:

Install-Package RabbitMQ.Client

Then, we can set up a basic publisher and consumer:

        static void Main(string[] args)
        {
            Console.Title = "async RabbitMQ";

            var factory = new ConnectionFactory();

            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                const string queueName = "testqueue";

                // create queue if not already there

                channel.QueueDeclare(queueName, true, false, false, null);

                // publish

                var props = channel.CreateBasicProperties();
                    
                for (int i = 0; i < 5; i++)
                {
                    var msgBytes = Encoding.UTF8.GetBytes("Message " + i);
                    channel.BasicPublish("", queueName, props, msgBytes);
                }

                // set up consumer

                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += Consumer_Received;
                channel.BasicConsume("testqueue", true, consumer);

                Console.ReadLine();
            }
        }

Our consumer will call the Consumer_Received event handler whenever a message is received. This is the first version of the event handler:

        private static void Consumer_Received(object sender, BasicDeliverEventArgs e)
        {
            var body = e.Body;
            var content = Encoding.UTF8.GetString(body);

            Console.WriteLine("Began handling " + content);

            Thread.Sleep(1000);

            Console.WriteLine("Finished handling " + content);
        }

If we run this now, the messages are processed one at a time and in order just as we expect:

rabbitmq-async-sync

Now, let’s change the event handler to an asynchronous one:

        private static async void Consumer_Received(object sender, BasicDeliverEventArgs e)
        {
            var body = e.Body;
            var content = Encoding.UTF8.GetString(body);

            Console.WriteLine("Began handling " + content);

            await Task.Delay(1000);

            Console.WriteLine("Finished handling " + content);
        }

If we run this now…

rabbitmq-async-async

…we see that our concurrency and ordering guarantees have just gone out the window.

Understanding async void, Revisited

In my recent article, “In-Depth Async in Akka .NET: Why We Need PipeTo()“, I explained what happens when you call async void methods. Let’s recap that.

Say we have this program. We’re calling an async void method in a loop.

        static void Main(string[] args)
        {
            Console.Title = "async void";

            for (int i = 0; i < 5; i++)
                RunJob("Job " + i);

            Console.ReadLine();
        }

        static async void RunJob(string str)
        {
            Console.WriteLine("Start " + str);

            await Task.Delay(1000);

            Console.WriteLine("End " + str);
        }

When you call an async void method, it’s done in a fire-and-forget manner. The caller has no way of knowing whether or when the operation ended, so it just resumes execution immediately, rather than waiting for the async void method to finish. So you end up with parallel and interleaved execution such as this:

rabbitmq-async-asyncvoid

If we change RunJob() to be synchronous instead…

        static void RunJob(string str)
        {
            Console.WriteLine("Start " + str);

            Thread.Sleep(1000);

            Console.WriteLine("End " + str);
        }

…you’ll see that everything happens one at a time and in order:

rabbitmq-async-sync2

So you have to be really careful when using async void:

  1. There is no way for the caller to await completion of the method.
  2. As a result of this, async void calls are fire-and-forget.
  3. Thus it follows that async void methods (including event handlers) will execute in parallel if called in a loop.
  4. Exceptions can cause the application to crash (see the aforementioned article by Stephen Cleary for more on this).

Fixing async void event handlers

Despite these problems, if you want to await in your event handler, you have to make it async void. To prevent parallel and interleaved execution, you have to lock. However, you can’t await in a lock block, so you need to use a different synchronisation mechanism such as a semaphore.

My own Dandago.Utilities provides a ScopedAsyncLock that allows you to neatly wrap the critical section in a using block:

        private static ScopedAsyncLockFactory factory = new ScopedAsyncLockFactory();

        private static async void Consumer_Received(object sender, BasicDeliverEventArgs e)
        {
            using (var scopedLock = await factory.CreateLockAsync())
            {
                var body = e.Body;
                var content = Encoding.UTF8.GetString(body);

                Console.WriteLine("Began handling " + content);

                await Task.Delay(1000);

                Console.WriteLine("Finished handling " + content);
            }
        }

Like this, messages are consumed one at a time, and in order:

rabbitmq-async-scopedasynclock

ScopedAsyncLockFactory uses a semaphore underneath, so don’t forget to dispose it!

Getting Started with Microsoft Orleans

Microsoft Orleans is an actor model implementation for the .NET platform. The main idea of an actor model is that you distribute your computation across a number of fine-grained elements (called actors, or in Orleans, grains) which communicate between each other using message passing, and can each execute only one message at a time. This altogether avoids any need for multithreading synchronisation, and promotes distribution of computation even across physical machines.

The Orleans team have gone to great lengths to develop an API that is friendly to .NET developers, and which hides much of the complexity of building distributed systems. In this article, I hope to get you up and running with Orleans in no time.

The source code for the latter part of this article is available at the Gigi Labs BitBucket repository.

The Visual Studio Extension

If you download and install the Microsoft Orleans Tools for Visual Studio extension, you’ll get a few project templates that you can use to easily create new Orleans projects:

orleans-setup-templates

This is not strictly necessary, and I will show you how to create Orleans projects without it. But it’s quite convenient to have.

The Dev/Test Host project

A really quick way to start playing with Microsoft Orleans is to create a project of type Orleans Dev/Test Host. This is one of the project types provided by the Visual Studio extension (see previous section), and it will generate a bunch of infrastructure code (Program.cs and OrleansHostWrapper.cs) that you can use as-is. In fact, just go ahead and run it:

orleans-setup-quickrun

Just give it a few seconds; Orleans will perform some initialisation tasks, and then tell you that you have a silo running. Orleans applications typically involve a client (a regular console application, Web API, etc which communicates with Orleans) and a server (known as a silo, where all the Orleans magic happens). The Orleans Dev/Test Host is simply a way of having both in the same project.

Hello World

Among the code generated with the Orleans Dev/Test Host template, you’ll find a Main() method that looks something like this:

        static void Main(string[] args)
        {
            // The Orleans silo environment is initialized in its own app domain in order to more
            // closely emulate the distributed situation, when the client and the server cannot
            // pass data via shared memory.
            AppDomain hostDomain = AppDomain.CreateDomain("OrleansHost", null, new AppDomainSetup
            {
                AppDomainInitializer = InitSilo,
                AppDomainInitializerArguments = args,
            });

            var config = ClientConfiguration.LocalhostSilo();
            GrainClient.Initialize(config);

            // TODO: once the previous call returns, the silo is up and running.
            //       This is the place your custom logic, for example calling client logic
            //       or initializing an HTTP front end for accepting incoming requests.

            Console.WriteLine("Orleans Silo is running.\nPress Enter to terminate...");
            Console.ReadLine();

            hostDomain.DoCallBack(ShutdownSilo);
        }

We can put some of our own code instead of that comment. For this, we’ll need to create an interface:

    public interface IPerson : IGrainWithStringKey
    {
        Task SayHelloAsync(string message);
    }

One important thing to note at this stage is that interfaces used by Orleans grains must always return a Task (or Task<T>), because Orleans enforces asynchrony on its actors/grains.

Another thing to note is the IGrainWithStringKey interface we’re extending. All grains have an identifier (that’s how we’re able to find them from our code); identifiers may be of type string (as in this case), Guid, long, or a special compound type.

Next, we can create a class that implements this interface:

    public class PersonGrain : Grain, IPerson
    {
        public Task SayHelloAsync(string message)
        {
            string name = this.GetPrimaryKeyString();
            Console.WriteLine($"{name} says: {message}");

            return TaskDone.Done;
        }
    }

We’re deriving our class from Orleans’ Grain type, and we’re implementing the interface we just declared. We’re getting the grain’s identifier using the GetPrimaryKeyString() method before writing out a message. The TaskDone.Done is simply a utility task that you can return from non-async methods. Similar to the Task.CompletedTask that was introduced in .NET 4.6, this is just a convenient way to avoid doing something like Task.FromResult(0) all the time.

With that done, all we need to do is replace the comment in Main() with code such as the following:

            var joe = GrainClient.GrainFactory.GetGrain<IPerson>("Joe");
            joe.SayHelloAsync("Hello!");

This gets an instance of a grain that implements IPerson, with identifier “Joe”. The grain will be created if it doesn’t already exist; Orleans abstracts out the creation and destruction of actors. Once we have an instance, we can call methods on it. They are all asynchronous, but whether you will await them depends very much on the type of application you will be writing.

orleans-setup-hello

This is already enough for you to go on experimenting with Orleans. In the next sections (which you can safely skip if you’re just starting out), I will explain how to build out a proper project structure.

Grain Class and Grain Interface projects

There are two other project types you get with the Visual Studio extension: Orleans Grain Class Collection, and Orleans Grain Interface Collection. As your project starts to grow, you should move your grain classes and interfaces out into these project types, so that your main application consists solely of client code that interacts with Orleans via the GrainClient.GrainFactory.

NuGet packages

If you don’t want to use the Visual Studio extension, you can create regular class libraries or console applications, and just add in the necessary NuGet packages. These are the projects you need to create and the NuGet packages you need to install for each:

Purpose Type NuGet package References
Client Console Application Microsoft.Orleans.Client Interfaces
Silo Console Application Microsoft.Orleans.Server Interfaces, Grains
Grains Class Library Microsoft.Orleans.Core
Microsoft.Orleans.OrleansCodeGenerator.Build
Interfaces
Interfaces Class Library Microsoft.Orleans.Core
Microsoft.Orleans.OrleansCodeGenerator.Build

While the Microsoft.Orleans.OrleansCodeGenerator.Build package is not strictly necessary, it enables code generation for grains and grain interfaces at build time, which is better than having to do it at runtime.

A More Complete Project Structure

The rest of what we need to do to make this application work (whether using the Visual Studio extension or not) is described in the Minimal Orleans Application tutorial. I’m going to adapt it so that we have separate projects for client and silo/host (which is usually the case in real applications), to use XML configuration throughout, to fit our earlier IPerson example, and to retry to connect from the client to the silo until the silo is up.

The Silo needs the following Garbage Collection configuration to go into its App.config:

<configuration>
  <runtime>
    <gcServer enabled="true"/>
    <gcConcurrent enabled="false"/>
  </runtime>
</configuration>

Add a file called OrleansConfiguration.xml to the Silo and set it to Copy always:

<?xml version="1.0" encoding="utf-8"?>
<OrleansConfiguration xmlns="urn:orleans">
  <Globals>
    <SeedNode Address="localhost" Port="11111" />
  </Globals>
  <Defaults>
    <Networking Address="localhost" Port="11111" />
    <ProxyingGateway Address="localhost" Port="30000" />
  </Defaults>
</OrleansConfiguration>

Silo configuration needs (at a minimum) two things: an endpoint for inter-silo communication (that’s the Networking element) and an endpoint that clients outside the silo can use to talk to it (ProxyingGateway). In other words, our Client needs to talk to the Silo on port 30000.

In fact, we will now add a ClientConfiguration.xml file to the Client (set this also to Copy always):

<ClientConfiguration xmlns="urn:orleans">
  <Gateway Address="localhost" Port="30000"/>
</ClientConfiguration>

The PersonGrain class we saw earlier needs to go in the Grains project, and the IPerson interface needs to go in the Interfaces project.

Our program logic will look something like this (basically adapted from the Minimal Orleans Application tutorial, but without the client code):

    class Program
    {
        static SiloHost siloHost;

        static void Main(string[] args)
        {
            Console.Title = "Silo";

            // Orleans should run in its own AppDomain, we set it up like this
            AppDomain hostDomain = AppDomain.CreateDomain("OrleansHost", null,
                new AppDomainSetup()
                {
                    AppDomainInitializer = InitSilo
                });

            Console.WriteLine("Orleans Silo is running.\nPress Enter to terminate...");
            Console.ReadLine();

            // We do a clean shutdown in the other AppDomain
            hostDomain.DoCallBack(ShutdownSilo);
        }

        static void InitSilo(string[] args)
        {
            siloHost = new SiloHost(Dns.GetHostName());
            siloHost.LoadOrleansConfig();

            siloHost.InitializeOrleansSilo();
            var startedok = siloHost.StartOrleansSilo();
            if (!startedok)
                throw new SystemException(String.Format("Failed to start Orleans silo '{0}' as a {1} node", siloHost.Name, siloHost.Type));
        }

        static void ShutdownSilo()
        {
            if (siloHost != null)
            {
                siloHost.Dispose();
                GC.SuppressFinalize(siloHost);
                siloHost = null;
            }
        }
    }

Program logic in the Client should look something like this:

        static void Main(string[] args)
        {
            Console.Title = "Client";

            var config = ClientConfiguration.LoadFromFile("ClientConfiguration.xml");

            while (true)
            {
                try
                {
                    GrainClient.Initialize(config);
                    Console.WriteLine("Connected to silo!");

                    var friend = GrainClient.GrainFactory.GetGrain<IPerson>("Joe");
                    var result = friend.SayHelloAsync("Hello!");

                    Console.ReadLine();
                    break;
                }
                catch (SiloUnavailableException)
                {
                    Console.WriteLine("Silo not available! Retrying in 3 seconds.");
                    Thread.Sleep(3000);
                }
            }
        }

Set both the Silo and Client as startup projects, and run them. The silo will take a few seconds to initialise, and the client will keep trying to reach it until it’s up:

orleans-setup-dual