Wednesday, May 13, 2009

This blog has moved

As of today, this blog (loooong not updated as anyone reading it might have noticed) has moved to a new location at http://twistedcode.net/blog/

Tuesday, December 11, 2007

Runtime mapping of ASP.NET configuration settings - a new Mono feature

Recently, I've added a new feature to the Mono ASP.NET stack which allows one to modify the configuration settings on the application runtime, based on the operating system the ASP.NET application is executing on. This feature is Mono specific and is currently avaliable only from the svn trunk.

Why is it useful?
When developing ASP.NET applications which may be ran by the end user on either MS.NET/ISS or Mono/XSP/mod_mono, one may face a limitation of the .NET configuration system - the lack of conditional configuration constructs. Being unable to use different configuration settings for different operating systems/platforms, means that most of the time it is necessary to provide separate set of config files for every operating environment that differs to the other ones we support.

One example when such need arises is the usage of the WebParts feature of ASP.NET 2.0. As you may know, Mono currently does not support that feature and so applications which can optionally use it (like, e.g. MojoPortal) need to ship with a special configuration for Mono which excludes the WebPart configuration settings. Using settings mapping, it is possible to ignore the configuration sections related (and unsupported) by Mono.

Another, perhaps more common, scenario are file paths used in the Web.config file. Windows and Unix use different directory separator characters, Windows supports drive letters while Unix does not use them, a different character is (by convention) used to separate PATH-style variables under Windows (:) and Unix (;). While all those differencies can be dealt with easily in the application source code, it is not so for configuration files. A custom settings mapper can take care of the adjustments for you, seamlessly modifying "canonical" file paths used in the config file to the operating system the application runs on.

There's a pretty extensive document on how to use the feature in your application at http://mono-project.com/ASP.NET_Settings_Mapping

Tuesday, September 11, 2007

AJAX Control Toolkit: broken samples work now

Since the last update I have fixed all the remaining bugs and all the samples work now just the way they do on MS.NET. To run all the Toolkit samples, you will need mono from svn trunk, at revision 85628 or newer. As a reminder, the samples that didn't previously work were:
  • CascadingDropDown. The reason it didn't work was that Mono's WebServiceParser incorrectly treated the paths passed to it.
  • Filtered TextBox. The reason this one didn't work was a problem in the way TemplateControlCompiler treated arguments of type Type in the GenerateObjectInstance method: it would generate code to instantiate an internal type System.MonoType instead of the (correct) typeof expression.
  • HoverMenu. Fix for this one was a change in the logic which dealt with controls inside templates (see this post)
  • ListSearch. This one required implementation of the System.Web.Extensions.Design assembly as well as a few missing pieces of the System.Design one. I've added stubs for all of the missing pieces to mono svn trunk.
  • NumericUpDown. This one was made to work by the same WebServiceParser fix mentioned above.
  • ReorderList. Frankly, forgot what fixed this one :)
  • AutoComplete. This sample deserves a special mention. It still doesn't work for me, but Daniel Nauck reported it works for him with FireFox 2, Opera and IE7 on both Windows and Linux, with Mono from svn trunk. So I'll assume it works too and that there's some client issue on my side.
Shown below is a screencast demoing all the above samples (except for the AutoComplete one, of course). You will also note a JavaScript error at the end of the screencast - it happens every now and then, but it is probably a glitch in FireFox (at least in my copy) and it doesn't affect the demo:

Monday, September 10, 2007

Linux+Gnome on TV?

Whenever I watch a movie or some TV series and they show a glimpse of a computer screen, I like to freeze the picture and take a look at what it might be (and how credible what they show is, sometimes :D). Recently, I've started watching the Numb3rs show and in the 2nd episode of the first season (Uncertainty Principle) one of the main characters, a genius mathematician, explains a certain search pattern to his colleague from the University using the well-known Mines game. When I saw the sequence, what was on the computer screen seemed familiar, so I froze the frame and I think what you see on screen is GNOME (my guess is that the OS is some version of Ubuntu), here's the screenshot:


Even though it is definitely not the version of Mines shipped with Gnome, I do think the notebook is running Linux. Cool :)

Update:
Most people seem to think it's MacOS/X, but I'm still not convinced (being stubborn as I am) :)

Update2:
It seems it really is MacOS/X... oh well :) Will keep trying!

Friday, September 7, 2007

AJAX Control Toolkit Update: what doesn't work

