DCSIMG
January 2013 - Posts - All Your Base Are Belong To Us

All Your Base Are Belong To Us

Mostly .NET internals and other kinds of gory details

January 2013 - Posts

Using Something You Can't Implement Yourself

I have found that the biggest obstacle I face when adopting a new language, technology, or framework is using something I don't fully understand how to implement myself. I read hundreds of blog posts every week talking about language extensions to JavaScript, cool new iOS application frameworks, and brand-new SaaS offerings on top of Windows Azure -- just as a small sample. Obviously, just using some piece of technology or adapting a sample to my needs is usually not that hard. The thing is, I can't bring myself to adding code to my arsenal if I don't understand how it works and how it has been implemented. It's somewhat akin to the Not Invented Here syndrome, except I don't actually write all my own frameworks; I just want to be able to write them. Here are a few recent examples.

In late 2011 I started getting my feet wet with Node.js, and in 2012 implemented several personal and commercial projects on top of Node, Express, and many other Node modules. I was very reluctant to start working with Node until I grasped the fundamental concepts -- the event loop and the asynchronous nature of everything -- which gave me the foundation to implement "something like Node" should I want to. There was even a time when I was considering to implement a Node-like HTTP framework with the new C# support for async/await, but gave up because there are many like it, ASP.NET MVC async controllers notwithstanding.

Next, I always was -- and to some extent, still am -- quite "afraid" of WPF. I can't say that I love client development in general, but nearly everything feels, on a purely psychological level, like a more appealing target for me than XAML-based frameworks. It's not that WPF is very hard for me to use: I understand the fundamental concepts such as data binding, styles, resources, and data templates, enough to implement simple desktop applications or sample Windows 8 and Windows Phone apps. It's the depth and breadth of WPF that always keeps me wondering: Is there a better way to do what I just did? How is this XAML expression working under the hood with this data context and that dependency property? Should I have moved this entire chunk of code into a behavior or a separate control?... I can't say I haven't tried: I read at least three books on WPF, with a total of more than 1500 pages, and they had had zero effect on my state of mind. The result, at least for me, is that on a subconscious level I steer clear of XAML-based frameworks, because I am not sure how to implement my own. The funny thing is that I'm fairly comfortable with several "thick" client technologies, including MFC, Windows Forms, Android, and iOS -- but it's as though XAML, with all its objective advantages, had developed a conditional gag reflex in my mind.

Moving on to something I am very comfortable with, I always felt at home with Reflection-based approaches to virtually anything, from serialization through validation all the way to code generation. Attributes and Reflection have somehow grown very strong roots in my mind ten years ago, when I was first working on a large .NET application, and have been a very powerful tool for me ever since. I attribute this mostly to the fact that I understand how managed types are laid out in memory, how .NET metadata is organized, and thus how Reflection can provide access, at runtime, to this information. In fact, I immediately feel at home with Reflection in other languages and frameworks as well: for instance, my first instinct when working on the Windows Azure Mobile Services unofficial Android SDK was to write my own JSON serializer in Java instead of relying on a third party library. After the fact, it might not have been the best decision, but it took me less than 2 hours to have a working serializer that supports most of the types WAMS requires.

