Windows Azure Role Communication

by Brian Hitney 3. February 2010 11:07

I have a few posts along the lines of scaling an Azure application, but thought I’d throw this tidbit out.  You might be developing your own management system for your Azure deployments, and in doing so, having visibility into the roles running within your deployment is very handy.   The idea behind this series of posts is to ultimately explore how to get visibility into roles, and then a few ways we can tackle inter-role communication. 

The first task is to define internal endpoints for each of our roles.  If you don’t do this, you will only have visibility into the current role.  So, if you have a single role solution (any number of instances) than you don’t have to do this. 

Let's take a pretty simple example where we want to enumerate all the roles in our deployment, and their instances:

foreach (var appRole in RoleEnvironment.Roles)
{
    var instances = RoleEnvironment.Roles[appRole.Key].Instances;

    foreach (var instance in instances)
    {
        Response.Write(instance.Id);
    }
}

While this code will work fine, by default it will only show you the instances for the current role – other roles will show an instance count of zero.  Running this in my workerrole and trying to enumerate my webroles, I see this:

image

What we can do is define and internal endpoint for our roles that will allow this data to be discoverable.  In Visual Studio, it’s simply a matter of going into the properties of the role and defining an internal endpoint:

image

And we’re done.  Debugging the solution again:

image

We can do the same for our workerroles to be discoverable by other webroles, etc. 

In some future posts, I’ll build off this idea for doing some lightweight service management and role communication.

Tags: , ,

Azure | Development | Tech Tips

SQL Azure Transport-Level Error

by Brian Hitney 3. February 2010 10:34

If you’ve been playing with SQL Azure, you might have run into this error when opening a connection to the database:

A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine.)

Ick!  Anything at that transport level surely can’t be a problem with my code, can it?  :)

The goods news is that you aren’t going crazy and the problem isn’t with your code.  There’s a difference in the way SQL Azure manages its connections compared to .NET connection pooling, and the result is that the connection pool is giving out connections that have already been closed.  When you try to do something with that connection, you get this error.   It’s sporadic in that only happens when you get an idle connection from the pool that has already been dropped by SQL Azure.

There are a couple of workarounds until a fix is implemented by Microsoft (I’ve been told it’s coming soon).  One method is to retry the connection (I hate this one, but it’s a viable option nonetheless).  It’s just messy and I’d have to do this in a few dozen places.  The amusing fix is to have a thread that continually pings the database, keeping every connection alive.  The best fix that I’ve found to date is to simply turn off connection pooling temporarily by adding a pooling=false option to the connection string:

image

I tested this on my webrole, leaving my workerroles as-is, and the webrole has been running for a week or two without a single error, whereas the workerrole (without disabling pooling) will get a couple errors every day.

I haven’t done any performance tests but UA testing (which is me) sees no appreciable hit, so I’ll go with this option until the permanent fix is deployed. 

Tags: , , ,

Azure | Development | SQL | Tech Tips

Robocopy in Win7

by Brian Hitney 1. February 2010 13:17

I’m surprised I didn’t realize this earlier, but Win7 introduced multithreading support in Robocopy.  I’ve always used Robocopy for copying lots of files particularly over a network, and especially over a VPN.  I’ve also always specified the /E /Z switches to copy all folders, and support file resume. 

File resume is especially helpful over a VPN because the VPN connection may be lost for any number of reasons.  I’ve had situations where my access was off for hours, and it picks up right away on reconnect.   Now in Win7, you can specify a /MT[:n] switch that specifies the number of threads (default 8) to use.  

And if you prefer a GUI, RichCopy is a nice tool as well!

Tags: ,

Microsoft | Tech Tips

Leaderboard Tweaks and T-SQL Fun

by Brian Hitney 21. January 2010 06:01

With the chaos of the Worldmaps to Azure migration winding down, I decided to take a look at some the low-pri issues on my to-do list.   Those close to the project or who follow their leaderboard ranking closely know that last year, the leaderboard was ranked by Total Hits.  This worked pretty well at the time, but it made it impossible for those who joined the site weeks or months after others to compete unless their site had considerable more volume to close the gap.

