Saturday, October 31, 2009

AJAX publish/subscribe

Calling long running web server process and locking the user for a while in web applications with the typical for the HTTP request/replay way can be critical for the user expirience. Even more, possibly we don't get back the data due to problems with the network connection or browser timeouts.

Even if on top of unreliable protocol like HTTP we can provide some abstraction level to ensure we'll get the result from the web server. We could simulate the publish/subscribe pattern in ajax. Furthermore our communication with the web server is asynchronous and allows our application to respond better to the user interactions.

On the web server we could implement multithreading and open working threads which get the calculations done.

With javascript we send request to the web server and then in some interval of time we again and again ask if the server has prepared the result. When the web server has collected the information we need, we take the data from the web server, display on the page and stop the repetative calls to the web server.

I will implement publish/subscribe with ASP.NET MVC and jQuery.

The CityWeather model



First i'll create model class CityWeather. The only public properties of CityWeather object are "City" and "Temperature".

After CityWeather class created, the constructor calls Measure() in thread. The Measure() function simulates long running process used to collect the weather information for that city.

We store all the requests for measurements in static collection _measurements. The keys of this collection are the city names.

The only public function of the model class is the static function GetCityWeather() which when called will check if in _measurements exists object CityWeather for this city. If not will create one. The function returns back the corresponding CityWeather object from the _measurements collection.



namespace PublishSubscribe.Models
{
// Measurements per city.
// Call class method CityWeather.GetCityWeather(city)
// to get CityWeather object with measurements
// for that city.
// Repead calling CityWeather.GetCityWeather(city)
// until city.Temperature is not null.
public class CityWeather
{
// Holds all requested measurements.
// Used from class method GetCityWeather()
// The keys are city names.
// The values are CityWeather objects.
private static Dictionary<string, CityWeather> _measurements =
new Dictionary<string, CityWeather>();

// public properties of CityWeather object:
public string City { get; private set; }
public int? Temperature { get; private set; }


// The constructor itself starts measurement
// in an asynchronous thread.
private CityWeather(string city)
{
this.City = city;

// after the object is constructed will start
// doing measurement in a thread, which respectively
// takes some time
ThreadStart ts = new ThreadStart(Measure);
Thread th = new Thread(ts);
th.Priority = ThreadPriority.Lowest;
th.Start();
}

// Worker method started in separate thread from
// the constructor
private void Measure()
{
// measurement takes some time - up to a minute
Thread.Sleep(new Random().Next(1,6) * 10000);

// lock the object alowing concurent access
// to the object properties
lock (this)
// degrees Celsius between 10 and 20
Temperature = new Random().Next(10, 20);
}


// The only public method that capsulates all the logic
// of keeping single instances - one per city -
// just as static memory for the purpose of the
// demonstration.
//
// Keep calling CityWeather.GetCityWeather(city) until
// you get back an CityWeather object with
// property Temperature which is not null.
public static CityWeather GetCityWeather(string city)
{
lock (_measurements)
{
if (! _measurements.ContainsKey(city))
{
CityWeather cw = new CityWeather(city);
_measurements.Add(city, cw);
}

return _measurements[city]; // check
}
}
}
}



The usage of this class is pretty simple. We call the static function CityWeather.GetCityWeather() with the name of a city to get weather measurements for that city. We repeat the call again and again until we get back CityWeather object where Temperature property is set - is not null, but contains value.



The Weather controller



Then I'll create the controller class:



namespace PublishSubscribe.Controllers
{
public class WeatherController : Controller
{
public JsonResult Measure(string city)
{
return Json(Models.CityWeather.GetCityWeather(city));
}

public ActionResult Index()
{
return View();
}
}
}



The controller has two methods. Measure gets weather measurements for one given city. We send back JSON result.

The Index method we will use to create page where we will demonstrate how the AJAX publish/subscribe calls will work.

We are ready to try how the Measure JSON handler will respond and to see the how the CityWeather model will work. We run the application and navigate to /weather/measure where we request measurements for a city and repetative hit repoad on the browser until we receive back the Temperature calculated.

Here is how example session with repetative calls looks like:




URL: http://localhost:3284/weather/measure/?city=berlin
Response: {"City":"berlin","Temperature":null}
...
URL: http://localhost:3284/weather/measure/?city=berlin
Response: {"City":"berlin","Temperature":null}
...
URL: http://localhost:3284/weather/measure/?city=berlin
Response: {"City":"berlin","Temperature":12}




AJAX publish/subscribe with jQuery



