Twitter At Scale: Will It Work?

Posted on May 23rd, 2008 in Industry News, Ruby On Rails by Ashish  Tagged

Only two days ago the contact messaging application Twitter suffered another bout of downtime, leaving some users frustrated and others asking why the platform continues to suffer problems.

I have recently spoken to an individual who is familiar with the technical problems at Twitter as well as the challenges that lay ahead for the startup. He re-iterated his belief that the problems lay not with Blaine Cook (the former head of engineering who was shown the door), nor with Joyent NTT (their host) but with the early lack of understanding of how complex their problems would be.

The issue is that group messaging is very difficult to achieve at a grand scale. Other large sites such as Wordpress and Digg are mostly dealing with known problems, such as how to serve a large number of pages or a large number of images. Twitter is unique in that it needs to parse a large number of messages and deliver them to multiple recipients, with each user having unique connections to other users.

Social networks have similar complexity issues, but they only usually need to route a message to a single user (or at the most to a defined group). Even so, social networks like Friendster struggled for years with technical and scaling issues. Twitter is specifically dealing with text messages, and in most cases with active users those messages are very frequent and go out to hundreds of contacts (or followers, as they are referred to in Twitter). Every new Twitter user and every new connection results in an exponentially greater computational requirement.

Some of the best web applications are able to efficiently solve very complex problems to produce simple results for users (Eg. Google). The success of these applications is due to the innovative efforts by developers to solve large technical challenges, where they have often had to break new ground for solutions. For Twitter to reach a similar point of reliability they too will need a very comprehensive, ground-breaking solution.

The source that I spoke to also commented on how ill-prepared the Twitter team were and are for their current and future challenges. The small team contains a handful of engineers, with only a person or two committed to infrastructure and architecture. He goes on to point out that at Digg the team for network and systems alone is bigger than the total engineering team at Twitter, and that at Digg they are lead by well-known “A-list rockstars”.

The problems at Twitter are often attributed to their use of RubyOnRails, a web development framework. Twitter is almost certainly the largest site running on Rails, so fans of the framework and its developers have been quick to deflect the criticism and point it back at the engineers at Twitter. Utilizing a framework that has never conquered large-scale territory must certainly add to the risk and work required to find a solution. As an out-of-the box framework, Rails certainly doesn’t lend itself to large-scale application development, but was a big part of the reason why Twitter could experiment and release early.

Rails has enabled Twitter to prototype quickly, to quickly launch and then to easily iterate with new features. But the old adage of “Good, Fast, Cheap – pick two” certainly applies; and Rails would do itself no harm by conceding that it isn’t a platform that can compete with Java or C when it comes to intensive tasks. Twitter is at a cross-roads as an application and Rails has served its purpose very well to date, but you are unlikely to see a computational cluster built with Ruby at Apache any time soon.

What we see at Twitter today is a very useful and popular service, but one with very complex underlying technical challenges to overcome. Twitter will require not only a new architecture approach and a big injection of the best minds they can find ($15 million can help), but will also need a little patience from users and those of us observing.

FriendFeed Launches Rooms

Posted on May 23rd, 2008 in Industry News by Ashish  Tagged

Activity stream aggregator FriendFeed launched a new feature called FriendFeed Rooms this afternoon, which are effectively topic-based accounts that anyone can create or join (depending on privacy settings). Users can then add links and messages to relevant content.

The main difference between Rooms and a normal FriendFeed account is the fact that multiple users can author it, and that you can’t pull third party feeds into the service.

FriendFeed usage continues to grow steadily, and has clearly gained from Twitter’s (a competitor of sorts) constant downtime. I still haven’t gone religious on it, though, as some have. That’s mostly because i don’t like having a third party service centralize all this data about me and then not let that data back out again. See my rant on the Centralized Me for more on that.

According to FriendFeed a room is like a mini FriendFeed for a particular subject or group of people. You can make a room for your family, your work team, or your knitting club. If you’d like to see what a room looks like, check out the FriendFeed News room, a public room where people share and discuss FriendFeed in the press. Everyone in your room can share stuff with each other and leave comments that only other people in your room can see. You decide whether to make your room public, where anyone can join, or private, where you have to invite or approve each member. You can even choose to view everything from your rooms in your feed, instead of just in the rooms themselves.

Calculating time by converting between time zones using PHP and PEAR

Posted on May 15th, 2008 in PHP by Ashish  Tagged

