Wednesday, June 09, 2010

Poor man's CSS Framework



If you have simple site structure, for example classic: header, left panel, content panel and footer, then it may be an option to skip full scale css framework. JQuery introduced "position" utility. Here is how I stitched my content panel to the left panel:

$('#pages').position({
of: $('#main-menu'),
my: "left top",
at: "right top"
})


No stupid tricks with css margins!
Taking into account that css3 layout won't be ready any soon and taking into account not the best architecture of css overall, jQuery can become layout engine of the choice in the future.

JSON and WCF


Microsoft JSON implementation just pisses me off.

First, they serialize enums as numbers.

Second, this strange date type serialization. Ok, I can understand that jscript has no hint that given string is a date, but when client sends '2001-12-31' to the server, which does know the type, how stupid it is to demand: "DateTime content '2000-01-01' does not start with '\/Date(' and end with ')\/' as required for JSON"???

Thursday, April 29, 2010

Automatic build from tags (not trunk)


Requirements


My requirement for Continuous Integration is slightly different. Our project involves semi-manual Sql scripts preparation for a build, so I can not relaibly build every version from svn. Only the code in tags/Builds is good. But I am so lazy, I don't want even run my build script. I want to new build to be automatically detected and built. Just email me please when you are done :)

The first attempt to automate daily builds was to create my own "small" asp.net project to do it. But as soon s I realized that I need a winservice to perform long lasting tasks, such as source code checkout, I abandoned this idea. It is too much effort and I should be able to find something ready.


Almost continuous integration


So I decided to give a whirl to Cruise Control.NET. I heard of it before, but it does what I do not need: it tracks *any* change to the *trunk*, whereas I need to track new folder in "tags/Builds" and trigger svn checkout of this particular subfolder, not just "svn update" of "trunk" folder.

As I suspected, CCNet Svn plugin can crate new labels in tags but it can not track changes in tags folder.
I tried Hudson build manager too. More plugins, way much better UI but the same problem: it tracks trunk only.

Such a minor problems do not stop me and I dived inside Cruise Control.NET.
At first I tried to do what I want by introducing some faked task, which would check last build tag and compare it to the last one available in svn. But CCNet asks "source" plugin for changes and if it detects nothing, no "task" will be invoked.
So I started digging CCNet's "Svn" class. Well, it can be done, but a lot of work, and to make it flexible and not reflecting my particular setup even more work.

All the sudden I took another look at seemingly unrelated plugin "external source". It says that you use it to integrate with other source control systems, but you can do more with it. You can call your own script which will do custom svn search logic.

Bummer, "external source" command line is specified as "executable GETMODS "fromtimestamp" "totimestamp" args". So if I want to execute "ruby.exe /path/to/ruby/script.rb", I can't: script parameter is the last in the list of params. The same with "cmd.exe", I can't pass params in the order I want.

But this should be easy fixable: downloaded sources (make sure you get the same version of sources as you have installed as binary package), add one more parameter "argsLeading" and it works!

Configuration



<project name="Your Project">
<workingDirectory>C:\tmp\ccnet-working\YourProject</workingDirectory>
<artifactDirectory>C:\tmp\ccnet-working\YourProject.Artifacts</artifactDirectory>
<triggers>
<intervalTrigger name="interval" seconds="3600" initialSeconds="10"/>
</triggers>

<sourcecontrol type="external" autoGetSource="true">
<executable>ruby.exe</executable>
<argsLeading>C:\Projects\Your\Project\TagCheck.rb</argsLeading>
<args></args>
</sourcecontrol>

<tasks>
<!--<nullTask />-->
<msbuild projectFile="src/YourProject.sln">
<executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
<logger>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MSBuild.dll</logger>
</msbuild>
</tasks>
<publishers>
<email mailhost="mail" from="build-no-reply@enviance.com">
<users>
<user name="BuildGuru" group="buildmaster" address="you@your.company.com" />
<user name="JoeDeveloper" group="developers" address="you@your.company.com" />
</users>
<groups>
<group name="developers">
<notifications>
<notificationType>Failed</notificationType>
<notificationType>Fixed</notificationType>
</notifications>
</group>
<group name="buildmaster">
<notifications>
<notificationType>Always</notificationType>
</notifications>
</group>
</groups>
</email>
<xmllogger/>
</publishers>
</project>