Now I'm going to implement the web page to demonstrate the idea behind the AJAX publish/subscribe.

The html body tag is very simple.



<body>

<label for="city">City:</label>
<input type="text" id="txtCity" />
<input type="button" value="measure" id="btnMeasure" />

<table id="cites">
<thead>
<tr><td style="width:200px">City</td><td>Temperature</td></tr>
</thead>
<tbody>
</tbody>
</table>

</body>



We write city name into the input box and click the "measure" button. We repeat that several times with other city names. We expect whenever the server has measured the weather for a city we asked for, the result will be added to the table as new row. The order of the cities we ask for measurements is not necessarily the order we'll get back calculated measurements. The time the server will spend to take weather measurements may vary from city to city and is not presumable.

This way we will have asynchronious communication with the server and the user will appreciate the better respond from the application.


Last, I'll put some javascript after the closing body task and will automate the html page with jQuery.

As we don't have multithreading in javascript we simulate it with setInterval and clearInterval. We start repetative calls as we run sendMeasureRequest(city) every second and ask the web server if the measurements for that city are calculated. Once the server gives back calculated results we stop the repetative calls.

The setInterval() function gives us interval ID which we later use at calling clearInterval() to stop repetative tasks. Then we also need to map somewhere interval ID to city name, thereof we create array measurements which keys are city names. The values of the measurements dictionary are data structures wich hold interval ID, city name and the temperature as measured from the web server.

Once the web server respond calculated measurement we stop the corresponding repetative calls to the web server and call the function cityMeasured(). We add new row into the table with the measurements.



<script type="text/javascript">

/* Hash array of all collected measurememts */
var measurements = new Array();

/* Does weather measurement for a city */
function measureCity(city) {
if (measurements[city] == undefined) {
// send request to the server every one second
var intervalID = setInterval(sendMeasureRequest, 1000, city);
measurements[city] = {
IntervalID: intervalID,
City: city,
Temperature: null
};
sendMeasureRequest(city);
}
cityMeasured(city);
}

/* Send GET request to the server to collect weather measurements for a city */
function sendMeasureRequest(city) {
$.ajax({
'url': '<%= Url.Action("Measure") %>',
'type': 'GET',
'dataType': 'json',
'data': { 'city': city },
'success': function(data) {
if (data.Temperature != null) {
clearInterval(measurements[data.City].IntervalID);
measurements[data.City].Temperature = data.Temperature;
cityMeasured(data.City);
}
}
});
}

/* Does weather measurement for a city */
function cityMeasured(city) {
if (measurements[city].Temperature != null) {
if ($('#tr_' + city).length == 0) {
$("#cites > tbody").append('<tr id="tr_' + city + '"><td>'
+ measurements[city].City
+ '</td><td>'
+ measurements[city].Temperature + ' grad'
+ '</td></tr>');
}
}
$('#tr_' + city).fadeOut();
$('#tr_' + city).fadeIn();
}

/* SetUp click handler */
$(document).ready(function() {
$("#btnMeasure").click(function() {
var city = $("#txtCity").val();
measureCity(city);
});
});
</script>



After I ran the application and navigated to /weather/ I asked for weather measurements for the following cities in the exact order: Paris, Boston, Rom, Hamburg

Then I waited few seconds and the weather measurements were displayed to the page one after other:




Well, we may consider as next to be done, once the weather in city from the table has charnged, we refresh the information on the table.

Atanas Hristov

kick it on DotNetKicks.com
Shout it

Tuesday, October 13, 2009

Design Patterns – Abstract Factory Pattern

Factories are objects that encapsulate the logic for creating other objects.

Factory object could create one or another object based on some configuration parameters. Or the factory could decide what kind of concrete object to create based on a parameter to some object creational method. For example if the method received post-code the factory creates City object and when the parameter is an email address the factory creates Customer object. In that way one might create factory to select one or another kind of object from database based on the user input.

Abstract Factory



The Abstract Factory is that encapsulates the way of creating concrete objects that have lot of common.

Often the created from abstract factory objects derive from same base class or share some interface. Abstract factory object for example could be used to create fake objects for the purpose of testing the software, and create regular objects otherwise in production mode. The fake object and the regular object derive from same base class or share same interface. The client code deals only with instances of the base type and has no knowledge of the concrete implementation.

I will give an example of abstract factory created with C#.

Reflection based abstract factory



The central feature of our abstract factory is to create concrete objects based on key/value pairs.

We register the types the factory is able to create into a dictionary. For registration of the types the factory may create we expose method Register().

