TechDays Day I – Architecture: The good, the bad and the ugly

Posted by admin on March 10th, 2009

I was a little bit too late for this session, but I did manage to grab the most important things. The presentation began with a lot of antipatterns and then followed with good patterns. Most of the things were rather obvious. A really funny thing was an example of the MSSQL database behind one of the first versions of SharePoint. There were like hundreds of tables with absolutely no relationships between them. Instead they created some 500 stored procedures that needed to take care of the integrity of the database… Guess there are also ‘disaster developers’ working for Microsoft.

Anti patterns

McKinsey Syndrome

  • We know it all, we don’t nee to listen…
  • They don’t know what they really want…
  • Just a cookie-cutting re-delivery…

Opposite Anti-pattern: Obedient Butler

Napkin Doodle

  • It was so straight-forward requirement…
  • We agreed on all req’s during lunch…
  • Light projects don’t need heavy process…

Opposite Anti-pattern: Documentation Overkill

Measure abuse

  • Each req must have success metrics…
  • If you can’t measure it, it is not there…
  • We need binary criteria of achievement…

Opposite Anti-pattern: Softie-softie

Start small, grow fast

  • Just for couple of users first…
  • Prototype, patch-up, deploy…
  • We’ll add scalability later…

Opposite Anti-pattern: Let’s Go Global NOW!

Best-of-breed

  • All the best tools (best database, best webserver, …) but no communications beween them…

Opposite Anti-pattern: Vendor Lock-in

YAGNI (You Ain’t Gonna Need It)

  • I’m sure nobody needs this requirement…
  • I bet this one is totally irelevant…
  • Too low on priority list…

Opposite Anti-pattern: Analysis Paralysis

Reinventing the wheel

  • We can do it better. Much better…
  • It would be boring to re-use the old stuff!
  • I trust my code and my code only.

Opposite Anti-pattern: Golden Hammer (One thing that solves everything… everything must be a nail…)

Sales-driven Design

  • We sold it, you just implement it…
  • Trust me, I’m technical too…
  • Does it work? Shut-up then…

Opposite Anti-pattern: Technological Purity

YAFL (Yet Another Fine Layer)

  • Architecture is simplicity, not intellectual violence

Good patterns

  • Modularity (degrees of freedom)
  • Open-ended systems (specific vs generic). Move from Application-Specific (solution) to General-Purpose (Infrastructure)
  • Build to grow (Wu Wei)
  • Identifier, Format and Protocol (back to the roots)
  • Middle-out Architecture (Wide range of implementations, Minimal Spec and Wide range of uses)
  • Poor-man Application Model
  • Web-Oriented Architecture
  • Lines matter more than boxes (Protocals are inherently stable, applications are not)
  • Dependency Inversion (Fold knowledge into data so program logic can be stupid and robust, What needs to be easy to understand and change goes into data, What will be stable goes into code). Data should depend on code, Code should not depend on data.
  • New-age development with MetaData and Model-Driven Design
  • Virtual worlds, virtual rules
<

Allow Port on Windows Server to enable WebORB Messaging

Posted by admin on March 6th, 2009

Had a problem starting the WebORB RTMPServer (in global.asax) today which was solved after adding the port as an exception in the Windows FireWall.

Log from WebORB:

[Thread-11] WEBORB INFO:6/03/2009 11:26:37:shutting down WebORB Message Server
[Thread-11] WEBORB EXCEPTION:6/03/2009 11:26:37:System.Net.Sockets.SocketException: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
at System.Net.Sockets.Socket.Shutdown(SocketShutdown how)
at Weborb.Messaging.RTMPServer.shutdown()
[Thread-15] WEBORB EXCEPTION:6/03/2009 11:26:37:System.Net.Sockets.SocketException: A blocking operation was interrupted by a call to WSACancelBlockingCall
at System.Net.Sockets.Socket.Accept()
at Weborb.Messaging.RTMPServer.run()
[Thread-11] WEBORB EXCEPTION:6/03/2009 11:26:37:System.ObjectDisposedException: Cannot access a disposed object.
Object name: ‘System.Net.Sockets.Socket’.
at System.Net.Sockets.Socket.Disconnect(Boolean reuseSocket)
at Weborb.Messaging.RTMPServer.shutdown()