PHP comes with an extensive catalog of date and time functions, all designed to let you easily retrieve temporal information, massage it into a format you require, and either use it in a calculation or display it to the user. However, if you’d like to do something more complicated, things get much, much hairier.

A simple example of this involves displaying the time on a Web page. With PHP, you can easily use the date() function to read the server’s clock and display the required information in a specific format. But what if you’d like to display the time in a different location – for example, if your company is located in a different country from your server and you want to see “home” time instead of local time? Well, then you have to figure out the difference between the two places and perform some date arithmetic to adjust for the different time zones. If the time difference is significant, you need to take account of whether the new time is on the day before or after, worry about daylight savings time, and keep track of end-of-the-month and leap year constraints.

As you can imagine, the math to perform such time zone conversions can quickly get very complicated if you do it manually. To be fair, PHP has built-in time zone functions to help with this, but these aren’t particularly intuitive and require a fair amount of time to get used to. A quicker alternative is to use the PEAR Date class, which comes with built-in support for time zones and is, by far, the simplest way to perform these conversions.

This tutorial will teach you how to convert temporal values between time zones with the PEAR Date class. It assumes that you have a working Apache and PHP installation and that the PEAR Date class has been correctly installed.

Note: You can install the PEAR Date package directly from the Web, either by downloading it or by using the instructions provided.

Getting started

Let’s begin with the basics – initialising and using a Date object. Create a PHP script with the following lines of code:

getDate();
?>

This is fairly simple – include the class code, initialise a Date() object with a date/time string, and then use the getDate() method to display the value you just inserted. Here’s the output:

2006-06-21 15:45:27

What if you want the date in a different format? If the format is a standard one, such as the ISO format, simply pass getDate() a modifier indicating this:

getDate(DATE_FORMAT_ISO_BASIC);
?>

The output in this case conforms to the standard ISO format.

20060621T154527Z

If you’d like a custom format, you can do that too, with the format() method. Like PHP’s native date() function, this method accepts a series of format specifiers that indicate how each component of the date is to be formatted. Below is an example (look in the class documentation for a complete list of modifiers):

format("%A, %d %B %Y %T");
?>

And here’s the output:

Wednesday, 21 June 2006 15:45:27

Converting between time zones

Now that you’ve got the basics, let’s talk about time zones. Once you have a Date() object initialised, converting from one time zone to another is a simple two-step process:

1. Tell the Date class which time zone you’re converting from, with the setTZByID() method.
2. Then, tell the Date class which time zone you wish to convert to, with the convertTZByID() method.

setTZByID("GMT");

// convert to foreign time zone
$d->convertTZByID("IST");

// retrieve converted date/time
echo $d->format("%A, %d %B %Y %T");
?>

In this case, I’m attempting to convert from Greenwich Mean Time (GMT) to Indian Standard Time (IST). India is about 5.5 hours ahead of Greenwich, which is why the output of the script is:

Wednesday, 21 June 2006 16:06:27

Simple, isn’t it? Here’s another example, this one demonstrating how the class handles leap years and month end values.


// include class
include ("Date.php");

// initialize object
$d = new Date("2008-03-01 06:36:27");

// set local time zone
$d->setTZByID("GMT");

// print local time
echo "Local time is " . $d->format("%A, %d %B %Y %T") . "\n";

// convert to foreign time zone
$d->convertTZByID("PST");

// retrieve converted date/time
echo "Destination time is " . $d->format("%A, %d %B %Y %T");
?>

And the output is:

Local time is Saturday, 01 March 2008 06:36:27
Destination time is Friday, 29 February 2008 22:36:27

Note: In case you’re wondering where the time zone IDs come from, you can find a complete list within the class documentation.

Calculating GMT offsets

Another piece of information that’s sometimes useful when working with time zones is the GMT offset — that is, the difference between the specified time zone and standard GMT. The PEAR Date class lets you get this information easily, via its getRawOffset() method. Here’s an example:

setTZByID("PST");

// get raw offset from GMT, in msec
echo $d->tz->getRawOffset();
?>

Here, the getRawOffset() method calculates the time difference between the local time and GMT. Here’s the output:

-28800000

Note that this offset value is expressed in milliseconds, so you will need to divide it by 3600000 (the number of milliseconds in one hour) to calculate the time zone difference in hours.

Tip: You can use the inDaylightTime() method to see if the destination is currently observing daylight savings time. Look in the class documentation for details on this method.
Adding and subtracting timespans

The Date class also lets you perform sophisticated date arithmetic on temporal values, adding or subtracting durations to a date/time value. These durations (or timespans) are expressed as a string containing day, hour, minute and/or second components.

