kanban-warrior sees its first birth!

In a previous post I described how you can implement a Kanban board with Task Warrior.
To make life a bit easier when using the flow, especially moving between the stages, I made a wrapper script around Task Warrior, which I called kanban-warrior
It accepts simple commands (in the style of Task Warrior 🙂 ), to add and move around tasks in the different stages. It also gives an error message when you try to move a task to the wrong stage. It can also generate reports of the different stages.
Since kanban-warrior provides just some convenient shortcuts to implement the flow (if you look at the code, you will see that it actually executes TW commands), you can just use it in combination with other TW commands (and equally fuck up things 🙂 )

I released version 1.0 and you can get it here.
It is one of my first projects in Python, so forgive me if the coding style is not according to Python standards.
Please contact me if you have comments, encounter bugs, have suggestions for new features, or even if you want to contribute.

A basic usage example

Add a task to the backlog

./kanban-warrior addtobacklog "Starship:propulsion" "Add static warpfield converter"
Created task 3.
The project 'Starship:propulsion' has changed.  Project 'Starship:propulsion' is 0% complete (1 of 1 tasks remaining)

Display the backlog

./kanban-warrior.py list backlog Starship
ID Project                  Pri Added                 Started Due Recur Countdown Age Deps  Tags     Description                  
 3 Starship:propulsion   -  14-3-2013 20:59                 -                              2m           backlog           Add static warpfield converter                                                                                                                                                        
1 task

Move a task from the backlog to the Work In Progress Queue and start it immediately

./kanban-warrior start 3
Loading task list..

Modifying task 3 'Add static warpfield converter'.
Modified 1 task.
Project 'Starship:propulsion' is 0% complete (1 of 1 tasks remaining).

Starting task 3 'Add static warpfield converter'.
Started 1 task.
Project 'Starship:propulsion' is 0% complete (1 of 1 tasks remaining).

Set a task on hold

 ./kanban-warrior.py hold 3 "Fucked up"
Loading task list..

Stopping task 3 'Add static warpfield converter'.
Stopped 1 task.
Project 'Starship:propulsion' is 0% complete (1 of 1 tasks remaining).

Modifying task 3 'Add static warpfield converter'.
Modified 1 task.
Project 'Starship:propulsion' is 0% complete (1 of 1 tasks remaining).

Annotating task 3 'Add static warpfield converter'.
Annotated 1 task.
Project 'Starship:propulsion' is 0% complete (1 of 1 tasks remaining).

Invalid move

./kanban-warrior.py finish 3
Loading task list..
Error: Task must be in progress

You can’t move a task in the ‘on hold’ stage directly to the ‘done’ stage, it has to go through the ‘in progress’ stage first

Note: The ‘3’ in the commands above is the TW task id, which you can retrieve by just generating a TW report (either with or without kanban-warrior)
More information about the siupported commands can be found in the README file and there is also a short help screen when executing kanban-warrior -h

Kanban Warrior

Yesterday I discovered this awesome command line tool called Task Warrior. It is basically a to-do list on steroids; you can define tasks, group them into projects, generate reports etc. etc. (see the website for more information). When I was fiddling around with the program, the thought occurred to me (since I use mostly Scrum+Kanban methodologies in my work projects): Can Task Warrior be used to implement a Kanban board? (for more information about the Kanban methodology see here).

After some thought and browsing through the Task Warrior forum about this topic with some very good ideas, i’d come up with my own workflow. It is actually based on the solution Nikola Petrov posted in the forum. Note that there is no checking on constraints (max WIP items, illegal moves between columns, etc.), so it’s possible to mess up things, that is all up to you. Then again, when using an “analog” whiteboard you can also do these funky things.