Since yesterday, the following samples started to work:

  • HoverMenu. The result this one wasn't working was twofold. First, there was a bug in our implementation of TemplateControlCompiler which incorrectly exposed all the controls contained in a template marked with the TemplateInstance.Single attribute if any of template children was marked that way. The correct action is to expose only those controls which are either direct children of such template or whose parent containers are templates themselves (unless the parents bear the attribute, of course). Fixed in svn commit to revision 85473. The second problem was non-portable coding in the Toolkit itself. To make the sample work you need to modify the App_Code/TodoXmlDataObject.cs:

    Line 92 should read:
    get { return Path.Combine(RootPath, String.Format ("App_Code{0}TodoItems.xsd.orig", Path.DirectorySeparatorChar)); }

    Line 204 should read:
    get { return Path.Combine(RootPath, String.Format ("App_Data{0}TodoItems.xml", Path.DirectorySeparatorChar)); }
    On line 92 the TodoItems.xsd.orig should be the name of the file you renamed TodoItems.xsd into.
  • FilteredTextBox. This one will work if you modify code starting at line 47 in the FilteredTextBox/FilteredTextBox.aspx file and remove either the Custom or the Numbers string together with the comma from the value of the FilterType attribute. It is not, of course a fix, but a workaround to show that the sample does (generally) work. Fix will come soon.
  • AutoComplete. It has every right not to work, because it doesn't work when the toolkit is running under MS.NET either. The webservice works correctly (which you can confirm by visiting http://localhost:8080/AutoComplete/AutoComplete.asmx directly).
The rest of the fixes must wait till after the weekend.

AJAX Control Toolkit on Mono

As some of you probably already know, thanks to great work by Mainsoft we can run Microsoft AJAX applications with Mono from svn trunk now. As long as the System.Web.Extensions namespace is almost complete, there were missing (or buggy) bits and pieces inside the System.Web assembly provided by Mono.
In the past two days I've been implementing the missing and fixing the buggy code to get the AJAX Control Toolkit running without modifications under Mono. Today it works nearly in 100%!
There are few things that don't work, but I'll leave it for later, since first I want to present a small screencast showing that the toolkit does run under Mono :)

The screenshot below shows that the toolkit is indeed ran under Mono's XSP (weak proof, but what's a blogpost without graphics, eh? :D):


The screencast below shows some of the demos in action (some demos don't work, see further down the page).



What doesn't work (and why):
  • AutoComplete. There's a problem with the remote service, haven't checked what is the problem yet.
  • Cascading DropDown. Another problem with the remote service, also not checked for details yet.
  • Filtered TextBox. The sample throws a weird parser exception, will take care of it soon.
  • HoverMenu. Throws errors about duplicate controls.
  • ListSearch. Throws a NullReference exception.
  • NumericUpDown. This one works in all cases except the one which uses a web service.
  • ReorderList. Depends on the existence of the TodoItems.xsd file which I had to remove (see below).
All the other samples work without problems. I'm going to take a look at the failing ones tomorrow and, hopefully, make them work.

There's one other issue you need to keep in mind if you want to test the toolkit on your Linux machine: the Mono's XSD generates invalid code from the TodoItems.xsd file that comes with the toolkit. To make the sample website work, you must generate the .cs file from the above .xsd with the .NET version of the tool:

xsd TodoItems.xsd /c

then put the result file in the SampleWebSite/App_Code directory and rename the TodoItems.xsd file to, for instance, TodoItems.xsd.orig

At this point you should be able to play with the demos.

Friday, August 17, 2007

New mod_mono/xsp in 1.2.5

Unlike stated in the previous post, the changes described there will make it into Mono 1.2.5 as they turned out to fix more bugs they were intended to (wish me more fixes like that!). mod_mono and xsp were copied from svn trunk and are part of the 1.2.5 Preview 4 release.

Thursday, August 16, 2007

New mod_mono and xsp developments

It's been a while since I blogged. The reason for this is simple - all the work I've done on ASP.NET in the past weeks was bugfixing and most of it wasn't blog-worthy. But recently a couple of important bugs were closed which resulted in several nice feature additions to mod_mono and XSP.

One of the important bug fixes was a modification to Mono assembly shadow copying code. We had a race condition that showed up when one thread was shutting down an application domain and another would be starting a new one. The latter would overwrite the shadowed assemblies which would cause the former to throw an exception about invalid opcodes present in the assembly. The fix was to introduce an internal AppDomain serial number which would be unique for each new domain. The serial number is then used in generating the names of shadow copy directories. That way, even for the same application, new AppDomain created by the same application, with the same root directory, setup etc. (e.g. an ASP.NET hosting domain) saves its shadow assemblies in another target directory.

Another bug was reported to happen on ASP.NET sites powered by Apache/mod_mono. The problem was another race condition which occurred in the request startup/teardown sequence inside the Mono.WebServer assembly (shared by both xsp and mod_mono backends). The race was in the assignment and release of request ids which sometimes ended up reused even though the original request with that id wasn't done yet. The solution was to introduce a few lock statements in the code as well as an delegate way of releasing the request id in the code using Mono.WebServer.

The third bug was reported by a Mono user running a very busy website which triggerred the behavior described in the paragraph above, but also exhibited problems with memory consumption for the long-running mod_mono backends. We haven't solved the memory consumption problem yet (it's probably related to the GC), but as part of workaround for the issue we implemented set of options and features for mod_mono which make sites with such problems more robust. I will enumerate and shortly describe the features below.