addSpan(new Date_Span("0,1,20,0"));

// retrieve date as formatted string
echo $d->format("%A, %d %B %Y %T");
?>

In this case, I’ve added an hour and twenty minutes to the initial timestamp, by calling the Date class’ addSpan() method and supplying it with a Date_Span() object initialised to that duration. The output is fairly easy to guess:

Wednesday, 21 June 2006 17:05:27

Just as you can add timespans, so too can you subtract them. That, in fact, is the purpose of the subtractSpan() method, which is illustrated below.

addSpan(new Date_Span("0,1,20,0"));

// subtract 00:05 from it
$d->subtractSpan(new Date_Span("0,0,5,0"));

// retrieve date as formatted string
echo $d->format("%A, %d %B %Y %T");
?>

Here, I’ve first added an hour and twenty minutes, and then subtracted a further five minutes. The net effect is an addition of an hour and fifteen minutes, and the output reflects this:

Wednesday, 21 June 2006 17:00:27

As the examples above illustrate, the PEAR Date class provides methods to intuitively and efficiently perform fairly complex date math. If you’re looking for a stress-free way to convert timestamps between different locations, I’d heartily recommend it to you.

10 reasons to use PEAR classes

Posted on May 15th, 2008 in PHP by Ashish  Tagged

Most PHP Web developers have heard of PEAR, the PHP Extension and Application Repository, but very few of them actually use it on a regular basis. Here are 10 reasons to get started today.

Most PHP Web developers have heard of PEAR, the PHP Extension and Application Repository, but very few of them actually use it on a regular basis. This is an oversight that should be corrected, because PEAR is actually a rich treasure trove of PHP widgets that can significantly simplify the average Web developer’s workday.

If you think I’m overstating the benefits, ask yourself if you’ve ever written custom code to (a) create HTML e-mail, (b) generate Web forms on the fly, or (c) validate email addresses. PEAR has pre-built PHP packages for all these tasks, and a few hundred more besides. These packages provide a robust, well-tested code base that can save you the time and effort you would otherwise spend on “rolling your own” code. You can’t beat the price either…they’re free!

PEAR classes cover a wide range of tasks, and so this document will focus specifically on classes of interest to developers working with Web pages and form input. If there are other categories you’d like to see addressed, send in your suggestions and we will examine those areas too…and until then, here’s to easier coding!

Note: You can install PEAR packages directly from the Web, by following the provided instructions.

Package Name: Validate
Description: This package provides validation routines for common input types: email addresses, credit card numbers, URLs, dates and times, string and number classes, and more.

Use this package to test user input entered in Web forms and ensure it is valid before using it in a calculation/saving it to a file or database.

URL: http://pear.php.net/package/Validate

Calendar
This package creates calendar data structures for one or more months. These data structures can then be combined with HTML formatting or a template to create a calendar display, complete with forward/backward navigation links.

Use this package to quickly integrate a pop-up Web calendar into a Web site.

http://pear.php.net/package/Calendar

Mail_Mime
This package provides routines to create a MIME-compliant multi-part message. Such a message can contain embedded HTML, images, file attachments, or other parts. The package also provides functions to decode received multi-part messages into their constituent parts.

Use this package to create HTML email with embedded images, or messages with one or more attachments. You can also use this class to decode multi-part messages – for example, as an attachment browser in a Web mail client.

http://pear.php.net/package/Mail_Mime

Cache
This package provides a simple caching framework for a Web site. It allows you to cache the output of PHP scripts as well as function calls, and reduce response times by rendering the cached pages to clients. Cached pages may be stored as files on disk, in a database, or using a custom storage engine.

If your site receives a lot of traffic, use this package to reduce server load and page processing time by occasionally providing clients with snapshots from the page cache instead of the “live” page. You can also reduce the load on your database server by caching the output of frequently-used SQL queries.

http://pear.php.net/package/Cache

Image_Graph
This package makes it possible to automatically convert numerical data into a graph suitable for display on a Web page. Bar, graph, pie, radar and scatter graphs are just some of the supported graph types. X and Y axis customisations are supported, as are many different output formats.

Use this package to display numerical data in a visual manner for easier comprehension – for example, when calculating Web site traffic or ad clicks.

http://pear.php.net/package/Image_Graph

HTML_QuickForm
This package provides routines to generate, validate, and process Web forms programmatically. It supports all the HTML form input types, and comes with built-in validation routines for most common input types. It also provides built-in functionality for multi-page forms and file upload forms.