As a final example, I have a very big problem adopting new languages, especially if they're not merely compiled to another language. In other words, I wouldn't mind using something like TypeScript or CoffeeScript, where I can easily see how the source is compiled down to JavaScript, and how a new piece of syntax is merely a mapping or syntactic sugar on top of existing syntax. But a "brand new" language, such as Objective C, poses huge problems for my mind. It's not the brackety syntax I have trouble with; it's the "how" of the language. How are Objective C objects laid out in memory? How are methods dispatched, considering that you can override them and even dispatch them dynamically by name? How does the compiler manage memory automatically (yes, reference counting -- but that's just a buzzword)? The same applies to a language like Python: I can use Python to write scripts, create modules, and even interact with C-style DLLs, but I don't have a clear picture of where attributes are stored and how typing works in a dynamically-typed language.

To conclude, I wish that every tutorial in the world were followed by a "how it works" section that would tell me how I can implement that language, technology, or framework -- on my own. Until such time, I hope this post explains why I tend to over-analyze how stuff works, to the extend of implementing it myself. The root cause of this might be that I'm used to systems, frameworks, and languages that I fully understand; it might have something to do with debugging or performance concerns; but at the end of the day, I need to know how it works: otherwise, I face a psychological barrier that gets more and more painful to overcome every day.


I am posting short links and updates on Twitter as well as on this blog. You can follow me: @goldshtn

Taking Windows Azure Media Services on a Real-World Spin

During the last few weeks I have been involved in a very interesting project with lots of potential, using Windows Azure Media Services. In a nutshell, Windows Azure Media Services supports encoding, management, and streaming of media from Windows Azure, in a completely hosted solution.

The client requested a proof-of-concept end-to-end solution that involves uploading existing media assets to Windows Azure, encoding them to smooth streaming formats, and delivering them to an audience using Windows computers, iOS devices, and Android devices. (The client’s current solution involves shipping of media files to a third party company, which takes care of the encoding jobs and delivers back URLs for streaming.)

Architecture
The architecture I ended up implementing on top of Windows Azure is the following:

image

From the client’s perspective, the only on-premise component is the uploader application, which uploads H264 MP4 files to an ASP.NET web application hosted in Windows Azure Web Sites (1). The web application creates a Windows Azure Media Services asset and streams the client’s upload to Windows Azure Blob Storage (2). Metadata about the upload, such as the file name, description, thumbnail URL, and other information is stored in Windows Azure Table Storage (3). When the upload completes, the ASP.NET application puts a message in Windows Azure Queue Storage (4), which a Worker Role dequeues and initiates an encoding job with Windows Azure Media Services (5). When the encoding job completes (6), the Worker Role generates streaming URLs with the Windows Azure Media Services origin servers, and stores these URLs for the web application to consume (8).

This end-to-end process can potentially replace the client’s current solution for media encoding and delivery. Although full pricing information for Windows Azure Media Services has not yet been disclosed (for example, the cost of on-demand streaming units), our estimates indicate a considerable cost savings when moving the whole solution to Windows Azure.

Support for multiple devices
To support as many devices as possible, it was necessary to encode the original MP4 video to two streaming formats: IIS Smooth Streaming, supported easily by Silverlight players, and Apple HLS, supported natively by iOS devices as well as newer Android devices.

On Windows and Mac computers, we could stream the video using a Silverlight player, which I borrowed from CodePlex.

On iOS and Android devices, all we had to do is embed the streaming URL in a <video> element:

<video width="640" height="480" controls>
   <source src="..." />
</video>

Finally, for “unsupported” devices, we chose to use a <video> element pointing to the original MP4 file, progressively downloaded from Windows Azure Blob Storage. Although this does not provide the advantages of smooth streaming (adaptive bitrate), it works out of the box on any device that supports the <video> element in a browser.

Implementation highlights
Overall, rolling out the above solution took only a few days. I integrated most of the moving parts on-premises, and then started uploading parts of the system to Windows Azure. First, I uploaded the ASP.NET web application to Windows Azure Web Sites, which was a breeze. Next, I wrapped a console application (that took care of starting and monitoring the encoding process) in a Worker Role. Finally, after sorting out a few remaining issues, the solution was ready to roll on Windows Azure. Below are some of the implementation highlights:

Creating a Windows Azure Media Services asset and uploading the MP4 file to Windows Azure Blob Storage:

Stream inputStream = Request.InputStream;
var blobClient = storageAccount.CreateCloudBlobClient();
var asset = mediaContext.Assets.Create(
    assetName, AssetCreationOptions.None);
var writePolicy = mediaContext.AccessPolicies.Create(
    "policy for copying", TimeSpan.FromMinutes(30),
    AccessPermissions.Write | AccessPermissions.List);
var destination = mediaContext.Locators.CreateSasLocator(
    asset, writePolicy, DateTime.UtcNow.AddMinutes(-5));
var destContainer = blobClient.GetContainerReference(
    new Uri(destination.Path).Segments[1]);
var destBlob = destContainer.GetBlockBlobReference(file);
dest.UploadFromStream(inputStream);
destBlob.Properties.ContentType = "video/mp4";
destBlob.SetProperties();

Getting a publicly readable URL for the static MP4 file uploaded:

var assetFile = asset.AssetFiles.Create(file);
assetFile.Update();
asset = mediaContext.Assets.Where(
    a => a.Id == asset.Id).FirstOrDefault();

var readPolicy = mediaContext.AccessPolicies.Create(
    "policy for access", TimeSpan.FromDays(365 * 3),
    AccessPermissions.Read | AccessPermissions.List);
var readLocator = mediaContext.Locators.CreateSasLocator(
    asset, readPolicy, DateTime.UtcNow.AddMinutes(-5));
string[] parts = readLocator.Path.Split('?');
string staticUrl = parts[0] + "/" + file + "?" + parts[1];

Firing off an encoding job that first encodes the MP4 file to the IIS Smooth Streaming format, and then encodes the result to Apple HLS format suitable for streaming from iOS devices:

var job = mediaContext.Jobs.Create(
    "Encoding Job for " + asset.Name);
var encoder = mediaContext.MediaProcessors.Where(
    m => m.Name == "Windows Azure Media Encoder").First();
var encodingTask = job.Tasks.AddNew(
    "Encoding Task for " + asset.Name, encoder,
    "H264 Smooth Streaming 720p", TaskOptions.None);
encodingTask.InputAssets.Add(asset);
var ssOutput = encodingTask.OutputAssets.AddNew(
    "output-Silverlight-" + asset.Name,
    AssetCreationOptions.None);
var packager = mediaContext.MediaProcessors.Where(
    m => m.Name == "Windows Azure Media Packager").First();
var conversionTask = job.Tasks.AddNew(
    "Conversion Task for " + asset.Name, packager,
    File.ReadAllText("MediaPackager_SmoothToHLS.xml"),
    TaskOptions.None);
conversionTask.InputAssets.Add(ssOutput);
conversionTask.OutputAssets.AddNew(
    "output-HLS-" + asset.Name, AssetCreationOptions.None);
job.Submit();

What does the future hold?
If this proof-of-concept is successful, we could be talking about petabytes of data hosted in a similar fashion on Windows Azure and streamed to millions of viewers.

We still need to find better solutions for older Android devices, which do not support Apple HLS natively; there’s also live streaming to consider, which Windows Azure Media Services currently does not support.

In closing
This was a project that highlighted the flexibility and ease of use that have been so typical of Windows Azure since the first time I’ve touched it. Whether it’s a Node.js app on Windows Azure Web Sites, a Windows Azure Mobile Service accessed by iOS and Android apps, or a fuller solution like the above, Windows Azure is fun to use and easy to understand.

When I first pitched this solution to the client, I faced lots of anxiety about putting data on Windows Azure or streaming media from a datacenter far away. Later in the project, I was greeted by the client’s less-technical folks humming away on Windows Azure Virtual Machines, configuring firewalls for Windows Azure SQL Database, and experimenting with publishing ASP.NET applications to Windows Azure Web Sites.

Thanks to Maor David and Noam King from Microsoft Israel for their support with this project.


I am posting short links and updates on Twitter as well as on this blog. You can follow me: @goldshtn

P/Invoke with C++ bool Return Values

I encountered an interesting gotcha today, which I thought would be interesting to share with you. The symptoms were the following: I wrote a simple C++ function exported from a DLL, and tried to invoke it using a P/Invoke wrapper. The C++ function returns a bool, and was declared as follows (the code was simplified for expository purposes):

extern "C" __declspec(dllexport) bool IsPrime(int n) {
    if (n <= 1) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;
    for (int i = 3; i < n; ++i) {
        if (n % i == 0) return false;
    }
    return true;
}

The managed counterpart was:

[DllImport(@"..\..\..\Debug\NativeDll.dll",
           CallingConvention=CallingConvention.Cdecl)]
static extern bool IsPrime(int n);

At runtime, for some values of n, the output would be inconsistent. Specifically, when n=0 or n=1, the managed wrapper would return true – although the C++ function clearly returns false. For other values, however, the wrapper returned the right values.

Next, I disassembled the C++ function, to find the following code responsible for the first branch:

cmp dword ptr[n], 1
jg BranchNotTaken
xor al, al
jmp BailOut

BailOut:

ret

In other words, to return false, the function clears out the AL register (which is the lowest byte of the EAX register), and then returns. What of the rest of the EAX register? In the debug build, it’s likely to contain 0xCCCCCCCC, because of this part of the function’s prologue:

lea edi,[ebp-0CCh] 
mov ecx,33h 
mov eax,0CCCCCCCCh 
rep stos dword ptr es:[edi]

To conclude, the function returns 0xCCCCCC00 in the EAX register, which is then interpreted as true by the managed wrapper. Why? Because by default, P/Invoke considers bool parameters to be four-byte values, akin to the Win32 BOOL, and then any non-zero value is mapped to true.

To fix this, I had to convince P/Invoke to marshal back the return value as a single byte. There’s no dedicated type for that in the UnmanagedType enumeration, but U1 (unsigned byte) or I1 (signed byte) will do the trick:

[DllImport(@"..\..\..\Debug\NativeDll.dll",
           CallingConvention=CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool IsPrime(int n);


I am posting short links and updates on Twitter as well as on this blog. You can follow me: @goldshtn

Announcing: SELA Developer Practice, May 5-9, 2013

I’m very happy to announce our next conference—the biggest one yet—SELA Developer Practice, May 5-9, 2013.

email_confirmation_banner

This time we opened the call for papers to local and international speakers, and here are the results, in numbers:

Our last conference was record-breaking in terms of attendance, and we definitely hope to break that record again! If you live in Israel, you can take advantage of early bird registration right now, and save 33%.

I will be delivering three sessions at the SDP:

Improving .NET Performance – the time-tested full-day workshop that teaches you how to measure and improve .NET application performance, based on the Pro .NET Performance book.

Windows Azure Mobile Services – a breakout session on one of the coolest Microsoft technologies, which provides a backend for your mobile apps on all four major platforms: Windows 8, iOS, Android, and Windows Phone.

Attacking Web Applications – a brand-new breakout session covering common attacks on web applications, including XSS, SQLi, CSRF, insecure credential storage, and many others.

In closing, I encourage you to check out the list of sessions and speakers and see for yourself: the SDP is the biggest and best developer conference in Israel.


I am posting short links and updates on Twitter as well as on this blog. You can follow me: @goldshtn

Windows Azure Mobile Services Unofficial Android SDK: Authentication Support

I totally forgot to blog about it, but my unofficial SDK has had authentication support for a few days now. This has been pretty easy to implement, actually, thanks to OAuth and the Mobile Services backend.

If you haven’t gotten started with WAMS authentication yet, you really should try it out. It’s easy as pie, really, and you can set yourself up with 3-4 authentication providers in a matter of several minutes. I’ll leave the rest to this great tutorial on authentication with WAMS.

So, if you’ve got the latest version from GitHub, you can now do this to authenticate:

mobileService.login(
MobileServiceAuthenticationProvider.TWITTER,
new MobileServiceLoginCallback() { public void errorOccurred(MobileException exception) { //Invoked if an error occurred } public void completedSuccessfully(MobileUser user) { //Invoked on success -- user.getUserId()
//provides the user id } public void cancelled() { //Invoked if the user cancelled the process } });

As a bonus, the client-side SDK will persist the authentication token returned by WAMS after the login flow completes. (If you care about the details, the token is persisted in a preferences file, and is not encrypted; this is something that needs to be taken care of in the future.) On subsequent runs of your app, you won’t have to display the login flow again to the user. Use the MobileService.isLoggedIn method to determine whether the user is currently logged in, and the MobileService.logout method to log out.


I am posting short links and updates on Twitter as well as on this blog. You can follow me: @goldshtn