Explanation of stages

  • Backlog: Work items defined to be done in this period/sprint/whatever
  • In progress: A queue of work items that YOU are currently working on. See it as your personal backlog. This should be limited to maybe 1 or 2 items (but that is a matter of convention. Can contain active items, i.e. the things you are really working on at this very moment
  • Done: Work items that are done
  • On hold: Work items that can’t be worked on due to an external cause

You can see an example and screenshots below. I used the terminal application found in Xubuntu and for each stage (Backlog, In progress, Done, On Hold) I defined a tab. I use the tab Control for administration, i.e. adding & modifyng tasks.

Add some tasks to the backlog:

task add project:"Starship.Propulsion" +backlog "Implement subspace distortion detector"
Created task 1
The project 'Starship.Propulsion' has changed.  Project 'Starship.Propulsion' is 0% complete (1 of 1 tasks remaining).

task add project:"Starship.Propulsion" +backlog "Implement warp coil heater"
Created task 2
The project 'Starship.Propulsion' has changed.  Project 'Starship.Propulsion' is 0% complete (2 of 2 tasks remaining).

task add project:"Starship.Propulsion" +backlog "Implement warp containment field modulator"
Created task 3
The project 'Starship.Propulsion' has changed.  Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).

task add project:"Starship.Defense" +backlog "Implement tachyon beam detector"
Created task 4
The project 'Starship.Defense' has changed.  Project 'Starship.Defense is 0% complete (1 of 1 tasks remaining).

task add project:"Starship.Weapons" +backlog "Improve phaser array"
Created task 5
The project 'Starship.Weapons' has changed.  Project 'Starship.Weapons is 0% complete (1 of 1 tasks remaining).

Moving items from the backlog to the ‘In progress” queue

task 1-3,5 modify -backlog +inprogress
Modifying task 1 'Implement subspace distortion detector'.
Modifying task 2 'Implement warp coil heater'.
Modifying task 3 'Implement warp containment field modulator'.
Modifying task 5 'Improve phaser array'.
Modified 4 tasks.
Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).

(Re)start working on items in the In progress queue

task 1,5 start
Starting task 1 'Implement subspace distortion detector'.
Starting task 5 'Improve phaser arrayr'.
Started 2 tasks
Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).
Project 'Starship.Weapons' is 0% complete (1 of 1 tasks remaining).

Stop working on an item (but it’s not finished yet)

task 1 stop
Stopping task 1 'Implement subspace distortion detector'.
Stopped 1 task.
Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).

Start working on an item, but then the item is put on hold for some reason

task 3 start
Starting task 3 'Implement warp containment field modulator'.
Started 1 task.
Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).

task 3 stop
Stopping task 3 ''Implement warp containment field modulator''.
Stopped 1 task.
Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).

task 3 modify -inprogress +onhold
Modifying task 3 'Implement warp containment field modulator'.
Modified 1 task.
Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).

task 3 annotate "We can't set the correct delta-factor compensation"

Putting an “On hold” item back to the “In progress” queue and start working on it again

task 3 modify -onhold +inprogress
Modifying task 3 'Implement warp containment field modulator'.
Modified 1 task.
Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).

task 3 start
Starting task 3 'Implement warp containment field modulator'.
Started 1 task.
Project 'Starship.Propulsion' is 0% complete (3 of 3 tasks remaining).

Setting items to Done

task 1,3 modify -inprogress
task 1,3 done
Completed task 1 'Implement subspace distortion detector'.
Completed task 3 'Implement warp containment field modulator'.
Completed 2 tasks.
The project 'Starship.Propulsion' has changed.  Project 'Starship.Propulsion' is 66% complete (1 of 3 tasks remaining).

Notes:

I used the ‘subproject’ feature to indicate my user stories (so ‘Starship’ is the name of the project and ‘Propulsion’ is the name of the story), so that I can relate tasks to a particular story.

Screenshots

[nggallery id=1]

A hardware monitor in C# 4.0 with the Task Parallel Library – Part 2 – Exception handling

Welcome back at part 2 in this series. In the last part I described the basic framework for the hardware monitor. In this part I will add some exception handling to the monitor and also a way to provide the monitor with extra configuration parameters.

The code can be found here, in the “Part 2” folder.

Exception handling