This year, I changed the formula to base the data off of average hits per day.  This adds a bit more excitement because it’s a level playfield regardless of join date, for the most part.  The one remaining problem I have with hits per day is that if a site gains popularity over time, the resulting average encourages the user to delete and recreate their map for better rankings.  At some point in time, I’ll further refine this so it looks at hits per day for the last month or two (for example).

In the meantime, though, I got some heat from Chris Eargle who pointed out some problems with my implementation when he looked at his numbers.  The way the implementation worked was that it grabbed the earliest hit, the most recent hit, and divided by the number of days.   To prevent division by zero and give a minimum of 1 day, 1 was added to the number of days like so:

coalesce(sum(hits.NumHits) / (DATEDIFF(d, MIN(hits.CreateDate), MAX(hits.ModifyDate))+1) ,0) as HitsPerDay

While this worked “okay,” it wasn’t perfect.  For starters, using DATEDIFF returns an integer based on the dates passed in.  If you pass in “1/21/2010 23:59” and “1/22/2010 00:01,” the DATEDIFF (by days) is 1, even though only 2 minutes have passed.  If you pass in “1/22/2010 00:01” and “1/22/2010 23:59,” a zero is returned even though it’s just 2 minutes short of a day.  This isn’t wrong, but it’s limited for what we need because the leaderboard is generated throughout the day. 

Adding 1 can be incorrect because, using the first example, it will now return 2 days (!) when only 2 minutes have expired.  It’s a pretty extreme example but possible.  I wanted an implementation that, using T-SQL alone, would be a bit more consistent.  The criteria I had was: 1) had to support partial days and 2) had to give a minimum of 1 day.  #2 is because I don’t want a map that was just created (as in the first time example) to end up getting (again, for example) 50 hits in 2 minutes and due to the math, getting averaged at say 100,000 hits per day.  Using a minimum of 1 day makes the leaderboard a little more stable.  The resulting query:

CAST(FLOOR(
    SUM(NumHits)/
      CASE 
        WHEN (DATEDIFF(hh, MIN(hits.CreateDate), MAX(hits.ModifyDate))/cast(24 as float)) < 1 THEN 1        
        ELSE (DATEDIFF(hh, MIN(hits.CreateDate), MAX(hits.ModifyDate))/cast(24 as float))
      END
      )
as int) as HitsPerDay

This works out really well.  First, we use hours instead of days and simply divide by 24.  It’s essentially the same as days, but gives a fractional value.  If the value is less than 1, we’ll use just 1 as the minimum.  This solves the second criteria above and also any division by zero cases.  The ELSE of the CASE gives us the fractional days, so hits per day is more accurate and no more +1 tomfoolery.  Even though the FLOOR returns an whole number, the data type is unchanged so a cast to an int is necessary for the application.

If we look at the results in query analyzer, you can see the results are more true:

image

The “days” and “days_partial” shows the difference between using hours and days in DATEDIFF, giving us more accuracy.  The “HitsPerDay_New” compared to “HitsPerDay_Original” shows the more accurate result.  In some cases unchanged, in some cases much more accurate as you can see by looking at the “FirstHit” and “MostRecentHit” columns.

Anyway, just some fun playing with T-SQL and if you see some adjustments in the Leaderboard, this is why. 

But Chris, it won’t help you get into the Top 10. :)

Tags: , ,

Worldmaps | Development | SQL

Customizing your Worldmaps

by Brian Hitney 17. January 2010 05:51

I admit that site design is something that often takes a back seat when developing Worldmaps, but in the recent migration to Windows Azure, I added a few new minor customizations to the maps.

When you log into your account, you should see a list that contains all of your current maps:

image

From this screen, you can either modify a map, or create a new one.   When creating a new map, you’ll see a simple form to fill out:

image

All of the information that is required for the map is the URL and Leaderboard.  The latitude and longitude fields indicate your home location.  You can use the home locator map on the bottom of the screen to help in this regard, or you can leave this blank.  Without this information, some statistics cannot be calculated.  The Leaderboard indicates which category best suits your map.  Is it a personal blog?  A technology blog?  A personal site?   Pick the one that best fits your site – this can be changed later.