Startup optimization


mod_mono used to start the backends in the child init hook, which is called after apache forks a new child and has already switched from the root user to the target user/group named by the User/Group directives, respectively. The problem with this solution was that if we had 5 child processes, then 5 copies of mod_mono would launch that many backends simultaneously. Eventually all but one backends would die, but the initial impact on performance would be quite severe. New code moved the backend launch to a server init hook function which runs when apache is still executing as root (i.e. in the main apache process). The code looks up the User/Group directives and switches temporarily to the defined uid/gid in order to launch the backend. That way the vhost backends are launched only once.
To lookup User/Group properly, mod_mono must be loaded after the two directives in the apache config.

The dashboard

The dashboard is a shared memory area which stores information about all instances of mod_mono backends. Each virtual host has its own dashboard, so the performance impact of one vhost's dashboard locking is none for the other vhosts present in the server. The dashboard is used by mod_mono to synchronize (re)starts of the backends so that only one copy of mod_mono stops or starts the backend (Apache can run several sub-processes each of which loads its own copy of mod_mono). The dashboard is also used to store accounting information used by the auto-restart feature described below.
In order to synchronize access to the dashboard, mod_mono must be able to acquire a lock before accessing the data. By default it uses whatever the underlying Apache runtime chooses, but there are cases when it might fail on some systems. Should such event occur, you can use the MOD_MONO_LOCKING_MECHANISM environment variable to specify one of the available mechanisms. For the list of currently recognized ones, please consult the mod_mono manual page (man mod_mono)

Auto-restart

If your mod_mono site uses patterns which make Mono allocate large amounts of RAM, and the site is busy enough for the Mono garbage collector not being able to free enough memory on time, you can configure mod_mono to restart the backend(s) automatically based on two criterions: backend uptime or the number of requests served. The feature is configured on a per virtual host basis. Configuration is done by means of three Apache configuration directives:

  • MonoAutoRestartMode. This directive selects the restart mode and can take one of three values: None (default, no automatic restarts are done), Requests (restart after the given number of requests) and Time (restart after the backend has been up for the specified period of time)

  • MonoAutoRestartRequests. Specifies the number of requests after which the backend should be restarted. Defaults to 10000 requests.

  • MonoAutoRestartTime. Specifies the minimum uptime after which the backend will be restarted. Takes values in the generic format DD[:HH[:MM[:SS]]]. Defaults to 12h (00:12:00:00)


If your site stores data in the ASP.NET session storage, you must make sure that you use out of process session storage, since the in-process data wil l be destroyed when the restart occurs.

Lamentably, the changes described above will not be part of the upcoming 1.2.5 release of Mono. You need to use the svn trunk versions of mod_mono and xsp in order to take advantage of them.

Wednesday, June 27, 2007

Hack week @Novell

This week all of us working at Novell are free to work on any pet project we want. Together with several other folks, I am working on implementing desklets using the recently developed Moonlight - a port of Silverlight. So far it's been an ejoyable experience and we already have several desklets implemented :)

Friday, May 18, 2007

Mono 1.2.4 - the best ASP.NET 2.0 release so far

With Mono 1.2.4 released, the ASP.NET 2.0 support is nearly complete (with the exception of WebParts and the management APIs) and what we're looking into now is making sure all the little incompatibilities, missing APIs etc. are added and tested.

As part of this effort, I've recently tested all the non-data samples in the .Net QuickStarts set (available either online at http://quickstarts.asp.net/ or with the .NET SDK) and fixed quite a few little bugs or incompatibilities. Unfortunately the changes aren't part of the Mono 1.2.4 release but, as before, I recommend that you use the svn trunk version of Mono (or a daily snapshot) for your 2.0 development and testing. The data controls will be tested as soon as we update our SqlClient implementation with some features that'll help in the testing.
A note about testing the QuickStarts with xsp2 on Mono. The online QuickStarts site uses probably virtual directories in IIS to make sure that the samples which are fully-contained applications get their configuration and paths right. If you run xsp2 in the aspnet/ QuickStarts directory and notice that some don't work, just go to their source folder and run xsp2 from there.
Currently, again as part of the .NET conformance testing, I'm porting several ASP.NET 2.0 applications (starter kits and others) to use PostgreSQL instead of MS SQL - this will allow them to be fully hosted on Unix. I will blog about the ports as they happen.