Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • Richard 10:40 am on July 30, 2014 Permalink | Log in to leave a Comment  

    Improving Orleans Silo Startup Times 

    The startup times for Orleans Silos seems a bit variable. I’ve tried a few things out, and got the startup time down when using the Dev/Test Silo. I don’t know if all of these make a difference, but they might be worth trying if you’re as impatient as me.

    • Remove any Storage Providers you’re not using from the configuration.
    • Turn off logging (unless things aren’t working!) by setting TraceToConsole="false" and TraceToFile="false" in the Tracing element.
    • If you’re not putting any client code in the Dev/Test Silo (perhaps you’re connecting another application such as an ASP.NET) then remove the Orleans.OrleansClient.Initialize("DevTestClientConfiguration.xml"); line from Main.cs.
    • Remove any Grain Collection classes you’re not using from the Orleans SDK\LocalSilo\Applications directory.
    • Delete the Orleans.FSharp.dll from SDK\LocalSilo.

    I’ve got startup time down to under 6 seconds.

    My DevTestServerConfiguration.xml file looks like this:

    <?xml version="1.0" encoding="utf-8"?>
    <OrleansConfiguration xmlns="urn:orleans">
      <Globals>
        <StorageProviders>
          <Provider Type="Orleans.Storage.MemoryStorage" Name="AzureStore" />
        </StorageProviders>
        <SeedNode Address="localhost" Port="11111" />
      </Globals>
      <Defaults>
        <Networking Address="localhost" Port="11111" />
        <ProxyingGateway Address="localhost" Port="30000" />
        <Tracing DefaultTraceLevel="Error" TraceToConsole="false" TraceToFile="false"/>
        <Statistics WriteLogStatisticsToTable="false"/>
      </Defaults>
      <Override Node="Primary">
        <Networking Address="localhost" Port="11111" />
        <ProxyingGateway Address="localhost" Port="30000" />
      </Override>
    </OrleansConfiguration>
    

    My DevTestClientConfiguration.xml file looks like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <ClientConfiguration xmlns="urn:orleans">
      <GatewayProvider ProviderType="Config"/>
      <Gateway Address="localhost" Port="30000"/>
      <Tracing DefaultTraceLevel="Info" TraceToConsole="false" TraceToFile="false"/>
      <Statistics WriteLogStatisticsToTable="false"/>
    </ClientConfiguration>
    
     
  • Richard 2:20 pm on July 23, 2014 Permalink | Log in to leave a Comment  

    Using Observers for Pub Sub in Project Orleans 

    Orleans has a cool feature for pub-sub messaging. This allows you to register for grain originated events without you having to poll a grain. Instead you can asked to be called back when the interesting thing happens.

    To do this you create an ‘observer’ object. You then create a reference to this object, and pass it to the grain. The grain maintains a list of all observers. The grain can then send them all a message with a single call.

    To create an observer, create an interface which inherits from IGrainObserver. You should put this in your Grain Interfaces project.

    public interface IFooGrainObserver : IGrainObserver
    {
        void Foo(string message);
    }
    

    Note that the method signature for Foo returns void. This is a requirement for subscribers.

    Next create an implementation of this class. It doesn’t really matter which project you put this in. It’s probably best placed in the project where you want the code to actually run, so if you’re sending a message back to the client, put it alongside your clide code.

    class FooObserver : IFooGrainObserver
    {
        public void Foo(string message)
        {
            Console.WriteLine(message);
        }
    }
    

    We’ll need a grain which is going to receive the subscriptions, and perform the publication.

    This is the grain interface which has a method for registering a subscriber (Subscribe), and another to call when you wish to publish a message (Publish):

    public interface IPubSubGrain : IGrain
    {
        Task Subscribe(IFooGrainObserver observer);
        Task Publish(string message);
    }
    

    And this is the implementation:

    public class PubSubGrain : GrainBase, IPubSubGrain
    {
    
        ObserverSubscriptionManager<IFooGrainObserver> subscribers = new ObserverSubscriptionManager<IFooGrainObserver>();
    
        public Task Subscribe(IFooGrainObserver observer)
        {
            subscribers.Subscribe(observer);
            return TaskDone.Done;
        }
    
        public Task Publish(string message)
        {
            subscribers.Notify(x => x.Foo(message));
            return TaskDone.Done;
        }
    }
    

    Note that Orleans provides a ObserverGrainManager which helps you manage the subscriptions, and send notifications.

    Now to actually make this work.

    When the Grain Interfaces project compiles a factory is created for our subscriber (FooGrainObserverFactory) – just like the factories are created for the grains.

    To use the factory, we pass in an instance of our IFooGrainObserver interface (which will be a FooObserver). This will give us back an object we can then pass to the Subscribe method of our grain.

    This is the subscribe process complete. Now, just call publish.

    Your client code (perhaps this is in your Dev/Test Silo) will look something like this:

    var grain = PubSubGrainFactory.GetGrain(0);
    
    // register a subscriber.
    var observerRef = await FooGrainObserverFactory.CreateObjectReference(new FooObserver());
    await grain.Subscribe(observerRef);
    
    // send a publish
    await grain.Publish("Hello World");
    
    // Hello World is printed on the console by the instance of FooObserver
    

    Simple!

     
  • Richard 8:44 am on June 25, 2014 Permalink | Log in to leave a Comment  

    Orleans vs a Distributed Cache 

    I’m often asked what the difference is between Orleans and a distributed cache. It’s a good observation because on the face of it they have similar aims, to hold objects in memory for the right period of time to provide a performance benefit.

    However, there are a number of differences.

    1. The grains in Orleans are programmable, whereas caches normally just store data.
    2. With a distributed cache you keep objects in memory, but there’s a good chance that the data doesn’t reside on the same machine that’s serving the request. This means that machine processing the request has to retrieve the data from another node. Orleans will send the request to the machine which holds the data, which in theory should be more efficient.
    3. Orleans queues message to each grain and processes them one by one with a single threaded programming model. This stops concurrency problems and race conditions. With caches you have to build a locking system yourself, as described here for memcached.
    4. A grain can register a timer so it can call itself without requiring an external request. Caches generally just respond to external requests.

    People are certainly using Orleans as a cache, but I think it’s capable of much more.

     
    • Roger Alsing 11:02 am on June 25, 2014 Permalink | Log in to Reply

      On #3) my impression is that during a net split, Orleans can spawn the same virtual actor on each side of the network partition, and thus, break the fundamental single threaded behavior of actors.
      I Think Caitie McCaffrey taked about this during a Jepsen webcast.

      If this is true, you can still get race conditions and corrupted data

    • Graham Hay 3:34 pm on June 30, 2014 Permalink | Log in to Reply

      “stops concurrency problems and race conditions” is a bit optimistic :) It might remove certain categories of problems, if you’re lucky, but any interactions between grains will still be subject to the usual problems with distributed systems.

  • Richard 4:10 pm on June 19, 2014 Permalink | Log in to leave a Comment  

    Codename Orleans – Using Generics with Grains 

    In Orleans you can use generics with grain interfaces:

    public interface IGenericGrain<T> : Orleans.IGrain
    {
        Task SetValue(T value);
    
        Task GetValue();
    }
    

    When you talk to this grain from a client application, you can specify the value of ‘T’ on the factory class:

    var grain1 = GenericGrainFactory<int>.GetGrain(1);
    await grain1.SetValue(123);
    await grain1.GetValue();
    
    var grain2 = GenericGrainFactory<string>.GetGrain(2);
    await grain2.SetValue("foo");
    await grain2.GetValue();
    

    You can even extend ‘T’ to the persistence layer:

    public interface IMyGrainState<T> : IGrainState
    {
        T Value { get; set; }
    }
    
    [StorageProvider(ProviderName = "AzureStore")]
    public class GenericGrain<T> : Orleans.GrainBase<IMyGrainState<T>>, IDbGrain<T>
    {
        public Task SetValue(T value)
        {
            this.State.Value = value;
            return this.State.WriteStateAsync();
        }
    
        public Task GetValue()
        {
            return Task.FromResult(this.State.Value);
        }
    }
    

    This seems to work well for value types such as string, int, double etc…

    One word of caution; make sure that you always use the same value for ‘T’ when dealing with a particular grain ID, otherwise you’ll get cast exceptions.

     
  • Richard 1:12 pm on June 19, 2014 Permalink | Log in to leave a Comment  

    Running Codename Orleans on Ubuntu 

    Untitled

     

    Yesterday I did a presentation on Orleans. Afterwards I was chatting to Richard Conway. He told me he was thinking of getting Orleans to run on Linux to solve a data analytics problem. “Good luck” I said.

    Today I thought I’d give it a try. Here’s what I did:

    1. Built an Orleans project using Visual Studio.

    2. Took a blank Ubuntu 14 image.

    3. Installed Mono:

      $ sudo apt-get install mono-complete
    
    1. Copied the Orleans local silo binaries onto the Ubuntu machine. The files are located here:
      C:\Microsoft Codename Orleans SDK v0.9\SDK\LocalSilo\
    
    1. Copied the grains DLLs into the same ‘LocalSilo’ directory.

    (usually these are placed into an ‘Applications’ directory for you by a post-compilation step in the grain implementation project, but placing the binaries in this location didn’t seem to work for me).

    1. Started the Silo:
      $ mono OrleansHost.exe
    
    1. Started my client application in the same way:
      $ mono ConsoleApplication1.exe
    

    It just worked :¬)

    I don’t expect you’ll get any support running Orleans on Linux, but it’s interesting that you can!

    Note: I didn’t have any persistence providers configured in the ‘OrleansConfiguration.xml’ file.

     
  • Richard 3:28 pm on June 12, 2014 Permalink | Log in to leave a Comment  

    Reading the microphone’s audio stream in WinRT 

    I wanted to use the microphone on a Surface tablet to measure the audio level in the room. The technique I used was to implement my own stream, and then have the Microphone write to it.

    Set up the MediaCapture class as usual:

     

    var media = new MediaCapture();
    var captureInitSettings = new MediaCaptureInitializationSettings();
    captureInitSettings.StreamingCaptureMode = StreamingCaptureMode.Audio;
    await media.InitializeAsync(captureInitSettings);
    media.Failed += (_, ex) => new MessageDialog(ex.Message).ShowAsync();
    
    var stream = new AudioAmplitudeStream(); // custom stream implementation
    media.StartRecordToStreamAsync(MediaEncodingProfile.CreateWav(AudioEncodingQuality.Low), stream);
    stream.AmplitudeReading += AmplitudeReading; // get an amplitude event

     

    But you’ll notice I’m passing in an ‘AudioAmplitudeStream’. This is my custom stream implementation which just takes the average of the amplitude reported by the microphone. Here’s the code:

     

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using System.Threading.Tasks;
    using Windows.Storage.Streams;
    
    namespace IoT.WinRT
    {
        class AudioAmplitudeStream : IRandomAccessStream
        {
            public bool CanRead
            {
                get { return false; }
            }
    
            public bool CanWrite
            {
                get { return true; }
            }
    
            public IRandomAccessStream CloneStream()
            {
                throw new NotImplementedException();
            }
    
            public IInputStream GetInputStreamAt(ulong position)
            {
                throw new NotImplementedException();
            }
    
            public IOutputStream GetOutputStreamAt(ulong position)
            {
                throw new NotImplementedException();
            }
    
            public ulong Position
            {
                get { return 0; }
            }
    
            public void Seek(ulong position)
            {
    
            }
    
            public ulong Size
            {
                get
                {
                    return 0;
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
    
            public void Dispose()
            {
    
            }
    
            public Windows.Foundation.IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
            {
                throw new NotImplementedException();
            }
    
            public Windows.Foundation.IAsyncOperation FlushAsync()
            {
                return AsyncInfo.Run(_ => Task.Run(() => true));
            }
    
            public Windows.Foundation.IAsyncOperationWithProgress<uint, uint> WriteAsync(IBuffer buffer)
            {
    
                return AsyncInfo.Run<uint, uint>((token, progress) =>
                {
                    return Task.Run(() =>
                    {
                        using (var memoryStream = new MemoryStream())
                        using (var outputStream = memoryStream.AsOutputStream())
                        {
                            outputStream.WriteAsync(buffer).AsTask().Wait();
    
                            var byteArray = memoryStream.ToArray();
                            var amplitude = Decode(byteArray).Select(Math.Abs).Average(x => x);
    
                            if (AmplitudeReading != null) this.AmplitudeReading(this, amplitude);
    
                            progress.Report((uint)memoryStream.Length);
                            return (uint)memoryStream.Length;
                        }
                    });
                });
            }
    
            private IEnumerable Decode(byte[] byteArray)
            {
                for (var i = 0; i < byteArray.Length - 1; i += 2)
                {
                    yield return (BitConverter.ToInt16(byteArray, i));
                }
            }
    
            public delegate void AmplitudeReadingEventHandler(object sender, double reading);
    
            public event AmplitudeReadingEventHandler AmplitudeReading;
    
        }
    }
    

     

    The stream is only partially implemented, not all the calls are required.

    You can then subscribe to the event, and show the background noise level in your app!

     

    void AmplitudeReading(object sender, double reading)
    {
        Debug.WriteLine("Noise level: {0:0} dB", ToDb(reading));           
    }
    
    static double ToDb(double value)
    {
        return 20 * Math.Log10(Math.Sqrt(value * 2));
    }
    

    Here is a sample application: https://github.com/richorama/WinRTdB

    Have fun!

     
  • Richard 1:21 pm on June 10, 2014 Permalink | Log in to leave a Comment  

    Aggregating Results in Orleans 

    Orleans is great for maintaining hundreds of thousands of gains, each with their own internal state. However, it’s sometimes difficult to get aggregate figures out the system, such as the total for a particular value across all grains. You can’t practically make a fan out request to all grains to retrieve a value, firstly such a request would time out, secondly you probably don’t know what grains you’ve got. The answer is to set up a single grain, which all other grains will report to. We’ll look at a simple scenario to see how this could be done.

    Let’s suppose that we have grains that hold a score, and we’d like the total score for the entire system. Every time the score changes in the grains, we call a ‘total score grain’ which maintains the overall total. The grain looks like this:

     

        // Total Score Grain interface
        public interface ITotalScoreGrain : IGrain
        {
            Task AddScore(int value);
    
            Task GetTotalScore();
        }
    
    
        // Total Score Grain implementation
        public class TotalScoreGrain : GrainBase, ITotalScoreGrain
        {
            int total;
    
            public Task AddScore(int value)
            {
                this.total += value;
                return TaskDone.Done;
            }
    
            public Task GetTotalScore()
            {
                return Task.FromResult(total);
            }
        }
    

    This looks simple enough, but it’s a really bad idea, for a couple of reasons:

    • We now have a single grain acting as a bottleneck for the entire system. We’ve defeated the point in having a distributed system.
    • If you’re running the system on several servers, the chances are that the ‘total score grain’ will not be in the same silo as the grain calling it. This makes the call to the ‘total score grain’ a remote call, which is more expensive (takes more time).

    Let’s improve on this by introducing  a ‘sub total grain’ which will be responsible for collecting all scores from each silo, and reporting this up to the ‘total score grain':

        // Sub Total Grain interface
        [StatelessWorker]
        public interface ISubTotalGrain : Orleans.IGrain
        {
            Task AddScore(int value);
        }
    
        // Sub Total Grain implementation
        public class SubTotalGrain : GrainBase, ISubTotalGrain
        {
            int score;
    
            public override Task ActivateAsync()
            {
                RegisterTimer(SendUpdate, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
                return base.ActivateAsync();
            }
    
            async Task SendUpdate(object _)
            {
                if (score == 0) return;
                var totalScoreGrain = TotalScoreGrainFactory.GetGrain(0);
                await totalScoreGrain.AddScore(score);
                score = 0;
            }
    
            public Task AddScore(int value)
            {
                this.score += value;
                return TaskDone.Done;
            }
        }
    

    This grain has two interesting properties. First of all it’s a Stateless Worker (see the attribute on the interface), secondly it has a timer, so it doesn’t forward every score update on, it just updates some internal state, and forwards the information if required every 5 seconds. This means that:

    • The grain will auto scale as required, removing the bottleneck.
    • The grain will always be created in the local silo. Which removes the need for network hop to report score changes. The cross-silo hop will only be triggered every 5 seconds.

    This design introduces ‘eventual consistency’ to the total score, as the score could always be up to 5 seconds behind. However, the system should scale nicely with no bottlenecks.

    Is it right to store state in a Stateless Worker? It’s not the intention of Stateless Worker grains to be used in this way, but they are activated and work in the same way as normal grains, there are just multiple copies of them, and they’re created locally. This is fine if you can reconcile the state distributed across all the activations, which in our case is easy, because we can just add it up.

    Acknowledgements to Sergey Bykov for helping to foster the idea.

     

     
  • Richard 2:53 pm on April 16, 2014 Permalink | Log in to leave a Comment  

    Running Clojure on Azure Web Sites 

    The recent release of Java on Microsoft Azure Web Sites was a big one. Not only because there are a load of Java developers out there that can now get easy access to a great public cloud (and yes, Web Sites have sticky sessions out of the box) but the announcement is much more than just Java, it’s the Java Virtual Machine.

    The JVM is host to a number of interesting languages, so this announcement unlocks the potential to run thing likes Scala, Clojure, Groovy, JRuby, Jython and Kotlin on Azure Web Sites.

    I thought it would be fun to start with Clojure. It’s what Uncle Bob would do.

    This tutorial takes you from scratch to having a clojure ‘hello world’ running. I did this all from Windows 8, but I assume you could do this just as easily from any desktop operating system.

    Prerequisites

    Install Java

    Install Java SE Development Kit 7

    Install Clojure 1.6

    Install Leiningen

    Install Git

    (yes there’s a lot of installing)

    Create a Hello World Application

    We’ll use compojure to create a simple hello world app, and then create a war file.

    From the command prompt type this:

    > lein new compojure hello-world

    You can test your new web application by typing in:

    > cd hello-world
    > lein ring server

    … which will start the web server on port 3000.

    Now create a ‘war’ file, which we will use to deploy the application to Azure:

    > lein ring uberwar

    This should create something called target/hello-world-0.1.0-SNAPSHOT-standalone.war

    Creating the Azure Web Site from the Jetty Template

    The easiest way to get Java running is to take the existing Jetty template.

    In the Azure Portal go to ‘New’ and select Compute -> Web Site -> From Gallery.

    Select the ‘Jetty’ template (it’s in the ‘Templates’ sub section).

    Type in a unique url, and select a region, and click the ‘tick’ button to create the site.

    This will create a template website with the Jetty stuff already configured.

    Deploy to Azure

    To deploy our Clojure app, we need to put the war file in the right place in the Jetty template, and then push it up to Azure.

    In the portal navigate to the newly created website and click ‘Set up deployment from source control’ and select ‘Local Git repository’.

    This will take a few seconds, then give you a git url.

    Copy this url, and then from the command prompt, navigate out of the clojure app directory, and clone the website to a new directory (make sure the USERNAME and WEBSITENAME bit are correct for your site).

    > cd ..
    > git clone https://USERNAME@WEBSITENAME.scm.azurewebsites.net:443/WEBSITENAME.git
    > cd WEBSITENAME

    Now take the ‘target/hello-world-0.1.0-SNAPSHOT-standalone.war’ file, and save it in the ‘bin/jetty-distribution-9.1.2.v20140210/webapps’ directory as ‘ROOT.war’. This should replace the existing file.

    > git commit -am "added clojure war"
    > git push origin master

    And you’re done.  Navigate to the URL for your web site, and you should see ‘Hello World’.

    Conclusion

    It’s exciting to see Microsoft providing support for the JVM in Azure Web Sites. The JVM support a rich ecosystem of new languages and web frameworks, and deployment to Azure websites is a simple git push away.

    Oh, and Clojure is fun.

     
  • Richard 9:51 am on April 3, 2014 Permalink | Log in to leave a Comment  

    Microsoft Codename Orleans Public Preview 

    OrleansSDK_128x

    Yesterday at build the public preview of Micosoft’s Codename Orleans project was announced.

    You can download the Orleans binaries here:

    http://aka.ms/orleans

    The blog post on the .NET blog has more details:

    http://blogs.msdn.com/b/dotnet/archive/2014/04/02/available-now-preview-of-project-orleans-cloud-services-at-scale.aspx

    I was privileged enough to have early access to the project, and I wrote a few of the samples available in the Codeplex repository:

    https://orleans.codeplex.com/

     

    Why is Orleans Interesting?

    Orleans is ideally suited to problems requiring both high scale and low latency, but that doesn’t preclude you from using it at small scale.

    What Orleans does well is manage a large number of grains (the Orleans term for an actor) in memory, think hundreds of thousands of grains per server. It does this by managing the lifecycle of these objects, so they are only active when required, and after a certain period they can be garbage collected. Keeping these object in memory gives you low latency, as you can respond to requests on your system out of state you have in memory, rather than having to load information out of a database. It’s a bit like an in-memory cache in some regards, only the objects in the cache are programmable.

    Orleans can run on a cluster of machines (think hundreds of machines) to provide the high scale. The system has a fairly linear relationship between throughput and cluster size, which in plain english means that adding more machines to your cluster will increase your capacity, and doesn’t degrade too badly due to inter-server communication.

    Orleans is written in .NET, and you write your grains in C#. Grains are simply an interface and a class. The system is designed to be easy for the developer use. You don’t have to be a distributed system expert, those kinds of problems have been solved for you in the framework.

    Orleans will run on Windows Server, but it’s really designed for Azure. It’s a simple xcopy deploy to install, and comes with libraries designed to work with Worker Roles. You’ll need to front Orleans with your own API, which will have to be .NET (probably ASP.NET/WebAPI).

    Orleans gives you some constraints you must work within. You cannot have any shared state between grains, and all code must be asynchronous.

    However Orleans gives you some good guarantees. These are that there will only ever be one instance of a grain of a given identity and that the code in the grain will only run in a single thread (you can have exceptions to these rules). This means you don’t have to worry about thread safety, locking and parallel programming. You just write simple class implementations.

    Single threaded async, it sounds a bit like node.js doesn’t it? It even has the node hexagons. This is probably the reason I like Orleans so much!

    What next?

    Watch this space. I expect a small ecosystem of tools and libraries to grow up around Orleans, let me know if you’re interested.

     
  • Richard 2:52 pm on February 20, 2014 Permalink | Log in to leave a Comment  

    Async weirdness 

    What would you expect this program to print? (it’s set to .NET Framework 4.5 as the target framework)

    Untitled

    I’m not a world leading expert on C#, but I would expect to see this:

      null
      World

    But this is actually what you get:

      World
      World

    The program attempts to read the value of ‘Result’ while the task is delayed. The program then blocks at this point, waiting for the delay to elapse. It then doesn’t need to ‘Wait’, because the task has already completed.

    You don’t need to call ‘Wait’ at all. The ‘Result’ property will ‘Wait’ for you when you try to read it.

    I think it’s generally assumed that reading a property isn’t an expensive operation, so this behaviour came as quite a surprise to me (thanks Rob Blackwell for pointing it out). I can understand the motivation for this behaviour, it makes code less buggy, but it strikes me as odd.

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
Follow

Get every new post delivered to your Inbox.

Join 565 other followers