Use this package to significantly simplify the task of generating Web forms at run-time, or to efficiently validate and process form input.

http://pear.php.net/package/HTML_QuickForm

Auth
This package provides a framework for a basic login/authentication system using PHP. It can verify user credentials against a variety of data sources, including MySQL databases, ASCII files, LDAP servers and POP3 servers.

Use this package to quickly create a login system for a Web application. Because it has “out of the box” support for so many authentication sources, it can also be used to implement Web-based “single login” infrastructure.

http://pear.php.net/package/Auth

XML_RSS
This package is designed to parse RSS documents. It extracts information from an RSS feed as PHP data structures, which can be processed and formatted for display.

Use this package to integrate RSS feeds from other sites into your Web pages.

http://pear.php.net/package/XML_RSS

HTML_Progress
This package provides a framework for a progress bar on a Web site. It uses PHP, JavaScript and CSS to display and dynamically update a progress bar with visual notification of a task’s progress.

Use this package to display progress bars for time-consuming Web tasks — for example a file upload or a long-running loop.

http://pear.php.net/package/HTML_Progress

Translation
This package provides a framework for multi-lingual Web sites. It contains routines to retrieve a translation for each string value from a database and insert it into the appropriate location on each translation-enabled page.

Use this package to efficiently handle multi-language versions of a Web site.

http://pear.php.net/package/Translation/

Running XPath queries in PHP

Posted on May 15th, 2008 in PHP, XML by Ashish  Tagged ,

XPath is a language that allows you to address parts of an XML document, making XSLT transformations practically necessary. It also makes it an invaluable tool for managing XML data in applications such as Web applications.

Microsoft provides XPath functionality through the selectSingleNode() and selectNodes() methods on DOM nodes and documents. However, PHP uses functions that provide XPath functionality through contexts. In the following example, I’ll show sample XML data and PHP code to grab different parts of the XML document. I’ll also explain how the PHP code works.

In the example code, I use the following XML data to provide the functionality. (Note: This code was developed and run successfully using PHP 4.3.4, Windows XP, and IIS 5.1.)


Marmaduke
Garfield

Snoopy
Heathcliff

Spike
Sylvester

This XML data contains a few elements and some attributes including a namespace declaration — some basic XML. This results in varied queries for me to test.

<?php
$sxml = '

            Marmaduke
            Garfield

            Snoopy
            Heathcliff

            Spike
            Sylvester

    ';

$xml = domxml_open_mem($sxml);

$xpc = xpath_new_context($xml);
xpath_register_ns($xpc, "x", "http://www.someplace.com");

$nodes = xpath_eval($xpc, "//x:row/x:dog[@color='yellow']/text()");
foreach ($nodes->nodeset as $node) {
    print $node->content . "\n";
}

$nodes = xpath_eval($xpc, "//x:row/x:dog");
foreach ($nodes->nodeset as $node) {
    print $xml->dump_node($node) . "\n";
}

$nodes = xpath_eval($xpc, "//x:cat/child::text()|//x:dog[@color='white' or
@color='gray']/text()");
foreach ($nodes->nodeset as $node) {
    print $node->content . "\n";
}

$xml->free();
?>

First, I create a local variable to hold the XML string. This information could have been passed in as part of a POST HTTP request. However, for this example, I’m going to include it in the code. The next step is to create a DOM Document by using the domxml_open_mem() function. This function creates a DOM Document object in memory from a valid XML string. It accepts one parameter: the XML string. Another way to accomplish this is to store the XML in a separate file and use the domxml_open_file() function to load the XML from a file. This function takes one parameter: the filename of the XML file.

Once I create the DOM Document object, I can create an XPath context with this object through the xpath_new_context() function, which takes one parameter: the current DOM Document object. This context is used to evaluate the XPath expression and is also used to register namespaces, if needed. Since my XML includes a namespace, I register the namespace with the xpath_register_ns() function. This makes it possible to create XPath queries using prefixes. The xpath_register_ns() function takes three parameters: the XPath context, the prefix, and the namespace, respectively.

Now I can run XPath queries. This is done with the xpath_eval() function, whose first parameter is the XPath context and second parameter is the XPath expression. The function returns an array of DOM Nodes. In my code, I step through the nodeset and produce some form of output.

