Wednesday, December 16, 2015

2015 Retrospective

Wow! This is my 200th post, and the exact 7 year anniversary of when I started blogging!

Blog

Blogging for seven years straight has been quite a challenge, but it has also been one of most rewarding things that I have ever done. It has become a regular occurrence for me to answer questions at work with "oh, I have a blog post about that!"

I work best when I have deadlines and quotas, and I am very happy to have written three posts per month this year. I think that this pace has been perfect; enough to keep me busy and share plenty of information, but still not so much that I didn't have time to really fill out the content.

I intend to continue writing three posts per month in 2016.

QQ-Cast

Unfortunately, despite how much fun we had in 2014, the QQ-Cast got put on hiatus for most of 2015. This was not something that Jordan and I wanted to do, but as we say on the show "life got in the way." Jordan became a father, and I...well we will get to that in a moment.

Good news dear listener, we're back! My friend Zach Mayer and I have just started recording again. We are continuing the tradition of being iterative, so we will be making several tweaks to the show format. I'm very happy to be recording again, and can't wait to see how 2016 goes.

Professional

2015 was yet another crazy year for me professionally, and I wouldn't have it any other way! My company launched an amazing number of products, and I am very proud to have directly contributed to several of those launches.

My team and I have been focusing heavily automation and performance testing, and it is an absolute blast! We get to engage with engineers from around the company, we get to play with a diverse set of tech stacks, and I just love every minute of it.

At the time of writing this we have openings for C#, C++, and Node.js...so come work with us!

Personal

2015 has been a rough year for me personally. Tragedy struck my wife and I in April, and we have been struggling to recover ever since. Frankly, I cannot help but be glad that 2015 is over, and I can only hope that 2016 goes...better.

On the plus side, after being on the bench for four years, I have finally started to play soccer again! It's been an absolutely blast to just run around and kick the ball again. What's next? Rock climbing? Sailing? Spelunking? Let's find out!

Thanks again,
Tom

Sunday, December 13, 2015

WebSocket4Net Extensions: OpenAsync

I recently talked about .NET WebSocket Libraries, and how I like using WebSocket4Net as a .NET WebSocket client. That library is great, but really wanted it to have two additional features:

  1. Retry logic for opening a connection.
  2. An OpenAsync method.

...so I created an extension method that does both!

WebSocket4Net Extensions

public static class WebSocketExtensions
{
    public static async Task OpenAsync(
        this WebSocket webSocket,
        int retryCount = 5,
        CancellationToken cancelToken = default(CancellationToken))
    {
        var failCount = 0;
        var exceptions = new List<Exception>(retryCount);
 
        var openCompletionSource = new TaskCompletionSource<bool>();
        cancelToken.Register(() => openCompletionSource.TrySetCanceled());
 
        EventHandler openHandler = (s, e) => openCompletionSource.TrySetResult(true);
 
        EventHandler<ErrorEventArgs> errorHandler = (s, e) =>
        {
            if (exceptions.All(ex => ex.Message != e.Exception.Message))
            {
                exceptions.Add(e.Exception);
            }
        };
 
        EventHandler closeHandler = (s, e) =>
        {
            if (cancelToken.IsCancellationRequested)
            {
                openCompletionSource.TrySetCanceled();
            }
            else if (++failCount < retryCount)
            {
                webSocket.Open();
            }
            else
            {
                var exception = exceptions.Count == 1
                    ? exceptions.Single()
                    : new AggregateException(exceptions);
 
                var webSocketException = new WebSocketException(
                    "Unable to connect", 
                    exception);
 
                openCompletionSource.TrySetException(webSocketException);
            }
        };
 
        try
        {
            webSocket.Opened += openHandler;
            webSocket.Error += errorHandler;
            webSocket.Closed += closeHandler;
 
            webSocket.Open();
 
            await openCompletionSource.Task.ConfigureAwait(false);
        }
        finally
        {
            webSocket.Opened -= openHandler;
            webSocket.Error -= errorHandler;
            webSocket.Closed -= closeHandler;
        }
    }

Enjoy,
Tom

Monday, November 30, 2015

.NET Semaphore Slim that Supports Keys

While making a HUGE update to my CacheRepository project, I needed a way to have a dynamic number of semaphores that would lock on a specified cache key. The SemaphoreSlim is great, but I needed a wrapper around it that allowed me have one for each unique cache key being fetched.

The easiest solution was just to have a concurrent dictionary of string to semaphore, but at high load that would grow in size and I did not want to waste memory. Instead I created a class that does keep a dictionary of semaphores, but then removes them from the dictionary and stores them in a queue for reuse once there is nothing locking off on them.

Enough talking! Below is the code, and as always it comes with unit tests! :)

