Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • Richard 10:22 am on August 13, 2014 Permalink | Log in to leave a Comment  

    Public IP Addresses for Amazon 

    I previously blogged about the public IP address ranges for Azure.

    The public IP addresses ranges for Amazon has recently been updated. Amazon has over 8 million addresses, which is 8 times the number Azure has.

    Interestingly, these are not so evenly distributed:

    Untitled

    Raw data:

    DC Total public IP addresses
    US East (Northern Virginia) 3694592
    US West (Oregon) 1507328
    EU (Ireland) 1332224
    Asia Pacific (Tokyo) 739328
    US West (Northern California) 655360
    Asia Pacific (Sydney) 327680
    Asia Pacific (Singapore) 313344
    South America (Sao Paulo) 245760
    China (Beijing) 65536
    GovCloud 16384
    TOTAL 8897536

    I have also updated my tool to look up which DC a website is hosted in, to include the Amazon IP ranges.

     
  • Richard 11:12 am on August 7, 2014 Permalink | Log in to leave a Comment  

    Enabling SSL for Self Hosted Nancy 

    One of the things I like about Nancy is the ease of creating self hosted HTTP services.

    Here’s how to enable HTTPS for your service.

    First of all, create your SSL certificate:

    $ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem
    $ openssl pkcs12 -export -in cert.pem -inkey key.pem -out mycert.pfx
    

    Then go to ‘Manage Computer Certificates’ in the start menu (I’m using Windows 8.1).

    Right click on ‘Personal’ and import the freshly created mycert.pfx.

    Untitled

    Now go to your newly installed certificate, and get the thumbprint:

    Untitled2

    Now you need to register the URL with Windows:

    $ netsh http add urlacl url=https://+:4443/ user=YOUR_USERNAME
    $ netsh http add sslcert ipport=0.0.0.0:4443 certhash=‎YOUR_THUMBPRINT_WITHOUT_SPACES appid={06aabebd-3a91-4b80-8a15-adfd3c8a0b14} 
    

    You need to substitute your username, and the certificate thumbprint you copied (without the spaces)

    The appid is just a random guid, feel free to create your own.

    Now start nancy on this Uri https://localhost:4443/.

    using (var host = new NancyHost(new Uri("https://localhost:4443/")))
    {
        host.Start();
        Console.ReadKey();
    }
    
     
  • Richard 9:00 am on August 4, 2014 Permalink | Log in to leave a Comment  

    Public IP Addresses for Microsoft Azure 

    Microsoft publish a list of public IP addresses for the compute services hosted in their Azure Datacenters. When they say ‘compute’ they also include SQL Database, and the storage accounts seem to be included too.

    I thought it would be interesting to write a script to count the total number of IP addresses available for each DC.

    Here’s a pretty graph.

    Untitled

    Whilst the number of public IPs is no way of working out the number of machines provisioned in each DC, it does at least give you an idea of the magnitude of each of the regions.

    Some interesting things to note:

    1. The EU data centers are similar sizes, Dublin being slightly bigger.
    2. The 5 DCs in Asia, Brazil and Japan added together are smaller than US West.
    3. The total number of IPs is just over 1 million.
    4. There seems to be a step change between the largest 6, the next 4, and then the 3 small (and new) DCs in Japan and Brazil.
    5. US West is 28 times larger than Brazil South.
    6. Almost 60% of the IPs are in the USA.

    Here’s my processed data in table:

    DC Total public IP addresses
    uswest 179504
    useast 155808
    europenorth 150400
    europewest 144320
    usnorth 118112
    ussouth 109120
    asiaeast 62384
    uscentral 62336
    asiasoutheast 57440
    useast2 46832
    japanwest 18912
    japaneast 10976
    brazilsouth 6288
    TOTAL 1122432

    I think it will be really interesting to keep an eye on the IP ranges, and see how they change over time (or is it just me?).

    I also published a tool to look up if an IP (or domain name) is hosted in Azure, it also tells you which DC it’s in.

     
  • 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.

     

     
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 574 other followers