Tuesday, May 29, 2012

Pitfall in Responding to Different Views With Windows 8 WinJS Solution

It's recommended to use CSS to update the layout using CSS media selector, for instance, following css defines two sizes for the column class, one for landscape and the other for portrait:
@media screen and {-ms-view-state: fullscreen-portrait} {
    .column { width: 400px;}
} 
@media screen and {-ms-view-state: fullscreen-portrait} {
    .column { width: 250px; }
}
But in some situations the page layout as well as content vary based on the view-state (this view-state refers to the screen view state for a win8 device, totally different concept from the ASP.NET view state), and CSS is not capable of handling that. In such case, we usually use DOM window's resize event for notification. Traditional way of doing that is assign the handler as below:
window.onresize = function () { // Do stuff based on current view-state};
The handler still works in WinJS but it would override other handlers. A better way is to use addEventListener:
window.addEventListener("resize", pageLayoutChanged); 
function pageLayoutChanged() {
    // Do stuff based on current view-state
}
With addEventListener you can define multiple handler functions and they will all be invoked when event is triggered (sequence not determined). Be aware that this window object is global. So all registered event handlers will be invoked when you navigate to different pages. For example, you have page1LayoutChanged event in page1 and page2LayoutChanged event in page2. When the screen's view-state is changed, both page1LayoutChanged and page2LayoutChanged function will be triggered to run no matter when accessing page1 or page2.

This behavior is totally fine in Web application where new DOM objects and Javascript references are constructed when a page is loaded from server and rendered inside the browser. That's not the case for a WinJS app since all Javascript closures are still effective when running inside WinJS context. This may cause problem sometimes. Let's look at an example here. References to page1 local objects inside page1LayoutChanged function will be null when you are on page2. So we need to have some logic to check if it's current page inside the event handler function in this case. An easy way is check if a page DOM element exists or not:
// page1 view-state change event handler
function pageLayoutChanged() {
    var pageElement = document.getElementById("page1Header");
    if (pageElement) { 
        // Do stuff based on current view-state
    }
}
If you happen to use WinJS Navigation App template in which a pre-defined resize handler inside navigator.js will check and call a "updateLayout" page function, so you could just your add view-state change logic inside the updateLayout function without registering resize event handler:
updateLayout: function (element, viewState, lastViewState) {
    var pageElement = document.getElementById("page1Header");
    if (pageElement) { 
        // Do stuff based on current view-state
    }
}
Another note is that we use document.getElementById function to get a DOM element from the page. Actually there's a short-cut for element selector in WinJS app: simply reference any DOM element in Javascript by its unique ID. So following Javascript is equivalent to above version:
updateLayout: function (element, viewState, lastViewState) {
    if (page1Header) { 
        // Do stuff based on current view-state
    }
}

Saturday, May 26, 2012

More On WinJS Promise

I did some research on WinJS Promise in my previous post. Here are some more findings:

What's the difference between Promise then and done functions?

WinJS Promise then and done both take three optional functions (onComplete, onError, onProgress) as parameters. Promise then function returns another Promise object so you can chain the Promise one by one like fnAsync().then().then()... On the other hand Promise done function doesn't return any value so it should be used at the end of the flow.

The Promise error will be thrown as an unhandled exception if there's no error handler is defined in the Promise chain even the Promise execution of that error is wrapped inside a try catch block. The difference is that the Promise then function will swallow the error and keep going forward to the next chained Promise until the error handler is found, but Promise done function would throw the error immediately. Note that the regular JavaScript exceptions (not the Promise error) remain the same behavior inside both then/done functions, and they can be handled by try catch block.

What to return from a Promise then function?

Promise then function returns a Promise. If the callback function has a return value (not a Promise), WinJS will create a Promise to return and the callback function’s return value will be passed to the next callback back function. Method addThenDouble1 and addThenDouble2 have the same result in following code snippet:
    function addAsync(number1, number2) {
        return new WinJS.Promise(function (c, m, p) {
            setTimeout(function () {
                c(number1 + number2);
            }, 1000); // Caculate after one second
        });
    }

    function addThenDouble1(number1, number2) {
        return addAsync(number1, number2).then(function (data) {
            return data * 2;
        });
    }

    function addThenDouble2(number1, number2) {
        return addAsync(number1, number2).then(function (data) {
            return new WinJS.Promise(function (c, m, p) {
                c(data * 2);
            });
        });
    }

    function test() {
        addThenDouble1(2, 3).then(function (data) {
            var value = data; // value = 10;
        });

        addThenDouble2(2, 3).then(function (data) {
            var value = data; // value = 10;
        });

        addAsync(2, 3).then(function (data) {
            return new WinJS.Promise(function (c, m, p) {
                c(data * 2);
                return 100; // this line of code has no effect
            });
        }).then(function (data) {
            var value = data; // value = 10;
        });

        addAsync(2, 3).then(function (data) { return data * 2; }).then(function (data) {
            var value = data; // value = 10;
        });
    }
We can see such logic in one of its overloading methods defined in base.js from WinJS library:
    then: function CompletePromise_then(onComplete) {
        try {
            // If the value returned from the completion handler is the same as the value
            // provided to the completion handler then there is no need for a new promise.
            var newValue = onComplete ? onComplete(this._value) : this._value;
            return newValue === this._value ? this : new CompletePromise(newValue);
        } catch (ex) {
            return new ExceptionPromise(ex);
        }
    }
The parameter sent to the next Promise.then function will be undefined if the function doesn't return anything inside the previous then function. You can create a Promise object and send as many parameters as you want as below demo:
     fnAsync().then(function (data) {
            return new WinJS.Promise(function (c, m, p) {
                // logic to get p1, p2, p3
                c(p1, p2, p3);
            });
        }).then(function (p1, p2, p3) {
            // do stuff
        });
Would it be possible to make a Promise from async to sync or block/wait a Promise to complete?

Promise function will return immediately and it relies on callback function to do the next task. Is it possible to block the Promise object until it's complete so we can get back to the classic procedural flow like following code snippet?
    function fnAsync() {
        return new WinJS.Promise(function (c, m, p) { ... });
    }
    function fnSync() {
        var promise = fnAsync();
        // Wait until promise to complete
        var syncReturn = ?promise.getReturnValueSomehow()?
        return syncReturn;
    }
The answer is no. You may think about the Promise.join function to help, but that join function is also returning a Promise. JavaScript is a single-threaded language by design, and there's no equivalent Sleep() function which can be used to check the object state periodically. So we have to use Promise's then or done function to complete the tasks flow.

Wednesday, May 23, 2012

SharePoint Issues Caused by Inconsistent Times

Today we got some problems in our SharePoint environment after a few Windows patches installed by operation team:

1.Missing Search Bar on main page.
2.No search results when Find an Associate is used.
3.User Audiences not working (all web parts appearing on main page).
4.Missing Navigation/Links Bar on left.

It looks like something wrong with the application service at the first glance. By looking at the SharePoint log, one specific error caught my attention:

...Exception occured while connecting to WCF endpoint: System.ServiceModel.Security.MessageSecurityException: The security timestamp is invalid because its creation time ('2012-05-23T13:53:00.168Z') is in the future...

It tells there were some time-related issue in the farm. When the system admin logged in to front-end and application servers, he found there's 10 minutes difference between two servers! After syncing the time all SharePoint issues were gone and the portal was back to normal immediately.

So the root cause was the time inconsistency in the SharePoint farm, nothing related to the Windows patches. When the front-end server got a reply from the application server, it noticed response timestamp was far ahead of its local time, and then it throw a security exception and terminated further processing.

Why that time variance happened? One major reason is that our two SharePoint front-end servers are actually virtual machines, while the application server is a physical machine. The virtual machines would lose some time when hibernate or reboot if time service is not set properly.

Friday, May 04, 2012

A Study of WinJS Promise

.NET 4.5 introduces a new async/await asynchronous programming pattern. Metro Javascript library WinJS also has a similar asynchronous programming paradigm called Promise. Promise is an Javascript object with a "then" function that takes three parameters: a complete callback function, an optional failure callback function, and an optional on progress callback function. We can do something like:
    function getWebContentPromise(url) {
        WinJS.xhr({ url: url }).then(
            function (result) { // Successfully
                console.log("Get web content successfully. Data length:" + result.responseText.length);
            },
            function (err) { // Failed
                console.log("Get web content failed. Error:" + err);
            },
            function (prog) { // On progress
                console.log("Get web content on progress...");
            });
    }
I tested above script in Visual Studio 11 Beta. WinJS.xhr({ url: url }) returns immediately, and those "then" callback functions are hit later when the response content is ready or error occurs due to network issue. Looks good so far. How can I create my own Promise and asynchronous function? Say I have a simple script as follow:
    function complicatedCalculation(x, y) {
        var result = x + y;
        // fake busy work...
        for (var i = 1; i < 10000000; i++) {
            var dummy = (i * i) / i;
        }
        return result;
    }

    function getResult(x, y) {
        var result = complicatedCalculation(x, y);
        return result;
    }
It's just a heavy function that would block the UI for a while. So how can we convert it to be Promise-able? From MSDN documentation, I found Promise.as and Promise.wrap functions, and both could wrap an object in a Promise object. Unfortunately the documentation is super simple without any sample code or detail explanation, basically just useless. Forgive that since WinJS is still in Beta. Anyway I tried:
    WinJS.Promise.wrap(complicatedCalculation(x, y)).then(...
It works but it's not asynchronous, i.e. WinJS.Promise.wrap(complicatedCalculation(x, y)) doesn't return immediately, instead "then" callback functions are invoked only after the complicatedCalculation function is completed. That's not what we want. So I manually convert above method to the Promise object, whose constructor accepts three parameter, a complete callback function, an optional error callback function, and an optional on-progress callback function:
    function complicatedCalculationPromise(x, y) {
        return new WinJS.Promise(function (completeCallback, errorCallback, progressCallback) {
            try {
                var result = x + y;
                // fake some busy work here...
                for (var i = 1; i < 10000000; i++) {
                    var dummy = parseInt((i * i) / i);
                    if (progressCallback && dummy % 1000000 == 0)
                        progressCallback(dummy);
                }
                completeCallback(result);
            } catch (e) {
                errorCallback(e);
            }
        });
    }

    function getResult(x, y) {
        complicatedCalculationPromise(x, y).then(function (result) {
            return result;
        });
    }
Above code compiles okay and works without any exception. But it's still a synchronous function. The fuction complicatedCalculationPromise blocks the operation until the calculation is completed. I guess it's due to the fact that Javascript is single-threaded. Why WinJS.xhr could be asynchonous? The reason is that inside the xhr function, an XMLHttpRequest is created, a callback for response change event is registered, the request is sent out and then xhr method will return immediately without waiting the response from network. XMLHttpRequest supports asynchronous callback natively. WinJS.xhr is simply a wrapper of XMLHttpRequest and exposes it as a Promise object.

To simulate an asynchronous processing in Javascript, we could modify the script as below:
    function complicatedCalculationAsync(x, y) {
        return new WinJS.Promise(function (completeCallback, errorCallback, progressCallback) {
            var count = 0;
            var result = x + y;
            try {
                setTimeout(function () {
                    count++;
                    if (count == 10000)
                        completeCallback(result);

                    var dummy = parseInt((count * count) / count);
                    if (progressCallback && dummy % 1000 == 0)
                        progressCallback(dummy);

                    setTimeout(arguments.callee, 0);
                }, 0);
            } catch (e) {
                errorCallback(e);
            }
        });
    }
Now the function becomes real asynchronous. But we have to partition the work manually and use setTimeout timer function to hand back control to Javascript execution thread periodically. All those hustles are due to the limitation of single-threaded Javascript model for UI processing. In HTML5 Web Workers allows you to load the Javascript dynamically and run it in background thread, and you can pass result back to the UI thread. I hope that when WinJS.Promise is final released, it could have an option to integrate with Web Workers so asynchronous execution can be run in a separate background thread. That would be a big lift in my opinion.