tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

Amazon AWS's .NET SDK knows how to implement asynchronous operations. Not!

Published 27 Nov 2013 in AWS, Best practice or not?, Cloud, Multithreading/Parallelism/Asynchronous/Concurrency, and Storage & Backup

Recently I was working on an application of my own and as I was in it I decided to check what updates to NuGet packages are available. I like to keep up to date to avoid any huge updates and surprises. And I also noticed AWS SDK had a new version, new major version.

Little bit worried about some breaking changes, but anyway I decided to update. The application uses AWS S3 heavily so new code shouldn’t hurt. After solving some compilation errors as some changes were, of course, breaking, I realized I see in IntelliSense methods with Async suffix. Great I thought; I can get rid of some of my helpers and very likely the finally implemented asynchronous operations properly. Before, using the BeginXxx and EndXxx was wokring, but these were sometimes blocking or spinning new threads. Definitely something you don’t want when trying to scale with limited resources.

As I started changing the methods and removing explicit callbacks I started also small testing to see how it performs. What a (bad) surprise I saw, when the results and resource usage was not what I would expect from nice fully (given a lot of it is actual HTTP calls to AWS) asynchronous code. It was time to dive into code. :) After walking through code a little I started to see crazy stuff. Like crazy. Let’s say you want to upload some file to S3, without too much hassle. There’s a TransferUtility class and part of it is visible here. If you’ll jump to ExecuteAsync method, which is suspicious anyway, you find this (you can click on link before to see the code directly or on image below):

AWS SDK ExecuteAsync

Who the hell was implementing that? It’s starting a new task (that’s ultimately going to be executed somewhere, very likely ThreadPool) and then spinning a new Thread followed by immediate blocking (calling Join). The method being called is blocking as well, because the signature is Func<T>. That’s like a nightmare. Creating threads, blocking, :o :/.

Given Amazon AWS is one of, let’s say, top 3 players in cloud today I would expect the code to have at least “some” quality. To be honest, I was playing even for a while with the idea of implementing it properly, at least in S3 I use. But then I realized that with my limited free time I would rather spend it on ID3 renamer or FirebirdSql.Data.FirebirdClient (or NuoDb.Data.Client).

And I also moved storage for this application to Azure. :) So far no nasty surprise.