Adding an exception in windows firewall is done in the “Windows FireWall Settings”. Choose tab Exceptions and Add port… There you enter the port that you use for the RTMPServer (default 2037), give a name and choose TCP.

thx, Lieven Cardoen

<

Web Application Testing Using WatiN

Posted by admin on February 28th, 2009

Yestarday I was looking for a way to test a web application having hundred of links that have a certain structure. After a question on StackOverflow I got the same answer a colleague of mine already had given, WatiN. WatiN enables you to open a certain web page in Internet Explorer or Firefox and interacting with the web page though code (like clicking, entering text in controls, ...).

In my Unit Test Project (VS2008) I used Internet Explorer as this development is a little bit ahead of the Firefox development. To create cross browser WatiN tests, check this link. I'll try to port my project to cross browser testing later.

There's also a WatiN Test Recorder. The next Release of this looks very promising!

Here's an example how you get started by opening an Internet Explorer Window and go to a certain web page.

C#:
  1. IE ie = new IE("www.google.be");

Check if the page contains a certain text:

C#:
  1. Assert.IsTrue(ie.ContainsText("..."));

To find a link and click on it:

C#:
  1. ie.Link(Find.ByText("...")).Click();

Search for a certain TableCell:

C#:
  1. ie.TableCell(Find.ByText("..."));

Click on a TableCell:

C#:
  1. tableCell.Click();

Get all the TableCells of the current page:

C#:
  1. ie.TableCells;

Search for a certain Frame:

C#:
  1. Frame frame = ie.Frame(Find.BySrc(new Regex(".*main.aspx")));

Does a certain Element exists:

C#:
  1. Assert.IsTrue(frame.Element("app").Exists);

<

Peformance issues IIS7, WebORB, Network, …

Posted by admin on February 21st, 2009

Two weeks ago I had a lot of problems in a project of mine. Often some clients couldn't connect to weborb.aspx (actually 0.01% of the times). After a lot of searching we weren't really able to find the problem. It seemed to me that maybe it was a network issue. The customer had just changed a lot of servers and improved their network. What previously worked didn't seem to work anymore now.

We changed some things after which everything started to work smoothly again:

- When an error is thrown from the server or there's a network problem we invoke the server call again with Credentials. We use authentication, so if at a certain moment in time IIS decides to recycle, the next calls to the server will fail. So we implemented a fallback system. If a fault occurs we authenticate again and try the call a second time. If the second time would also fail, then we give the user an Alert with some information what to do.

- When profiling SQLServer2008 we saw that there were millions of logs being written to the database by WebORB. We had configured WebORB logging with Log4Net and set the Filter in Log4Net on INFO. Basically everything that was logged was written to the database. This meant a lot of overhead. After having put the Filter on Warning connections to database reduced by a factor 100.

Configuring WebORB Logging with Log4Net (in global.asax):

C#:
  1. void Application_Start(object sender, EventArgs e)
  2.     {
  3.         log4net.Config.XmlConfigurator.Configure();
  4.         log4net.ILog log = log4net.LogManager.GetLogger("Global.asax");
  5.         log.Info("Application_Start(" + sender.ToString() + ", " + e.ToString() + ")");
  6.  
  7.         //Configuring WebORB Logging with Log4Net
  8.     try
  9.     {
  10.         Weborb.Util.Logging.Log.addLogger("log4NetLogger", new Edu3.Util.Logger())
  11.                 Weborb.Util.Logging.Log.removeLogger("default");
  12.     }
  13.     catch (Exception exception)
  14.     {
  15.         log.Error("Application_Start", exception);
  16.     }
  17.     }

- We profiled IIS7 with some tools that were proposed on StackOverflow. These tools were very interesting, but still I thought to get much more information. Strange that there's not a professional profiling tool for IIS7. We used Administration Pack for IIS 7.0, the stackoverflow question is at link. The strange thing was that in 0.01% of the requests a 404 was returned. Even after having enabled Failed Request Tracing in IIS7, I couldn't find the reason for the 404.

- Recycling happens automatically @ 23 hours. (this was allready done earlier when I had problems in November).

After these tweaks everything is working fine again. Those 404's remain a mystery...

Ciao, Lieven Cardoen

<

Creating a Guid in C#

Posted by admin on January 15th, 2009

What is a GUID