We would like to stop the main task when an exception is thrown and log the information.
Remember the continuation task we defined earlier to handle the main task cancellation. We can extend this that it also handles exceptions.

 this.readerTask.ContinueWith(t =>
 {
     if (t.IsFaulted)
     {
        t.Exception.Handle((x) =>
        {
           Console.WriteLine("Exception in task: {0}", x);
           return true;
        });

        try
        {
           CleanUp();
        }
        catch (Exception ex)
        {
           Console.WriteLine("Cleanup exception: {0}", ex.Message);
        }
    }
   //Notify everyone that we stopped
   OnStatusChanged(MonitorStatus.STOPPED);
   Console.WriteLine("Reader task stopped");
},TaskContinuationOptions.NotOnRanToCompletion);

When an exception in a Task is thrown, the status of the task is set to IsFaulted. So our continuation task should also be executed if the main task is in the faulted state. We accomplish this by changing the TaskContinuationOptions to TaskContinuationOptions.NotOnRanToCompletion, so that it executes when the main task is cancelled or is in the faulted state.

All exceptions thrown in a Task are collected by the TPL and put in one exception of type AggregateException (see here).
The Exception property of a Task contains this AggregateException. It exposes also a Handle method which has a delegate as parameter.
This delegate is executed for every exception in the AggregateException. In this delegate you can put your exception handling code, for example write it to log file or in the snippet above, write it to the console. (the X is the parameter to the delegate and is the current exception being processed) It should return True to indicate that this particular exception is handled, if it returns false the exception is further thrown down the stack.

After handling the exceptions, the CleanUp() method is called to ensure the monitor can be started again in a correct way.

Configuration parameters

It is not unthinkable that you want to pass some configuration parameters to your monitor, like baudrates, communication ports etc.
To add this functionality we have to change the interface a little bit:

public interface IDeviceMonitor<TConfigData, TDeviceData> : IDisposable
{
  void Start(TConfigData configData);
  ...
}

An extra type parameter (TConfigData) is added which represents a class (or even just an int or double or whatever)  that defines the configuration data you want to use.
When calling the Start method you pass an instance of this class.

Our base class also changes a bit, because, obviously, you want to work with the configuration data in your derived class:

public abstract class DeviceMonitorBase<TConfigData, TDeviceData> : IDeviceMonitor<TConfigData, TDeviceData>
{
  ..
  protected TConfigData configData;    
  public void Start(TConfigData configData)    
  {    
      this.configData = configData;
 ..

Example

I improved the example implementation a bit. I added a second timer monitor (TimerMonitorWithException) which throws an exception when the number of seconds is equal to an user specified number. You can pass this number as an argument to the Start() method. It therefore demonstrates the exception handling AND the use of configuration parameters.

I also extended the original timer monitor so that it uses a configuration parameter. Here you can adjust the interval of  printing the current time to the console.

This was part 2 of this series.  I hope you enjoyed reading this as much as you enjoyed the first part.

Happy coding and until next time!

A hardware monitor in C# 4.0 with the Task Parallel Library – Part 1 – The basics

Sometimes you need to continuously and in the background retrieve and process data from an external device connected to your system (for example a GPS receiver or you want to monitor your ethernet connection). The external device has maybe a low level driver/interface which only has the possibility to retrieve its data synchronously. I designed a small framework in C# 4.0 that makes a nice threaded abstraction layer around this. The multithreaded part is implemented with the help of the Task Parallel Library.
In this and following posts I will try to describe it step by step. The complete code can be found here and all code snippets below refer to the Part 1 project in the solution

[Disclaimer] I don’t pretend that this is the ONLY and/or MOST EFFICIENT way to implement this. It just works for me. If you have any remarks or suggestions for improvement or bugs, please leave them in the comments below [/Disclaimer]

Ok, after this introduction, LET’S GET STARTED!

Interface

First we start by defining an interface. Obviously we want to start and stop the retrieval/monitoring and since the monitor will be run on a background thread we define an event that is going to be fired when new data arrives.

public interface IDeviceMonitor<TDeviceData> : IDisposable
{
    void Start();
    void Stop();
    event EventHandler<MonitorStatusEventArgs> MonitorStatusChanged
    event EventHandler<DataReceivedEventArgs<TDeviceData>> DataReceived;
}

The generic parameter TDeviceData defines a class in which you can put the data your hardware/device makes available. An instance of this
class is passed along with the event. Since hardware communication may involve access to unmanaged resources we make it IDisposable as well.
We also define an event that is fired when the state of the monitor changes (e.g. from started to stopped or vice versa).

Base class

Then we define a base class in which we put all the TPL stuff and other plumbing code so that they are hidden away nicely from the actual implementations. (those implementations contain probably a lot of low level hardware interaction, and we don’t want to get all this plumbing code in the way.)

public abstract class DeviceMonitorBase<TDeviceData> : IDeviceMonitor<TDeviceData>

Here we define a couple of life cycle methods which can (or must) be overridden in a derived class.

protected virtual void Initialize() { }
protected abstract TDeviceData ReadData();
protected virtual void CleanUp() { }
public virtual void Dispose() { }

Initialize() is called after the monitor is started before entering it’s main event loop. You can put optional initialization code in here, like opening ports, setting baudrates and other stuff.

ReadData()  is called in the main event loop and is the method in which it all happens, reading the data from a device, and must be (obviously) overridden in a derived class.

CleanUp() is called after the monitor receives the request to stop. Here you can put clean up code like closing ports etc. N.B. It’s not recommended to put here ‘expensive’ operations like freeing memory or freeing device handles, put this code in the Dispose() method.  The purpose of this method is to put the monitor in a sort of ‘sleeping’ state so that it can be started again quickly.
The same principle counts for the Initialize method, don’t put there any memory allocation or other ‘heavy’ operation, since this will be executed every time when the monitor is started. You can put those heavy operations in the constructor of your derived class.

TPL stuff

The whole process is executed in a  Task (see this msdn link for more information) with a continuation task which handles the case when the main task is canceled after a call to the Stop() method.

The main task (readerTask) is created in the Start() method and its operations are defined in a lambda expression. The comments explain what is happening.

void Start()
{
    this.ctSource = new CancellationTokenSource();
    CancellationToken ct = ctSource.Token;

    this.readerTask = new Task(() =>
    {
         //Are we cancelled yet?
         ct.ThrowIfCancellationRequested();

         //Notify everyone that we started
         OnStatusChanged(MonitorStatus.STARTED);

         //Do initialization work
         Initialize();

         //This is our main loop and reads data until this task is cancelled
         while (true)
         {
             if (ct.IsCancellationRequested)
             {
                 //Cancel it
                 CleanUp();
                 ct.ThrowIfCancellationRequested();
             }

             //Read the data from the device
             TDeviceData data = ReadData();

             //Fire event
             OnDataReceived(data);
         }

    }, ct);
...
}

One further remark: In case you don’t already know, but cancellation of a task is accomplished with CancellationTokens that are created from a CancellationTokenSource. In the Stop() method actual cancellation is done by calling the Cancel() method on the CancellationTokenSource from which the CancellationToken is created. In the task an exception will be thrown which actually cancels and stops the task. See here for more info about task cancellation.

The continuation task executes only when its predecessor (our readerTask) has been cancelled. In this case a message is printed to the console, but you can write this message to a log file or event log or whatever. It also notifies all the subscribers that the monitor has stopped

 this.readerTask.ContinueWith(t =>
 {
   Console.WriteLine("Read task stopped");
   OnStatusChanged(MonitorStatus.STOPPED);
 }, TaskContinuationOptions.OnlyOnCanceled);

Example implementation

I made a sample implementation to put the theory from above in practice. You can find it in the TimerMonitor class. It’s just an amazingly unwieldy way to display the current time, but hey I just want to show a simple example.
I created also a sample console application which runs the TimerMonitor.

Well, I hope you have learned from this post and found it useful. Stay tuned for Part 2 of this series in which I add exception handling.
You can have a sneak preview when you look at the Part 2 project in the solution

Happy coding!

FOSDEM is coming again

It’s almost february and that means that one of the greatest FLOSS events in the year is due to happen – FOSDEM 2013.
The event is happening on the 2nd and 3rd of february at the ULB campus in Brussels,  with a lot of interesting talks and sessions (and a lot of geeks and beer too 🙂 about the magic world of Open Source Software. Please check out the website here for more information.

I will be visiting the event as well (starting at Friday evening at the beer event, so say ‘hi’ if you see me :-)) and will try to keep you posted about the sessions i’ll visit.