rpowers WebLog

Musings on Agile Development and Visual Studio ALM Tools
in

June 2007 - Posts

Silverlight 1.1 on Facebook Canvas Page using ASP.NET and Facebook Developer Toolkit

A couple weeks ago, working with Microsoft we delivered the facebook developer toolkit to help developers write Facebook applications using .net.  Since then, we created a codeplex project to help keep the toolkit up to date and relevant.  It has been fun, and the response/involvement from the community has been great.

Yesterday, I spent some time working on how to build canvas pages leveraging the toolkit.  A canvas page is a page that is accessed directly within facebook.com and the result is integrated into the user experience on facebook. These canvas pages were a major part of the new F8 facebook platform.  For more information, check out the Facebook Developer documentation.  Anyway, after struggling with the flow of authentication and application adding, I finally got it working and created 2 new canvas base pages (one for FBML type and one for IFrame).  I posted on codeplex about the changes here.  I also posted some very simple Canvas page examples for both FBML and IFrame.

Now that I had a good framework in place for building the canvas page, I wanted to see if I could get a Silverlight control with Facebook context showing up in my IFrame canvas page.  From past experience, I knew there were some major obstacles.

  1. Some namespaces used in the Facebook.dll (wrapper to the API) are not supported in Silverlight namespace.  Most notably: System.XML, System.Web.
  2. Silverlight 1.1 Alpha does not support cross domain posts.
  3. It will be tough to manage the facebook login process from the Silverlight control, since we can not show the facebook hosted login page.