Our base abstract factory class uses reflection to call the object constructors of the concrete type. That is done in method CreateInstance(). We invoke CreateInstance() with:



  • key - that will be used to create one concrete object or another as it is registered already via Register().


  • typeParams - if the concrete object has parameterized constructor which we want to use, then we specify the parameter types in an array.


  • valParams - if the concrete object has parameterized constructor which we want to use, then we specify the parameter values in an array.





Following is a implementation of reflection based abstract factory:




// T1 is the appropriate key type.
// T2 is the base type from which derive all the types the factory can create.
public abstract class AbstractFactory<T1, T2>
{
// Creates the factory.
// T1 is the appropriate type.
// T2 is the base type from which derive all the types the factory can create.
public static AbstractFactory<T1, T2> CreateFactory()
{
throw new Exception("Override FactoryReflected.CreateFactory()!");
}

// Register for types the factory can create.
protected Dictionary<T1, Type> _registered = new Dictionary<T1, Type>();

// Registers the specified factory types.
protected void Register(T1 key, Type type)
{
_registered.Add(key, type);
}


// Creates new instance of type by enumeration key.
public T2 CreateInstance(T1 key, Type[] typeParams, object[] valParams)
{
Type type = _registered[key];

System.Reflection.ConstructorInfo cInfo =
type.GetConstructor(typeParams);

return (T2)cInfo.Invoke(valParams);
}

}


We also have used generics to make the implementation of reflection based abstract factory more generalized.




Personal name



Let's face the problem and how we are going to find a solution. The different societies have different conventions for personal full name. In Russia the common order is "family-name given-name". In some situations the family-name is capitalized. In west Europe the usual convention is "given-name family-name", etc.

Our problem is - we are going to use the appropriate form of address when we communicate with people from different regions. For simplicity assume we have the family and the given name. We need a way to compose appropriate full name.

First we have the base class Name. The Name class has first and last name properties. We also have an abstract method GetFullName() which should give different result for different society. Furthermore, the concrete implementation will be done in derived classes:



// Base abstract class from which concrete implementations derive
public abstract class Name
{ // see http://en.wikipedia.org/wiki/Full_name#Naming_convention

protected string firstName;
protected string lastName;
protected Name() { }
public Name(string first, string last)
{
this.firstName = first;
this.lastName = last;
}

// Full name can be composed differently
// as the different societies have they different
// naming conventions
public abstract string GetFullName();
}

// composing Western full name
public class WesternName : Name
{
public WesternName(string first, string last) : base(first, last) { }
public override string GetFullName() { return firstName + " " + lastName; }
}

// composing Eastern full name
public class EasternName : Name
{
public EasternName(string first, string last) : base(first, last) { }
public override string GetFullName() { return lastName + " " + firstName; }
}

// another Eastern full name convention
public class EasternOfficialName : Name
{
public EasternOfficialName(string first, string last) : base(first, last) { }
public override string GetFullName() { return lastName.ToUpper() + " " + firstName; }
}





Concrete factory



Having the abstract factory from above we create concrete factory used for creation of objects of classes derived from the Name class. The NameFactory contains the initialization of itself in method CreateFactory(). If we create new concrete class derived from class Name to fit another convention for personal full name then we also have to register that new class in CreateFactory() method.



public class NameFactory : AbstractFactory<string, Name>
{
private NameFactory() { }

public static new NameFactory CreateFactory()
{
NameFactory factory = new NameFactory();

// Register which concrete type to create for which key
factory.Register("WesternOrder", typeof(WesternName));
factory.Register("EasternOrder", typeof(EasternName));
factory.Register("EasternOfficialOrder", typeof(EasternOfficialName));

return factory;
}
}




We will create instances of NameFactory only via the static method CreateFactory() and thereof we have specified the default constructor to be private.






Using the concrete factory



We create nameFactory object and then call one after another GetFullName() of all possible derived from class Name objects. These derived from Name objects we create as we call method CreateInstance() of nameFactory.



class Program
{
static void Main(string[] args)
{
NameFactory nameFactory = NameFactory.CreateFactory();

foreach (string convention in new string[] {
"WesternOrder", "EasternOrder", "EasternOfficialOrder", })
{
Name name = nameFactory.CreateInstance(convention,
new Type[] { typeof(string), typeof(string) },
new object[] { "Atanas", "Hristov" });

Console.WriteLine(name.GetFullName());
}


Console.Read();
}
}



And finally the output to the console:






Atanas Hristov

kick it on DotNetKicks.com
Shout it