In the first XPath example, I grab all the x:dog text elements under the x:row nodes, where the ‘color’ attribute equals ‘yellow’. This is where the XPath expression in PHP differs slightly from an XPath expression using MSXML. I include the ‘/text()’ part of the expression to return the text nodes only. With MSXML, you access the text node with the ‘text’ property. Using the ‘content’ property on the returned text node, I can get the content of the text node.

In the second example, I grab all the x:dog elements under the x:row nodes. However, I use the dump_node() method on the DOM Document object to print out the complete XML of the appropriate node. The dump_node() method accepts one parameter: the DOM Node of which you wish to dump the contents.

In the last example, I grab all the x:cat text nodes and all the x:dog text nodes where the ‘color’ attribute is ‘white’ or ‘gray’. Once again, I step through the nodeset and print out the content of each text node. Finally, I free up the DOM Document object.

Mapping visitors’ IP addresses in PHP

Posted on May 15th, 2008 in PHP by Ashish  Tagged

Sometimes you just need to know what country your site visitors are coming from—for example, if you’re trying to implement geo-targeted advertising. This article will show you how.

Sometimes you just need to know what country your site visitors are coming from—for example, if you’re trying to implement geo-targeted advertising. That’s where a tool like MaxMind’s GeoIP comes in—it lets you easily extract geographic data from your visitor’s IP address.

MaxMind makes available both commercial and free databases; the commercial ones are extremely precise and can get as fine-grained as the user’s city, while the free version can only identify the country of origin. We’ll use the free version in this article. If you need more detailed information, such as the remote client’s city and state of origin, you will need to purchase a more detailed database from MaxMind.

Getting started
To use it, you’ll have to first download the GeoIP Free Country file and extract it into a directory in your Web server. Then you’ll have to pick which language API to use with the database file. For simplicity, we’re going to use the pure PHP version because it doesn’t require any additional configuration or Apache modules. Remember to read the license terms before installing these on your Web site to ensure you are in compliance.

The code below demonstrates the basics of using the module (geoip.inc) to access the GeoIP Free Country database (GeoIP.dat). The example assumes both the PHP include and the country database file are in the same directory as the PHP file itself. You’ll have to change the paths as needed if this is not the case in your installation.


The sample code is pretty straightforward. After including the GeoIP PHP function library, the first step is to open the GeoIP database file with the geoip_open() function. This function accepts two arguments: the path to the database file and the type of database.

We then use the handle returned by the call to geoip_open() to obtain the two-letter country code and human-friendly name corresponding to the given IP address, via the geoip_country_code_by_addr() and geoip_country_code_by_name() functions, respectively. Both functions accept two arguments: the handle returned by geoip_open() and the IP address to resolve.

Once the required information is obtained, we close the database file with a call to geoip_close(). Simple as that.

Report creation with .NET’s various reporting options

Posted on May 14th, 2008 in .Net by Ashish  Tagged
Developers often cringe when they have to create reports, but there are numerous options available with .NET to simplify the process. Tony Patton offers you a look at .NET’s various reporting options.
Data is the lifeblood of the enterprise and almost every application you develop will tap data in some manner. With all that data, users eventually want to view it in a report.

Many novice developers foolishly tackle reporting by creating custom forms—but this legwork is not necessary, as there are plenty of options with .NET for creating reports by dragging and dropping or a custom object model. In addition, reporting solutions offer additional functionality like PDF generation and charting that is hard to duplicate with custom code. .NET’s choices include readily available options, third-party products, and open source solutions. Let’s take a closer look at the reporting options available with .NET by category.

Readily available reporting options
I was very excited when I first encountered .NET with Visual Studio .NET. My enthusiasm stemmed from the inclusion of Crystal Reports within the environment. That’s right, no more purchasing and installing the product (although a standalone version is still available). My excitement was quickly extinguished as I tackled my first product utilizing Crystal Reports functionality. Its documentation is arcane and getting everything working properly is a bit mind-numbing. As time as passed, a few books have appeared on the subject and there are numerous Web resources as well. One in particular that I would recommend is Crystal Reports .NET Programming by Brian Bischof.

While Crystal Reports is readily available, the Microsoft Office Suite is seemingly everywhere as well. You may utilise Excel or Word functionality in a Windows client application or use the Office Web Components for browser clients. The different applications are readily accessible via your .NET code. Or, your enterprise may opt for another suite such as StarOffice or OpenOffice. Whatever the product, you can take advantage of it in your application. If these products are not a viable option, there are plenty of third-party products available.