With this in mind, I had a plan.  And after a frustrating day, just got a Silverlight control showing on a canvas page with some facebook context.  Here's how.

  1. Added a new webservice (SilverlightService.asmx) to my ASPNETPlatformSamples web site.  This webservice is a proxy used by the silverlight application to call facebook
  2. Updated the ASPNETPlatformSamples web.config to support the web service.
  3. Added a ScriptService attribute to SilverlightService to enable it to support JSON calls
  4. Added WebMethod GetFriends wrapping the FacebookService.GetFriends(), this method needs to take the 4 parameters that comprise a facebook session, so that calls can maintain context.
    [System.Web.Script.Services.ScriptService] public class SilverlightService : System.Web.Services.WebService { Facebook.Components.FacebookService _fbService = new Facebook.Components.FacebookService(); [WebMethod] public UserJSON[] GetFriends(string api, string secret, string session, string userid) {
  5. Created a stripped down version of the Facebook.Entity.User class that is serializiable by JSON.  JSON can't serialize enums or subclasses.  So, for this I just stripped them out.  This is called UserJSON and is currently just a member of my ASPNETPlatformSamples web site. 
  6. In the GetFriends WebMethod, converted Collection of Users returned from Facebook call to Array of JSON compatible users.
    Collection<Facebook.Entity.User> friends = _fbService.GetFriends(); UserJSON[] x = UserJSON.ConvertFacebookUserArray(friends); return x;
  7. Created a new Canvas page (IFrame\Silverlight.aspx), alongside to my other IFrame canvas samples
  8. Added a placeholder for the Silverlight control and 4 hidden fields to store the facebook context.
    <head> <title>Silverlight Project Test Page </title> <script type="text/javascript" src="Silverlight.js"></script> <script type="text/javascript" src="CreateSilverlight.js"></script> </head> <body> <form id="Form1" runat="server"> <asp:HiddenField ID="hidAPI" runat="server" /> <asp:HiddenField ID="hidSecret" runat="server" /> <asp:HiddenField ID="hidSession" runat="server" /> <asp:HiddenField ID="hidUser" runat="server" /> <div id="SilverlightControlHost" > <script type="text/javascript"> createSilverlight(); </script> </div> </form>
  9. Added code in code-behind to populate hidden fields (so they can be accessed by silverlight control).
    public partial class _Default : CanvasIFrameBasePage { private const string FACEBOOK_API_KEY = "c559128010f3edee33796fd4205361c2"; private const string FACEBOOK_SECRET = "85887d1c9a8334e5059742468a5400ee"; new protected void Page_Load(object sender, EventArgs e) { base.Api = FACEBOOK_API_KEY; base.Secret = FACEBOOK_SECRET; base.Page_Load(sender, e); hidAPI.Value = this.FBService.ApplicationKey; hidSecret.Value = this.FBService.Secret; hidSession.Value = this.FBService.SessionKey; hidUser.Value = this.FBService.UserId; } }
  10. Created a new silverlight project using Orcas called SilverlightWebServiceClient
  11. Added a web reference to the above WebService
  12. Added code in page_loaded event handler of xaml code behind to call the GetFriends method on the WebService to retrieve an array of friends.
  13. Then simply wrote text to a textblock with the count that was found.
  14. I then needed to add a Silverlight Reference into the ASPNETPlatformSamples.  This essentially copies the .xaml from the Silverproject, and the compiled .xaml.cs into a ClientBin folder of the web site project so they can be accessed from within the website.
  15. You can see it in action, by going to my IFrame canvas sample.   After logging in and adding the application, you should have a Silverlight demo link which will show the Silverlight page.

I checked the updated c# code for ASPNETPlatformSamples and a new project for the Silverlight Control into the codeplex site.

Now we need to build some cool Silverlight canvas apps.  If anyone has better ways to do this, I'd be interested in learning about them.

Next up, Silverlight in FBML Canvas page.

Posted: Jun 27 2007, 05:29 PM by rpowers | with 9 comment(s)
Filed under:
SQL 2005 Performance Tuning using DMVs - Part 2 of 7 - Identifying CPU Pressure

In the my first post on DMVs, I gave an introduction to Dynamic Management Views and talked about some of the tuning activities that DMVs make easier.  I also gave my top 10 DMV list.

In this installment, I am going to review how DMVs can be used to analyze CPU utilization on a machine running SQL Server.

Identifying if a System has CPU Pressure

Prior to DMVs, the typical approach to checking whether a server was experiencing CPU bottlenecks was to use the Processor Queue Length performance counter.  This counter should typically be near 0 for systems not experiencing CPU pressure.

This approach is still valid, but is not necessarily a good measure for a server used for SQL Server.  To see why this is the case, we must examine SQL Server Execution Model.

SQL Server uses a User Mode Scheduler (UMS) to control the execution of SQL Server user requests (SPIDs or session_ids). The UMS manages the execution of SQL Server requests (without returning control to Windows). So when SQL Server gets its time slice from the Windows scheduler, the SQL Server UMS manages what user requests are run during this time.

In a 4-proc scenario, there will be 4 User Mode Schedulers, one for each CPU. Each UMS uses a number of constructs (queues, lists and worker threads) to govern execution. At any given time, each UMS will have at most a single running thread, a runnable queue of requests that are
waiting for CPU, a waiter list (for resources such as IO, locks, memory), and a work queue (user requests that are waiting for worker threads).

Whenever the current running thread needs I/O it is moved to the wait list.  When this occurs, the next request from the runnable queue is started.  When the thread needing I/O completes, it is moved back to the end of the runnable queue. 

The time waiting for a resource is shown as Resource Waits. The time waiting in the runnable queue for CPU is called Signal Waits. In SQL Server 2005, waits are shown in the Dynamic Management View (DMV), sys.dm_os_wait_stats.  In this DMV, high Signal Wait % indicates a CPU constraint.   


The query to measure cpu pressure using sys.dm_os_wait_stats is as follows:

 

SELECT sum(signal_wait_time_ms) AS signal_wait_time_ms, cast(100.0 * sum(signal_wait_time_ms) / sum (wait_time_ms) as numeric(20,2)) as '%signal (cpu) waits', sum(wait_time_ms - signal_wait_time_ms) as resource_wait_time_ms, cast(100.0 * sum(wait_time_ms - signal_wait_time_ms) / sum (wait_time_ms) as numeric(20,2)) as '%resource waits' FROM sys.dm_os_wait_stats

 

You can also monitor the SQL Server schedulers using the sys.dm_os_schedulers view to see if
the number of runnable tasks is typically nonzero. A nonzero value indicates that tasks have to wait for their time slice to run; high values for this counter are a symptom of a CPU bottleneck. You can use the following query to list all the schedulers and look at the number of runnable tasks.

SELECT scheduler_id, current_tasks_count, runnable_tasks_count FROM sys.dm_os_schedulers WHERE scheduler_id < 255

That's it for this installment, see you next time as we find out how to determine the likely causes of the CPU pressure we just identified.

SQL 2005 Performance Tuning using DMVs - Part 1of 7

A few months ago, I researched and put together an internal presentation on one of the more interesting features in SQL 2005 (Dynamic Management Views).  This topic is not quite as cutting edge now as it was when I researched it.  But, I think it is still useful to blog what I found.  First off, thanks to Kim Tripp at SQL at www.sqlskills.com.  I first became interested in this topic when watching some of her webcasts.  I also found many of my good samples of DMV useage from some of her posts.

I am going to break this up into parts, this first part is just an intro. 

Microsoft made a big effort with SQL Server 2005 to make the server more transparent to administrators and developers. The result is DMVs, which should make database tuning and maintenance easier.

“DMVs can expedite the diagnosis process by eliminating the need to generate and analyze physical dumps in most cases. DMVs provide a simplified and familiar relational interface for getting critical system information. This information can be used for monitoring purposes to alert administrators to any potential problems. Or, the information can be polled and collected periodically for detailed analysis later.”

DMVs are very useful in diagnosing different SQL performance problems.  I will go into more specifics with the future posts here.  But in general, you will find great resources for looking into any of the following:

  • Resource Bottlenecks
    • CPU
    • Memory
    • I/O
  • TempDB Bottlenecks
  • Slow Queries
    • Bad Plans
    • Missing Indexes
    • Blocking
  • Index Fragmentation

Here is a good list of the Naming Conventions of the DMVs that are available:

  • CLR Related
    • dm_clr_
  • Database Related
    • dm_db_
  • Execution Related
    • dm_exec_
  • Full Text Search Related
    • dm_fts_
  • Index Related
    • dm_db_index_
    • dm_missing_index_
  • SQL OS Related
    • dm_os_
  • I/O Related
    • dm_io_
  • Query Notifications Related
    • dm_qn_
  • Replication Related
    • dm_repl_
  • Service Broker Related
    • dm_broker_
  • Transaction Related
    • dm_tran_

After playing around with all the DMVs I could find, I put together a list of my 10 favorites:

  1. dm_exec_query_stats – performance stats of all queries
  2. dm_exec_sql_text – returns exact sql for entire batch given a sql handle
  3. dm_exec_query_plan – return query plan for entire batch given a plan handle
  4. dm_db_index_usage_stats – displays how often each index is used, show Read Seeks, Read Scans, Write Seeks and Write Scans
  5. dm_db_index_physical_stats – replace DBCC SHOWCONTIG used to check index fragmentation
  6. dm_db_index_operational_stats – use to check for index contention and blocking
  7. dm_os_wait_stats – Used to determine the types of waits (signal or resource that are occurring)
  8. dm_os_waiting_tasks – Used to help identify blocking
  9. dm_tran_locks – Used to help indentify blocking
  10. dm_os_performance_counters – Query Access to SQL Server Performance counters

The last thing I wanted to cover in this initial post, was just methods for writing queries to identify the DMVs and their types.  Some DMVs are actual views, while others are tabled valued functions.  Again, thanks to Kim Tripp for most of this knowledge.

Download a script for identifying DMVs and syntax to querying each here

Mixed Authentication- ASP.NET Forms and IIS 6.0 Windows Integrated

Recently I was working on a website that needed to leverage both Integrated Windows and Forms Authentication.  The idea is that this website has some users that are on Active Directory and should be able to gain access without being challenged from credentials when they are logged into the domain.  Additionally, these users should be allowed to enter their AD credentials and access the site if they access the site remotely (while not logged in to AD).  This is all handled by IIS Integrated Windows Authentication.  However, for our situation we also have users who are not in AD at all and need to access the site.  We preferred to not create AD accounts for these users just to permit access to the site.  The solution we wanted was try windows integrated, if it fails, use forms authentication.  This problem will go away with the integrated pipeline of IIS 7.0 (more on this with a later post).  But, in IIS 6.0 this problem proved very tough to solve.

After doing some research, we found this article.  http://msdn2.microsoft.com/en-us/library/ms972958.aspx.  This was a great article and provided the basic approach to the solution. 

To summarize

  1. Set site to use Forms Authentication
  2. Set web.config authorization to deny anonymous users
  3. You need to set one page in your web application to use Windows Integrated Authentication (this was a revelation to me, setting one page to different IIS authentication than others in same app).  In this case we call it WinLogin.aspx
    1. In this page, capture the Request Variable "LOGON_USER" and then call FormsAuthentication.RedirectFromLoginPage.
    2. This allows you to mimick a forms logon for the windows user.
  4. Set Forms loginUrl to page from step 3
  5. Handle Windows Integrated failures.  Add a custom handler for 401 errors, and in the static HTM page.  Use a javascript function to forward to the real ASP.NET forms login page (WebLogin.aspx).

6.  Update web.config to allow anonymous access of WebLogin.aspx.

7.  Redirect to original requested URL

 

This was very helpful and got us a solution that solved most problems.  However, we quickly ran into one problem that we couldn't live with. For IE users who did not have our site as a "Trusted Site", Windows Integrated would popup a login dialog prompting for credentials prior to our custom 404 provider.  So, our non AD users would have to press cancel on this to get to our login form.  Just not acceptable. 

Some more research brought us to another great post that ultimately gave us they framework for our solution.  The article that we used to help us solve this problem is here http://glazkov.com/blog/credentials-screening/.

We were not able to get his exact implementation working, and ended up changing the code quite a bit.  But, the essence of the approach is exactly as described in that post (and the subsequent updates). 

The short explanation of how this works is:

  • Create an HTTPModule to handle incoming requests
  • In this module, emit a javascript function to try to load the page that is setup as requiring Windows Integrated. 
  • Back in the module, check the LOGON_USER server variable.  (If javascript succeeded in accessing that file, this variable will be populated)
  • Continue with redirect

The key to the solution that solves the original problem is the javascript load of the page set to require Windows Integrated Authentication.  What this accomplishes is pre-empting the load of this page that IIS will do and allows our code (in the handler) to respond the results of the check prior to IIS potentially popping up a dialog.

The last thing we needed to do was simply added AD integration into the weblogin form.  So, we could still allow AD users who access the site without being logged into the domain use the domain credentials.  I will discuss this in my next post.  The code I am posting with this blog does not have the AD integration on the login page itself.  (As it will take more work for me to factor that out into a digestable snippet).

You can download a sample here

Posted: Jun 12 2007, 12:41 AM by rpowers | with 19 comment(s)
Filed under:
CNUG Silverlight Presentation

Our CTO, Jon Rauschenberger, and I did a presentation on Silverlight at the Chicago .NET User Group last week.  Jon presented the slides and I did a few technical demos.  The first demo included a simple introduction to Expression Blend and Media support.  The second demo included some programming Silverlight with .NET examples including HTML integration, POX, JSON WebServices, Proxy WebServices and some simple XAML constructs.

The session was very well attended.  And we had some good discussions around the Silverlight architecture and where it really fits into the Microsoft development stack.  If you are interested in learning more about Silverlight, we recorded the session.  The recording and resources (deck and demos) are available here.  http://claritycon.com/claritytv/

 

Facebook Developer Toolkit Codeplex project

We started a CodePlex project to help keep the Facebook Developer Toolkit up to date and relevant.  The project can be found here http://www.codeplex.com/FacebookToolkit.  Currently, I am working through some of the issues that have been identified and packaging up Version 1.1.  I am open to any and all help that anyone wants to contribute to the codeplex project.

Should be fun and a good way to make sure the community is able to voice problems and get updated builds.  Thanks to Microsoft for the support and commitment to this project.