The last box, Invitation Code, is for premium accounts and changes the way the data is stored for the given map.  I described this briefly in my last post.   For scalability reasons, most new accounts will be under the new scheme – if you need more detailed information (such as # of unique IPs), contact me for invitation code. 

Customizing your Map

Once your map is created, click the edit button next to your map to customize the colors.  The form should look similar to:

image

When the app is drawing your maps, you can control the colors used in drawing the circles.  Feel free to experiment with some color choices.  The four values you can customize are explained on the form.  Use the Silverlight-based Color Picker to find a color and copy that value into the text box of the value you’d like to change.  Or, you can enter values directly into the box if you know the hex-value of the color you’d like to use.  When done, click Save.  In general, the maps will be redrawn reasonably quick depending on how much work is currently in the queue.  Customizing the colors is a great way to add a little personalization to your maps!

Tags: , ,

Worldmaps | Tech Tips

Worldmaps Update

by Brian Hitney 17. January 2010 05:34

The recent update to Windows Azure went quite well!  The site is now using a single Azure webrole, a single Azure worker role, Azure Queues for workload, and Azure Blobs for storage.  It’s also using SQL Azure as the database.   From a user’s point of view, not much has changed but the performance and scalability has been much improved.  On the stats page, I implemented a few new stats …

First up is the hourly breakdown of hits to a site.  Below is Channel 9’s current breakdown.   Neat way to tell when the traffic is heaviest to your site.  In this case, C9 is busiest at 3pm GMT, or about 9am-4pm EST. 

image

In addition, Worldmaps includes country breakdown information:

image

And, Stumbler has been updated a bit so be sure to check it out and watch traffic in real time!

image

Finally, there’s change to the registration process.  To add some scalability, Worldmaps now stores data in one of two schemes.  The older scheme has been migrated to what is called a “plus” or enhanced account.  The newer scheme is the default, and it stores data in a much more aggregated way.   What determines how information is stored?  This is based off of an invitation code on the Create Map form:

image

If no invitation code is provided, the newer scheme is used.  If a valid invite code is provided, the old, more detailed method is used.  If you’d like an invite code, drop me some feedback.What’s the difference?  Currently, the difference is pretty small.  On the stats page, current number of Unique IP's can not be calculated, so it looks like so:

image

Future report options are a bit limited as well, but otherwise, all data (and Stumbler) is still available.

Tags: , , ,

Worldmaps | Technology | Azure

Podcast with Michael Kimsal

by Brian Hitney 19. December 2009 02:51

The other day, I had the honor of sitting down and rambling endlessly with Michael Kimsal in this podcast.  It was a lot of fun, despite the overly loud announcement system in the background (“…table 3, your order is ready” type of thing).   Michael is one of those insanely smart kind of guys that has a really balanced view of technology and a lot of fun to talk to.   Michael publishes (among other things) jsmag, a must read for javascript developers.  Check it out!   Also, if you use coupon HITNEY on the site, you can get a free issue!  (Thanks Michael!)

Tags: ,

Development | Technology | Babble

Worldmaps Migration Underway

by Brian Hitney 19. December 2009 02:40

For those of you with Worldmap accounts, the Azure migration is (hopefully) underway.  This process will take awhile, in part due to the holiday vacation :) but also testing and what not.  Starting today, the accounts section will be closed for changes until the migration is complete.

Hopefully, the migration will not cause any breaking changes.  However, the biggest possible change is to make sure you are accessing the service using www in the URL … for example, “http://www.myworldmaps.net….” – if you’re leaving that out, it will have to be added in or the map will not work after the migration due to limitations with the DNS CNAMEing in Azure.

Stay tuned, and hope for a smooth ride and management approval :)

Tags: ,

Development | Worldmaps

Pay Attention to your Azure Blobs

by Brian Hitney 13. December 2009 15:35

I have a fairly large Windows Azure migration I’m working on, and there are dozens of tips, recommendations, gotchas, etc. I’ve learned in the process.  This is one small item that cost me quite a bit of time, and it’s so simple I’m detailing it here because someone will run into this one.