Handling script

$svn_tags='https://svn.yourcompany.com/svn/your/project/tags/Builds'

def last_tag
`svn.exe ls #{$svn_tags}`.split().last().chomp('/')
end

def last_build
Dir.entries('.').select {|d| d =~ /^\d{8,}/}.sort().last() || '0'
end

def svn_info(tag)
info = {}
`svn.exe info #{$svn_tags}/#{tag}`.
split("\n").each {|line|
pair=line.split(/ *: */)
info[pair[0]]=pair[1]
}
info
end

#
# Get Modifications
#
if ARGV[0] == 'GETMODS'
if not last_tag > last_build
puts ''
exit 0
end

info = svn_info(last_tag)
date=DateTime.parse(info['Last Changed Date']).strftime()

# in fact, we should filter only modifications which are in between
# the ones in command line, but seems CCNet does check the result,
# so let's always return the latest entry
puts "

#{info['Revision']}
New build
#{last_tag}
#{date}
#{info['Last Changed Author']}

"
exit 0
#
# Get Source
#
elsif ARGV[0] == 'GETSOURCE'
workdir = ARGV[1]
timestamp = DateTime.parse(ARGV[2])
last = last_tag
info = svn_info(last)
date = date=DateTime.parse(info['Last Changed Date'])
if date > timestamp
STDERR.puts "Command line timestamp must be less then svn. Svn: '#{date}' command line: '#{timestamp}'"
exit 1
end
puts `svn.exe export #{$svn_tags}/#{last} #{workdir} --force`
exit 0
end


exit 1


Patch



Index: project/core/sourcecontrol/ExternalSourceControl.cs
===================================================================
--- project/core/sourcecontrol/ExternalSourceControl.cs (revision 7225)
+++ project/core/sourcecontrol/ExternalSourceControl.cs (working copy)
@@ -183,6 +183,14 @@
[ReflectorProperty("args", Required = false)]
public string ArgString = string.Empty;

+ ///
+ /// The same as "arg" but it will be the first parameter in command line.
+ /// Is useful if external program is a script engine and you need 1st parameter
+ /// to be a script name.
+ ///

+ [ReflectorProperty("argsLeading", Required = false)]
+ public string ArgLeadingString = string.Empty;
+
///
/// Should we automatically obtain updated source from the source control system or not?
///