For those of you who don't know, a GUID (pronounced goo'id - Globally unique identifier) is a 128-bit integer that can be used to uniquely identify something. You may store users or products in your database and you want somehow uniquely identify each row in the database. A common approach is to create a autoincrementing integer, another way would be to create a GUID for your products.

How to create a GUID in C#

The GUID method can be found in the System namespace. The GUID method System.Guid.NewGuid() initializes a new instance of the GUID class.

There are also a few overloads available for those of you who want the GUID formatted in a particular fashion.

Example:

C#:
  1. System.Guid.NewGuid().ToString()

There are some overloaded methods. See http://msdn.microsoft.com/en-us/library/system.guid.aspx for more information.

<

AS3 – C# String Replace with Regular Expressions and Callback function

Posted by admin on January 15th, 2009

In AS3:

Actionscript:
  1. ...
  2. var regExpDigitString:String = "\\d+"
  3. modified = original.replace(new RegExp(regExpDigitString, "gi"), findSuffix);
  4. ...
  5.  
  6. private function findSuffix():String {       
  7.     var result:String = arguments[0];
  8.     var index:int = arguments[1];
  9.     var input:String = arguments[2];
  10.        
  11.     ...
  12.                
  13.     return result;
  14. }

In C#

C#:
  1. ...
  2. String regExpDigitString = "\\d+";        
  3. modified = Regex.Replace(original, regExpDigitString, new MatchEvaluator(findSuffix), RegexOptions.IgnoreCase);
  4. ...
  5.  
  6. private String findSuffix(Match m) {
  7.     String result = m.ToString();
  8.     int index = m.Index;
  9.     String input = original; //apparently you can't get the original string out of the Mach Object, so you'll need a reference to the original Object in your class.       
  10.            
  11.        ...   
  12.  
  13.     return result;
  14. }

<

Open Source SubVersion Plugin for Visual Studio

Posted by admin on January 14th, 2009

http://ankhsvn.open.collab.net/

Just began using this Plugin and it seems very nice!

<

Rounding Up 2008

Posted by admin on December 24th, 2008

I started this year by taking over the lead of a big project for the Belgian government. The project is an e-learning environment created mainly with Flex, WebORB, .NET, MSMQ and MSSQLServer 2005. Daily hundreds of candidates go to Brussels were they are being tested by our software. Typically some 300 candidates start off at the same time to take a test.

So what have I learned this year (some of the things ;-) ):

Database

  1. Indexes are very important because they can speed up things a lot. However they can also be misused!!! So read about them.
  2. Stored Procedures made it easy to quickly write logic (transaction scripts). However it's hard to maintain these Stored Procedures and Cache dependencies don't work with complex Stored Procedures.
  3. MetaData was a very usefull mechanism to add new logic in Flex without having to change table designs.
  4. We also used MetaData for tags which wasn't the best choice.

.NET

  1. I didn't have a lot of experience in the beginning of this year so things kind of moved in the direction of Transaction Scripts. They aren't a bad choice but as the project gets complexer, transaction scripts are difficult to maintain.
  2. SubSonic (o/r mapping tool) did it job very good but I'm not very pleased with the lack of documentation, tutorials and clear explanations. I will certainly look into nHibernate and Entity Framework and see how they work with some of the patterns described in 'Patterns of Enterprise Application Architecture' by Fowler. In the future the project will certainly need to be scalable so things will have to change.
  3. Visual Studio is a great IDE.

IIS and ASP.NET

  1. By default IIS recycles application pools every 29 hours (will come back to that later because this caused a lot of problems).
  2. HttpHandlers are great.
  3. Cache is a very important feature if you want to speed up your application.

Flex

  1. Very good choice for our client side development. Application development however is far more complex than writing web pages in .NET. If you need your code to be maintainable you need to know about design patterns, frameworks, refactoring, architecture, ... Those things are mainly things you learn after having used them a couple of years.
  2. We now work with modules but in the future we will have to check out those shared libraries as well. Our application is now 2mb big so some kind of intelligent caching will be needed.
  3. Prana is great to configure your application externally. Check it out!
  4. The Flexbuilder Eclipse Plugin is a waste of memory and I hope Adobe tries to improve this in the future. Building our project takes far too long.
  5. Resource bundles could be made easier.
  6. Designing a Flex application is a hard thing because you really need a designer who knows some basic things about Flex.
  7. Implementing Pessimistic Concurrency with Messaging was a very hard one this year!
  8. Looking forward to create a desktop application version of our project.