First a bit of background: if you’re deploying a Windows Azure application, the package is uploaded and deployed as a whole.  If you have dynamic content or individual files that are subject to change, it’s a good idea to consider placing it in Azure Storage, otherwise you’ll have to redeploy your entire application to update one of these files.  In this case, I’d like to put a Silverlight XAP file in Azure storage, instead of the typical /ClientBin folder.

There are a number of references on the net for setting this up – searching for “XAP” and “Azure” returns a lot of good references including this one.  After checking my Silverlight project’s app manifest file, ensuring everything was correct, and uploading the XAP to my Azure storage account, my Silverlight app would refuse to run.  The page would load, but then … nothing.  I also checked Fiddler – the XAP file _was_ getting downloaded (and was downloading fine via a browser).  This is typically a tell-tale sign of a policy issue – yet I was certain everything was correct.  Here’s a screenshot (click for larger) of Fiddler downloading the file.  Can you spot the problem here?

image

The problem was indirectly with Cerebrata’s Cloud Storage Studio.   Cerebrata’s product is really nice and I enjoy working with it quite a bit to work with Azure storage (uploading/downloading files).  CloudBerry’s Explorer for Azure Blob Storage is another good one – I typically work with Cerebrata’s simply because it was easier to connect to development storage (not sure if this is possible in CloudBerry’s app).

Fast-forward and hour or two of frustration.  Staring at Cloud Storage Studio, I see:

image

Zip file as a content type?  This was in the Fiddler screenshot above, too.  I figured this was fine because after all, a XAP file is a zip file.  But as it turns out, this was the problem.   For kicks, I tried re-uploading the XAP file from CloudBerry to see how it handled the content type, and:

image 

Cloud Storage Studio does allow you to alter the content types, but truthfully I didn’t think this was all that important.  When I reloaded my application, though, the app loads and Fiddler comes to life as it should:

image

For kicks I changed the content type back to Zip, and the app would fail to load.  So, lesson learned!  Don’t forget about the content types.

Tags: , ,

Development | Microsoft | Tech Tips | Azure

Worldmaps Update & EOY Changes

by Brian Hitney 6. December 2009 16:05

Hi folks!  I wanted to take the opportunity and outline a few changes for Worldmaps – both changes in the service, the backend, and new features.

image First up: Stumbler.  A link to Stumbler was added to the nav menu at the top of the page.  If you haven’t played around with Stumbler, check it out.  It maps users in near real time to websites.

One of the biggest changes is the update to the new Bing Maps Silverlight control.  This doesn’t change much from the end-user point of view, but a few new features have been added so the UI in Stumbler is a bit cleaner around pushpins and effects.  In addition, there’s a new setting in the settings dialog to choose whether or not to scroll the map automatically.  Normally you zoom around the map automatically, but now you can turn that off to stay focused on a certain area.

image The other big new feature is multiple/extensible leaderboards.  The way it worked until now was there a single leaderboard for all users.  This “master leaderboard” is still there, but having sub leaderboards is a lot more interesting.  I defined a few leaderboards like “Tech Blogs” and “Personal Sites,” but will add more over time (leave feedback on new leaderboards!).  On the leaderboard page, the default view is the all-up leaderboard, while each leaderboard is displayed on the left nav. 

To pick a leaderboard, log in to your account and edit your maps.  In the detail section, you’ll see a drop down that allows youimage to select a leaderboard (see image to the right).  I should also point out that the sub-boards are sorted based on hits per day, not total hits. 

The other big change to outline is the end-of-year change.  At the end of the year, the individual hit data is reset.  This means all the red dots on the map will be wiped clean and start over again.  Data will be archived and available in some fashion, but this hasn’t been implemented yet.  Additionally, next year (2010) the main leaderboard will be sorted based on average hits per day. 

Now to address the biggest architectural change:  if you’ve created an account on Worldmaps but haven’t gotten an email yet with the approval, fear not.  Unfortunately the volume is such that with limited infrastructure, there’s not much more that can be done.  This will soon change.  Worldmaps has been moved to Windows Azure, Microsoft’s cloud computing platform.  This should give Worldmaps a nice bump in scalability (limited really only by funds).  So stay tuned in early 2010 for more info.

Tags: ,

Development | Technology | Worldmaps

your host...

Brian Hitney
Developer Evangelist
Microsoft Corp.

 

My Worldmap