Third-party products
Here is a sampling of third-party .NET reporting solutions. Free trial versions are available for most products, so you can give it a test run before making a commitment. Of course, there are open source options available as well.

  • ActiveReports for .NET: A managed implementation of the popular ActiveReports engine and report viewer. It provides complete code integration with the Visual Studio .NET environment. It supports both Web and Windows clients and allows exporting to PDF, Excel, RTF, HTML text, and TIFF images. The documentation is thorough and the drag-and-drop interface is straightforward.
  • ComponentOne Studio for .NET: It includes two tools: the report component, which generates Access-style database reports, and its companion Report Designer for report layout. It also includes tools for migrating Crystal Reports to their environment.
  • OOReport.NET: This product provides reports for Web-based clients. It also includes controls for assembling repots.
  • Visual Reports: This may be used with pre-.NET Visual Studio projects. It also includes an interactive report designer for proper layout. Report properties and such are accessed via COM interface.
  • Windward Reports: This product facilitates report design and creation via Microsoft Word. Open source reporting options

In the past, the term open source would never be uttered when discussing Microsoft-based development, but the .NET Framework’s acceptance and use of (some) standards has fueled several great open source solutions for .NET. And, reporting has a number of options.

Charting capabilities are provided by NPlot. One of the great features of .NET is the lack of adherence to one particular language, so you can use other products that are not .NET-based. While this may be beyond many .NET developers, open source solutions like the Java-based JasperReports can provide clean and simple reports.

Don’t overlook SQL Server
I would be remiss not to mention SQL Server’s Reporting Services. Microsoft describes it as “a comprehensive, server-based reporting solution designed to help you author, manage, and deliver both paper-based and interactive Web-based reports.” It is an excellent solution where SQL Server is readily available. It was first introduced as an add-on for SQL Server 2000, but it is also included with SQL Server 2005. It includes a report builder for simplifying report creation. SQL Server 2005 Reporting Services does not require Visual Studio .NET like its predecessor, but it may be utilised.

Make the data presentable
Where there is data there is a need to make sense of it, and reporting is one tool to aid users in this chore. Luckily, the .NET Framework includes various options ranging from the inherent Crystal Reports to open source alternatives. Your choices may depend on cost, but each product offers plenty of features to enhance your application.

.NET and serviced components

Posted on May 14th, 2008 in .Net by Ashish  Tagged

The .NET Framework provides enterprise services for building highly scalable solutions, but the implementation can be tricky. Learn when and where these services should be used.

One of the biggest mistakes architects can make when designing Enterprise Services is to assume that its sole purpose is to provide wrappers for existing unmanaged COM+ and MTS functionality. It’s a common assumption, given that the current Enterprise Services implementation provides little more than a managed interface to unmanaged COM+.

However, Microsoft views Enterprise Services quite differently. In its eyes, Enterprise Services is the replacement for COM+ and MTS. Going forward, Microsoft has two primary goals for new versions of the .NET Framework, starting with release 1.1 that’s due with Windows .NET Server 2003. First, all existing COM+ functionality will move to managed code. Second, all new distributed systems management functionality will be implemented in Enterprise Services in .NET. In fact, COM+ version 1.5 (released with Windows XP) will likely be the last version of COM+ available as an unmanaged release.

What is Enterprise Services?
Given Microsoft’s emphasis on Enterprise Services as its distributed systems development platform, you need to understand exactly what services Microsoft is talking about. Enterprise Services supports resource management in a distributed environment. This functionality includes support for distributed transactions, role-based security and packaging of objects, object pooling, just-in-time-activation (JITA), queued components, and loosely coupled events. When used together, these functions give architects the tools to implement a complete server application process model.

One of the most confusing aspects of Enterprise Services is when to use them. If your existing systems use COM+ extensively, you’ll naturally want to use Enterprise Services when porting your applications to .NET. But if you don’t use COM+ today, how do you get started and what’s the benefit?

Implementing transaction support
To understand how you can get started with Enterprise Services, let’s look at how you implement transaction support in three different scenarios: traditional distributed applications, Web services, and ASP.NET applications. It’s important to differentiate between how developers handle transactions in the COM+ world vs. .NET. In COM+, developers manually start a transaction and then check conditions to determine whether the transaction should be committed or aborted. But .NET lets you handle transaction commits and aborts automatically by using declarations exposed through attributes. In other words, you can think of distributed transactions as automatic or declarative transactions in .NET. (Developers still have the option of coding commits and aborts manually if they need that granular level of control.)

Traditional distributed applications
For a traditional distributed application, the developer needs to create a server object and then code the client to call the server object. Here’s a simple implementation of a server object implemented in C#:

using System;
using System.EnterpriseServices;
[assembly : ApplicationName("TxDemo")]

[Transaction]
public class Account : ServicedComponent {
[AutoComplete]
public void Credit() {
// do some work
} }

We should note three important items from this sample. First, the statement, using System.EnterpriseServices; gives you access to attributes in the Enterprise Services namespace. Second, the Account class inherits from the existing ServicedComponent class, where it gets its ability to be managed by EnterpriseServices. Finally, the Transaction and AutoComplete attributes make objects instantiated from this class transactional. The AutoComplete attribute tells EnterpriseServices to commit the work done in the Credit function unless an error occurs, in which case it should abort. You still can catch exceptions and swallow them (i.e., not Throw them up the call stack) with AutoComplete committing the transaction.

Here’s the code required to use the Credit object from a client application:

public Class AccountClient {
private void Transactions_Click() {
Account account = New Account();
order.Credit()
} }

Notice that the client has no idea that the server object uses transaction management.

Web Services
If your users need to consume resources managed by Enterprise Services but access them through a Web Services interface, you can expose those resources using parameters on the WebMethod attribute declaration. For example, the code below allows the WebMethod DeleteAuthor to create a new transaction before attempting to delete the author passed in by the user of the Web service:

[WebMethod(TransactionOption=
TransactionOption.RequiresNew)]
public int DeleteAuthor(string lastName) {
//…
}

Any other business objects called by this WebMethod automatically inherit its transaction context as long as they are marked to either Support or Require a transaction.

ASP.NET applications
Using transactions from ASP Pages is simple, as well. You add a page-level directive like this:


The Required setting allows this page to initiate a new transaction if it’s not already participating in an existing one. Any components called by this page will participate in the same transaction context.

What’s the benefit of Enterprise Services?
Before we look at the benefit of Enterprise Services, let’s first consider the widely discussed downside: performance. It’s true that calling serviced components is slower than calling other objects. This is because creating context and crossing context boundaries imposes overhead on your applications. But calling serviced components hosted in library applications (these run in-process with the application) is nearly as fast as calling nonserviced components. Server applications have a higher call time due to crossing process or machine boundaries. You determine whether components run as library or server applications when you install them in COM+.

But here’s the real issue: In most real-world applications, the performance cost of the infrastructure required to support Enterprise Services is minimal compared to the cost of the actual work that the component does. Moreover, if you didn’t use the features provided by serviced components, your code will likely have to do additional work to get the same functionality.

So when should you use serviced components? In general, if your application architecture can benefit from the services (like guaranteed transactions) provided by Enterprise Services, serviced components are worth the performance cost. You should also consider the ease of development and future expansion benefits of developing with serviced components. Development is simpler with serviced components. If you use a SqlTransaction object or OleDbTransaction object to manage transactions, you’ll have to manage the transaction yourself. With Enterprise Services, you simply add a Transaction attribute to your object(s). Enterprise Services ensures that transactions managed between multiple objects happen logically and consistently. For example, you won’t have to add any special logic to determine whether an object is the root of a transaction.

Future expansion is easier to accomplish if you code systems using serviced components from the start. Suppose you create an order management system that includes inventory tables managed as part of the overall order transaction. What if, in the future, the inventory tables move to a separate database? What if the inventory object is moved to a remote server? What if one of the objects wants to dispatch to a transactional message queue? If you built the system with manual transaction management, you’ll have to rewrite it in order to make it work in a distributed environment. Had you built the system using Enterprise Services, you could make these deployment decisions without requiring changes to the underlying application.

It will take time to learn how to implement serviced components correctly. And you may not need to use them for many of your smaller applications. But employing their functionality correctly for distributed applications will pay off in the long term because they allow you to make deployment decisions without regard for design decisions you made during development.

Schmap launches city guide web app for iPhone and iPod Touch

Posted on May 14th, 2008 in iPhone by Ashish  Tagged

Schmap, publisher of over 200 free online travel guides, has opened access to their guides for iPhone and iPod Touch users by way of a remarkably nifty web application. The guides cover cities throughout the US, Europe, Australia, Canada, and New Zealand, and provide information on everything from the city’s historical background to the best places to get your drink on.

schmap.pngAs portrayed in the image, the web app utilizes the iPhone’s gyro sensors and a Safari specific JavaScript function to determine how the device is currently oriented, and swaps between two display modes accordingly. If the device is oriented vertically, points of interest are displayed as a simple list; if horizontal, the points are overlaid on a map of the area. This allows the user to jump back and forth between modes without having to dig through menus, and is an ingenious way to make the most of the available screen real estate.