@@ -237,7 +245,8 @@
///
public override Modification[] GetModifications(IIntegrationResult from, IIntegrationResult to)
{
- string args = string.Format(@"GETMODS ""{0}"" ""{1}"" {2}",
+ string args = string.Format(@"{0} GETMODS ""{1}"" ""{2}"" {3}",
+ ArgLeadingString,
FormatCommandDate(to.StartTime),
FormatCommandDate(from.StartTime),
ArgString);
@@ -265,7 +274,8 @@

if (AutoGetSource)
{
- string args = string.Format(@"GETSOURCE ""{0}"" ""{1}"" {2}",
+ string args = string.Format(@"{0} GETSOURCE ""{1}"" ""{2}"" {3}",
+ ArgLeadingString,
result.WorkingDirectory,
FormatCommandDate(result.StartTime),
ArgString);
@@ -286,7 +296,8 @@
{
if (LabelOnSuccess && result.Succeeded && (result.Label != string.Empty))
{
- string args = string.Format(@"SETLABEL ""{0}"" ""{1}"" {2}",
+ string args = string.Format(@"{0} SETLABEL ""{1}"" ""{2}"" {3}",
+ ArgLeadingString,
result.Label,
FormatCommandDate(result.StartTime),
ArgString);

Friday, December 11, 2009

WCF errors translation



If you get a message from server:

The exception message is 'The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml', 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.'. See server logs for more details


this may mean that your ajax client did not set up ContentType such as "application/json; charset=utf-8"

Thursday, October 22, 2009

Menus in Gtk# (and Monodevelop)



Unfortunately there is surprisingly little information about Gtk# and gtk itself in Internet. So when I started my first UI project in Monodevelop, I had to spend a lot of time looking for information and experimenting.

My environment: gtk# version: 2.12, Monodevelop: 2.0, OS: Ubuntu-9.04

When you create new Gtk project, everything is very intuitive.
First little surprise is that in Gtk you can not create any element on your window but instead you have to put there a placeholder, usually a Vbox, and only than you can use familiar controls like menu.

Menu editing is intuitive and cause no problems. But I wanted to generate one of the menus programmaticaly: list of last files open. Here is a surprise.
Monodevelop has its own UI builder and most of the controls have appropriate object instances auto-generated. For example:

// Container child MainWindow.Gtk.Container+ContainerChild
this.vbox1 = new Gtk.VBox();
this.vbox1.Name = "vbox1";
this.vbox1.Spacing = 6;


But menu is an exception. Menu items do not have appropriate variables generated. There are two ways you can get your menu item: you can digg through "Children" properties until you find the menu item you want. Not too elegant, if you are looking several levels down.
The other way is to use UIManager:

var menu = (Menu)((ImageMenuItem)this.UIManager.GetWidget("/menubar2/FileAction/LastProjectsAction")).Submenu;

But how do I know what the path to the menu is? You need to open your auto-generated window class and find there a line like this:

this.UIManager.AddUiFromString("<ui><menubar name='menubar2'><menu name='FileAction' action='FileAction'><menuitem name='SaveAction' action='SaveAction'/><menu name='LastProjectsAction' action='LastProjectsAction'/><menuitem name='ManageProjectsAction' action='ManageProjectsAction'/><separator/><menuitem name='ExitAction' action='ExitAction'/></menu></menubar></ui>");

If you traverse nodes, following their "name" attribute, that would be the path you are looking for.

Using "Menu.Append()" you can add new MenuItem to the menu. You run your program, and... there is no result. There is no exception, but no new menu item either. Why is it missing? Gtk again: by default any widget's visibility property is off. Don't ask me why. Just call Gtk.Widget.Show() on newly added menu item. As alternative, you can add menu items and than call "Widget.ShowAll()" on the parent menu.

When those problems were sorted out I got functioning basic UI application which loads last used files as a menu.

Wednesday, July 29, 2009

Pattern: resource management using callbacks



In C# in order to manage resources, IDisposable interface is used. But what if resource creating is complicated and requires a dedicated function? Lets say we have a system with multiple databases and complicated logic deciding which database should be used. We want to encapsulate this knowledge into a function:

class ConnectionWrapper {
IDbConnection NewConnection() {
string connectionString
... // whatever application specific logic
... // constructing connection string
return new SqlConnection(connectionString);
}
}


There is something bothering me in this code. We return new Connection object without guarantee that it will be disposed. We assume that the caller will utilize "using" statement. So we create resource but we do not have control over it correct usage.

Now, do you remember that when creating Data Reader by calling IDbCommand.ExecuteReader, we can provide a parameter "CommandBehavior" and one of the options is "CommandBehavior.CloseConnection". Why is that? It is exactly for the reason I've just described: sometimes we create connection in one place but we create a reader in another place. So we can not coordinate their life time. We can not wrap Connection into "using" because most likely we will close connection before data reader will have chance to finish reading. That's where "CommandBehavior.CloseConnection" helps. We create connection without worrying (or shall I say "with a hope") and we always create reader with "CommandBehavior.CloseConnection" and wrap reader into "using".

Needless to say, it is fragile. May be not really terrible, but you have to be careful and remember about all those little agreements you have in your application. Of course, you never forget things but when you write a framework to be used by others 10 programmers, it is just matter of time, when somebody will start leaking half-committed transactions... you will have a lot of fun trying to figure it out.

So, what new and shiny C#-2.0 (or even better 3.0) gives us? Callbacks. Or should I say simple way to write callbacks.
Lets see, what we want is a guarantee that resource allocated is not leaked. So we need to use "using" statement.

class ConnectionWrapper {
IDbConnection NewConnection() {
string connectionString
... // whatever application specific logic
... // constructing connection string
using(var connection = new SqlConnection(connectionString))
return connection;
}
}
}


This is what we want. But it will not work, because connection will be disposed before returning it to the caller and caller will get disposed connection. So here is the trick:


class ConnectionWrapper {
void NewConnection(Action<IDbConnection> callback) {
string connectionString
... // whatever application specific logic
... // constructing connection string
using(var connection = new SqlConnection(connectionString))
callback(connection);
}
}
}


We do not return connection object now. Instead caller must provide a callback code.
And notice important detail: connection object is wrapped into "using" statement, so we achieved our goal: we have guarantee that it will not leak.
Here is how caller will look like:

ConnectionWrapper.NewConnection(connection=>{
IDbCommand cmd = connection.CreateCommand();
cmd.CommandText = "select ...";
using(IDataReader reader = cmd.ExecuteReader()) {
while(reader.Read())
...
}
});


Notice, that caller does not have to use "using" on connection object. We simplified caller and improved reliability the same time.
But now we look suspiciously at the remaining "using" statement: if we managed to get rid of one, can we do the same thing to the another? What if callback will return reader instead of connection string?


class ConnectionWrapper {
void NewConnection(string sql, Action<IDataReader> callback) {
string connectionString
... // whatever application specific logic
... // constructing connection string
using(var connection = new SqlConnection(connectionString))
IDbCommand cmd = connection.CreateCommand();
cmd.CommandText = sql;
using(IDataReader reader = cmd.ExecuteReader()) {
while(reader.Read())
callback(reader);
}
}
}
}

// Caller:
var names = new List<string>();
ConnectionWrapper.NewConnection("select ...", reader=>{
names.Add((string)reader["Name"]);
});


Wow! Caller is now just two lines of code. And at the same time we keep Connection and Reader object inside "using".

But what if I want some parameters into my Command? Or you want to set command timeout? By now you should get used that the answer is going to be... right, callback :)


class ConnectionWrapper {
void NewConnection(Action<IDbCommand> cmdCallback, Action<IDataReader> callback) {
string connectionString
... // whatever application specific logic
... // constructing connection string
using(var connection = new SqlConnection(connectionString))
IDbCommand cmd = connection.CreateCommand();
cmdCallback(cmd);
using(IDataReader reader = cmd.ExecuteReader()) {
while(reader.Read())
callback(reader);
}
}
}
}

// Caller:
var names = new List<string>();
ConnectionWrapper.NewConnection(
cmd => {cmd.CommandText = "select ..."; cmd.Parameters.Add(...)},
reader=>{names.Add((string)reader["Name"]);
});


Now the framework call two callbacks: one to give the caller opportunity to set up Command properties, and another callback for Reader which will be called for each row in Reader.

Conclusion.
This article demonstrates how to use callback to keep resources life time under control without burdening callers.

Tuesday, June 09, 2009

Console in Windows application



Sometimes it is convenient to have a text console in windows non-console application. For example it is much more convenient to debug windows service in console than as a real service.
If you try to do Console.WriteLine() from our service, it will produce nothing, because there is no console window at all. You can go to project settings and change project type from windows application to console application, but it is inconvenient, because your will have to remember to undo it.

Initialize console in windows application is easy calling API function:

[System.Runtime.InteropServices.DllImport("kernel32")]
static extern bool AllocConsole();


Now you can add some parameter parsing and programmatically switch into console mode without tweaking your project.

Another nice trick is to switch into console mode instead of windows service mode whenever you run your project under Visual Studio debugger.

static class Program
{
static void Main()
{
if (AppDomain.CurrentDomain.DomainManager.GetType().Name !=
"VSHostAppDomainManager")
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new Service1() };
ServiceBase.Run(ServicesToRun);
}
else
{
AllocConsole();
var srv = new Service1();
srv.Start();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
srv.Stop();
}
}

[System.Runtime.InteropServices.DllImport("kernel32")]
static extern bool AllocConsole();
}