Sunday, November 29, 2015

Obsolete Blog Posts

I was recently asked an interesting question:

"Are there any blog posts you wrote that you no longer agree with?"

Yes there are. As I have grown as a developer there are many patterns and practices that I have changed my opinions about. Also, many of my posts are related to specific technologies that have grown, changed, or become deprecated over time.

Here is a small list of posts on my blog that I now consider to be obsolete.

Going back through these posts to write this post has made me notice a common theme as I grow: I continue to advocate simpler solutions to problems. I like that trend, and I can't wait to see what I am writing about in another 7 years.

Live and learn,
Tom

Wednesday, November 25, 2015

.NET WebSocket Libraries

WebSockets are awesome, and you should be using them. If you are working with .NET, then there are some very easy to consume libraries to help you host a WebSocket server or connect as a WebSocket client.

Below is a complete chat server and client made using ONLY these two libraries.

Saturday, October 31, 2015

How to change HttpClientHandler.AllowAutoRedirect

In the past I have talked about how the HttpClient is thread safe. This allows you to reuse the same HttpClient and be very efficient regarding how many ephemeral ports your application consumes.

Because the HttpClient and the HttpClientHandler both need to be thread safe, their properties become immutable after a request has been issued. If you are in a scenario where you need to change settings, such as whether or not the handler allows redirects, you will have to develop a little hack to work around the default behavior.

Below is a method where you can use reflection to set a private field and avoid the property setter from checking whether or not a request has been issued. This could cause thread safety issues, however with the current implementation of HttpCliehtHandler it is perfectly safe so long as only one thread is consume the client at a time.

HttpClientHandler Extension

public static class HttpClientHandlerExtensions
{
    private static readonly FieldInfo AllowAutoRedirectFieldInfo =
        typeof (HttpClientHandler).GetField(
            "allowAutoRedirect",
            BindingFlags.Instance | BindingFlags.NonPublic);
 
    public static void SetAllowAutoRedirect(this HttpClientHandler handler, bool value)
    {
        AllowAutoRedirectFieldInfo.SetValue(handler, value);
    }
}

Unit Test

public class HttpClientHandlerExtensionsTests
{
    [Fact]
    public async Task SetAllowAutoRedirectTest()
    {
        using (var handler = new HttpClientHandler())
        using (var client = new HttpClient(handler))
        {
            handler.AllowAutoRedirect = true;
 
            using (var response = await client.GetAsync("http://www.google.com"))
                response.EnsureSuccessStatusCode();
 
            Assert.Throws<InvalidOperationException>(() =>
            {
                handler.AllowAutoRedirect = false;
            });
 
            handler.SetAllowAutoRedirect(false);
        }
    }
}

Enjoy,
Tom

Sunday, October 25, 2015

Override Configuration via Command Line

In my previous blog posts I have talked about creating complex config objects from your app.config file, as well as how to have cascading configuration settings from multiple files. Now I want to build on that concept by taking in configuration from command line in a generic fashion that will override your other cascading settings.

Configuration Object

public class TestConfig
{
    public string Hello { get; set; }
    public string Goodnight { get; set; }
}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="TestConfig.Hello" value="World" />
    <add key="TestConfig.Goodnight" value="Moon" />
  </appSettings>
</configuration>
Real Time Web Analytics