WebORB

  1. Great product. FluorineFX is the open source alternative, but WebORB has a lot more features. Without a support plan however some things are really hard to debug.
  2. Authentication and Authorization is worth to take a look at, but it's important to fully understand it.
  3. WebORB messaging integration with MSMQ is great to let other applications know what's happening.

Other tools that have been very usefull are CvsDude, Trac, Mylyn, SubVersion, Charles, SQL Compare, SQL Data Compare, ant, cruisecontrol, Linq, SilverLight (very promising), Spring,...

Ciao!

<

How to enable HttpContext in Unit Tests

Posted by admin on December 22nd, 2008

When you are using Cache in your Business Logic, then running tests will fail because there will be no HttpContext available. This is a workaround:

Add this to your App.Config:

XML:
  1. <appSettings>
  2.      <add key="AppPhysicalDir" value="..."/>
  3. </appSettings>

Then add these lines of code to your “public static void MyClassInitialize(TestContext testContext)”:

C#:
  1. using System.Configuration;
  2. using System.Web.Hosting;
  3. using System.Web;
  4.  
  5. ...
  6.  
  7.  
  8. string appVirtualDir = "/";
  9. string appPhysicalDir = ConfigurationManager.AppSettings["AppPhysicalDir"];
  10. string page = "/default.aspx";
  11. string query = string.Empty;
  12. TextWriter output = null;
  13. SimpleWorkerRequest workerRequest = new SimpleWorkerRequest(appVirtualDir, appPhysicalDir, page, query, output);
  14. HttpContext.Current = new HttpContext(workerRequest);

Are there other ways of doing this?

<

State Management ASP.NET 3.5

Posted by admin on November 27th, 2008

Just read a chapter in Beginning ASP.NET 3.5 in C# 2008. These are the things I need to remember for myself in a small summary. If you want more information, buy the book!

View State

Uses a hidden field that ASP.NET automatically inserts in the final, rendered HTML of a web page. Web Controls use this, but your web page code can add bits of data directly to the view state.
The ViewState property of the page is an instance of the StateBag collection class. The StateBag is a dictionary collection, which means every item is stored in a seperate "slot" using a unique string name.
Making your View State Secure can be done in two ways. You can make it tamperproof by instructing ASP.NET to use a hash code (which is generated with a cryptographic key). If you have a web farm you need to configure the different servers to use the same key! Besides this you can also enable view state encryption (imposes a performance penalty).
Retaining Member Variables: Basic principle is to save all member variables to view state when the Page.PreRender event occurs and retrieve them when the Page.Load event occurs. !You cannot store view state information in an event handler fot the Page.Unload event. Though your code will not cause an error, the information will not be stored in view state, because the final HTML page output is already rendered.

Cross-Page Posting

One page can send the user to another page, complete with all the information for that page. Uses a property named PostBackUrl, which is defined by the IButtonControl. This technique is a potential minefield and can lead to pages that are tightly coupled to others.

The Query String

Pass information using a query string in the URL.  Advantage is lightweight. Some limitations are:

  • Limited to simple strings
  • Information clearly visible to the user and http sniffers
  • The user can alter the query string
  • browsers impose limit on the length of the URL

Cookies

Cookies are small files that are created on the client's hard drive. They work transparently without the user being aware that information needs to be stored. You retrieve cookies from the Request object, and you set cookies using the Response object. Other ASP.NET features also use cookies (like session state and forms security).

Session State

Allows you to store any type of data in memory on the server. The information is protected, because it is never transmitted to the client, and it's uniquely bound to a specific session. Every client that accesses the application has a different session and a distinct collection of information.

Session Tracking is done using a unique 120-bit identifier. This ID is the only piece of session-related information that is transmitted between the web server and the client. The client can present the appropriate session ID with each request in two ways: using cookies or using modified URL's.

A careless use of session state is one of the most common reasons that a web appliation can't scale to serve a large number of clients. Sometimes a better approach is to use caching!

There are different modes of Session State namely InProc (default), Off, StateServer, SQLServer and Custom.

Application State

Allows you to store global objects that can be accessed by any client. Application state is rarely used because its two most common uses have been replaced by easier, more efficient methods:

  • web.config
  • ASP.NET cache
<

Copyright © 2007 Johlero – Cardoen Lieven. All rights reserved.