In addition to the city guides available for many major cities, Schmap is working on implementing a local search feature to provide similar functionality for cities they haven’t charted out yet. While local search results obviously won’t be as in-depth as the custom written city guide entries, it provides enough to get by: the business name, street address, and phone number. It did a good job of finding coffee shops in my area, even pointing out a few I’d somehow managed to ignore. I was unable to get the local search to recognize any zip codes, so you may need to type out the city’s name for the time being.

My only dislike with the service thus far is the tiny size of some of the buttons. I definitely don’t have sausage fingers, yet I constantly found myself tapping just outside of the detection areas. This was especially true of the arrows at the top and bottom of the interface.

Overall, Schmap for iPhone/iPod Touch is an incredibly handy application, especially while traveling or getting to know a new area. I’d expect to pay a few bucks a month for the service; that it’s free is just the mega delicious icing on the cake.

Improve data access in ASP.NET applications

Posted on May 12th, 2008 in .Net by Ashish  Tagged
Perhaps the two best examples of this axiom are the data-bound control from Visual Basic 3.0 and the Visual Interdev Design Time Control (DTC). The VB3 data-bound control made great demos, but its performance effects on the underlying database had even Microsoft’s own consulting services group recommending against its use in a production application.

Interdev DTCs are legendary for the number of developers who were suckered into using them for a simple application, only to find that they had to rewrite the functionality from scratch when they wanted to extend them or modify their output because the DTC was neither modifiable nor extensible. Consequently, when I first saw the .NET DataSet object, I was cautiously optimistic. Unfortunately, many developers chose not to be cautious at all.What’s wrong with the DataSet?
I’m not saying that there’s anything inherently wrong with the DataSet object. But it’s like any other tool—you need to understand how to use it appropriately. Although it’s a useful tool for Windows Forms applications, it’s much less useful for Web application development.

Let’s look at a simple example. Suppose you use a DataSet to return a set of 1,000 products to display in a DataGrid on a form. Since you might want to sort or filter the data later, you choose to save the DataSet in a session variable. Not knowing any better, you also leave the default page ViewState turned on. When a user navigates to this page, there are three copies of the data somewhere in memory. It’s on the server saved in a session-level variable. It’s in the ViewState stored as the contents of the DataGrid. And it’s in the rendered HTML stream in the form of HTML table directives that render the table. Now multiply the server memory by the number of users to assess impact on server memory, and multiply the two copies of the data by the number of users to assess the impact on bandwidth utilisation. You can quickly overload a server and its available network bandwidth on a high-traffic site.

The answer: Use the DataReader
Though not as sexy, the DataReader is much more functional for a Web application. Because the DataSet object’s cursor is designed to iterate in a forward-only, read-only fashion over the results of a query, it’s very fast. Moreover, the DataReader only holds the current record in memory at any one time—never the entire results set. The DataSet object can be bound to ASP.NET Server Controls (like the DataGrid). More importantly, server resources and connection resources are released as soon as you’re finished traversing them. Build your data-bound pages using DataReaders to retrieve data from an underlying database whenever it’s important for the data to be as fresh as possible.

When should I use the DataSet?
The only time I recommend using the DataSet in a Web application is when the underlying data changes on an occasional basis. For example, if you have a series of drop-down boxes or checklist items that come from a database but rarely change, it may make sense to load them in a DataSet in the Application_OnStart event and put them into the cache so that any page that needs to get the values will have them immediately available. This not only makes data retrieval faster for each page but also minimises the number of hits to the underlying database. You can get an additional speed boost by caching the Web pages, which rely on the cached DataSet for their values.

By setting a dependency between the cached Web pages and the cached DataSet, the Web pages will be regenerated whenever the DataSet changes. To make sure the DataSet is always current, you should create Update, Insert, and Delete triggers on the tables in the DataSet that modify a control file on the site. Then set a dependency between the cached DataSet and the control file. Whenever the control file changes, the DataSet in the cache will be invalidated. Add code to the Session_OnStart event to check for the cached DataSet, regenerate it if necessary, and place it back in the cache. Then whenever the underlying tables change, the cached DataSet will be regenerated.

Using the right tool for the right job is the best way to create optimised Web applications. Now you have some general guidelines for the right time to use the DataReader and the DataSet in your ASP.NET applications.

Next Page »