2009-03-31

My next new best friend

http://blogs.remobjects.com/blogs/ck/2009/02/06/p251

Read the comments I posted to see why I like it!

Unemployed

My employer's support contract has finally come to an end which means I have to look for another job, haven't had to do that in a while!

Drop me an email if you have any positions vacant, in the meantime it's time to do a little "networking".

2009-03-26

Hitler and the BNP

This is the funniest thing I have seen in a long time. It's a Nazi film that's been fraudulently subtitled to depict Hitler finding out that his name is on the leaked BNP membership list.

2009-03-24

Unity - contexts

The outcome of this fairly long exchange on codeplex has made me very happy!

The BNP need my help

It seems they are unable to spell the word "money", because every time they send me their drivel of a newsletter they always want money. Usually it is for their "Van of truth" (which amuses me immensely) but this time it is to help them to become "the most technically advanced political party in the UK".

So, what are they going to do to earn this esteemed title?

  1. Set up our own BNP call centre
  2. Set up the party campaign central office
  3. Purchase 18 computers/screens/software
  4. Activate our brand new central database platform
  5. Recruit more staff to cope
  6. Train all staff in new systems
  7. Set up central mailing and telephone points for party
  8. Open our new logistical distribution warehouse

Riiight.

  1. Call centre – Surely other parties have these?
  2. Central office – I am pretty sure other parties have these!
  3. 18 computers / screens / software – Screens? Are they going to watch TV on them? MONITORS! At least we are talking I.T. now though.
  4. Central database platform – Most likely a list of names and addresses in MS Access, which is probably a nice upgrade from an Excel spreadsheet.
  5. Recruit staff – Not I.T. related.
  6. Train staff – Surely it is assumed that recruiting staff entails training them to do their jobs?
  7. Mailing / telephone points – Get an address and a telephone?
  8. Warehouse – Bob's garage is too small for their Winston Churchill leaflets then?

If they think that is technologically advanced I had better not start my own political party, because my mobile phone is more technologically advanced than that, and it's broken!

I love the part where he says "This is a task of almost biblical proportions", brilliant! Nick Griffin has obviously not read The Bible! I can imagine Moses now. "Let my people go, or I will set up a small call centre with a telephone line, 8 computers with "Screens" and empty Bob's garage!"

As usual the entire thing is full of rubbish. Don't people realise that this party will never get into power, all they are doing is electing people into a system which will give them money for doing nothing at all?

Now what they should really do is to vote for this guy!

2009-03-09

My new favourite website

I don't mind people asking me questions, I enjoy helping people. What I don't like is when people ask me questions as a substitute for using their own brains. If the answer isn't obvious there is always Google!

That's why I love this website. When someone is asking me really basic questions that would easily be answered by Google I pop along to the site and enter the search phrase. I think it's a great way of getting a message across.

2009-03-08

No Silverlight?

I'm trying to view this page in Firefox. When it loads the browser tells me I need Silverlight, so I download and install it and then restart my browser only to be told I need to install Silverlight.

That's not impressive at all!

2009-03-04

Delphi flickers

My app has a wizard approach, the current control appears within a panel with Align set to fill the hosting panel. My first wizard step control merely had an image on it which resizes with its parent control. When I resize the form the host panel resizes, which resizes the wizard control, which resizes the image; and boy does it flicker!

I just had to spend some time upgrading my old Delphi DIB controls to D2009 just to get an image that doesn't flicker, crazy! By the way, I tried the same thing in VS2008 and there was no flicker at all, and I thought Delphi was supposed to be the tool that produced fast UI apps.

2009-03-03

Synchronising downloads and updates (2)

There was a potential deadlock in the last piece of code. When you obtain any kind of lock you will mostly use a try..finally block to ensure the lock is released when you have finished with it. The using() command expands to a try..finally block so the original code might look okay, however if you mentally expand the code you will see the problem.

using (FileLockingService.FileReadLock(product1.ID))
{
    //Some code here
}

This becomes

var disposable = FileLockingService.FileReadLock(product1.ID);
try
{
    //Some code here
}
finally
{
    disposable.Dispose();
}

So why is this a problem? In a single threaded application it isn't, but this is a website so there are multiple threads running at the same time. Now take into account the fact that a web request has a timeout, what if the thread is aborted after the lock is obtained? Ordinarily this isn't a problem because the acquisition is followed immediately by a "try", but if we expand this code further it is evident that this isn't the case for the code I originally wrote. The code below is indented per method rather than the normal logical indendation

  • var disposable =
    • //Code inside FileLockingService
    • var lockHandler = GetLockHandler(int id);
    • lockHandler.EnterWriteLock();
      //The next command must be a try block
    • var enterWriteLockResult = new DisposableAction(..............); //Oops!
      • if (action == null) throw new ArgumentNullException("Action");
      • this.Action = action;
      • this.Context = context;
    • return enterWriteLockResult;
  • try
    {
        //Some code here
    }
    finally
    {
    disposable.Dispose();
    }

So here you see that rather than there being a TRY block immediately after the EnterWriteLock the code above would create a DisposableAction, check a parameter, assign two instance members, and then return a result. If anything went wrong at any of these points (OutOfMemoryException, ThreadAbortException, etc) then we'd end up with a lock that would not get removed. The code has been changed as follows.

    public class FileLockingService : IFileLockingService
    {
        readonly object SyncRoot = new object();
        readonly Dictionary<int, WeakReference> Locks = new Dictionary<int, WeakReference>();

        public ReaderWriterLockSlim GetLockHandler(int productId)
        {
            WeakReference resultReference;
            ReaderWriterLockSlim result;
            lock (SyncRoot)
            {
                if (Locks.TryGetValue(productId, out resultReference))
                {
                    result = (ReaderWriterLockSlim)resultReference.Target;
                    if (result != null)
                        return result;
                }
                result = new ReaderWriterLockSlim();
                Locks[productId] = new WeakReference(result);
            }
            return result;
        }
    }

and when I use this service:

    FileLockingService.GetLockHandler(product.ID).EnterReadLock();
    //.NET wont allow any exceptions until flow passes into the try block
    try
    {
        //This is the earliest point that an exception can occur after acquiring the lock
        using (var sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            Response.ClearHeaders();
            Response.AddHeader("Content-Type", "Application/Binary");
            Response.AddHeader("Content-Disposition", "attachment; filename=" + product.ClientFileName);
            using (var resultStream = DownloadService.Process(currentUser, new List<string>(), product.ClientFileName, sourceStream))
            {
                int bytesRead;
                byte[] data = new byte[1024];
                while ((bytesRead = resultStream.Read(data, 0, data.Length)) > 0)
                    Response.OutputStream.Write(data, 0, bytesRead);
                Response.End();
            }//using
        }//filestream
    }
    finally
    {
        FileLockingService.GetLockHandler(product.ID).ExitReadLock();
    }

Lesson learned: When it comes to thread synchronisation don't do anything fancy!

2009-03-02

Synchronising downloads and updates

Apparently my boss used to be annoyed with something on his old website. When he wanted to upload an updated binary he often couldn't because his product was so popular that someone was always downloading it at the same time. He'd have to continuously hit Delete in his FTP client until eventually he'd slip in and manage to delete it before updating the new version.

This obviously isn't an ideal solution because:

  1. He constantly had to sit there for around an hour trying to delete it.
  2. Once deleted from the disk any user attempting to download would get a 404 – Not Found error.
  3. During upload any user attempting to download would get an Access Denied error of some kind.

For this website I have decided first of all to only update the files via a HTTP form post. So firstly any long running upload will not deny access to the currently available file, this eliminates problem 3. Additionally, using a form post means I can overwrite the existing file, so this eliminates problem 2.

The potential problems I have now though are:

  1. If he uploads but the file is in use the process will fail, causing him to have to upload again. From his upload use case this is worse than before because it takes much longer to discover your upload hasn't worked.
  2. If a user attempts to access the file during the process of copying from memory to disk they will still get an access error. Although this is now much less likely it could still happen.

My solution was to implement an IFileLockingService. Downloading a file should place a read lock, uploading the file should place a write lock. Multiple read locks may exist at once, but a write lock is exclusive. Any conflicts will result in the lock request waiting until it may proceed.

//Downloading
using (FileLockingService.FileReadLock(Product.Id))
{
    //Write a binary response based on the file
}

//Uploading
using (FileLockingService.FileWriteLock(Product.Id))
{
    //Write the posted file to disk
}

To implement the read/write lock I used a ReaderWriterLockSlim instance per Product.ID. To keep memory usage down I ensured that I used a WeakReference to hold the ReaderWriterLockSlim reference so that it may be collected once no longer referenced.

public class FileLockingService : IFileLockingService
{
    readonly object SyncRoot = new object();
    readonly Dictionary<int, WeakReference> Locks = new Dictionary<int, WeakReference>();

ReaderWriterLockSlim GetLockHandler(int id)
{
    WeakReference resultReference;
    ReaderWriterLockSlim result;
    lock (SyncRoot)
    {
        if (Locks.TryGetValue(id, out resultReference))
        {
            result = (ReaderWriterLockSlim)resultReference.Target;
            if (result != null)
                return result;
        }
        result = new ReaderWriterLockSlim();
        Locks[id] = new WeakReference(result);
    }    
    return result;
}

public IDisposable FileReadLock(int productId)
{
    var lockHandler = GetLockHandler(productId);
    lockHandler.EnterReadLock();
    return new DisposableAction(context => lockHandler.ExitReadLock(), null);
}

public IDisposable FileWriteLock(int productId)
{
    var lockHandler = GetLockHandler(productId);
    lockHandler.EnterWriteLock();
    return new DisposableAction(context => lockHandler.ExitWriteLock(), null);
}
}

DisposableAction is a class I have mentioned here

2009-03-01

The best tool for the job

If I had to write a large business app which accessed a DB, or a website, I would use .NET without hesitation. When it comes to small apps (less than 10MB) that will be downloaded by home users what should I use? I have such a project coming up soon, my boss has bought D2009 and wants me to use that because he is paranoid about people reverse engineering the binaries. I'm a little hesitant but I must admit that I think in this case Delphi 2009 probably is the best tool for the job, and I like to use the best tool for the job rather than the tool I like to use best for my job.

Hopefully things will go smoothly, it will be nice writing apps in two different languages.

Music to fight to

An odd title for a coding blog I know, but I love martial arts too, especially competitive ones.

I'm just putting together a CD for my car. The tunes on the CD music really make my adrenaline pump, so I am putting together a compilation of tunes which make me want to win a fight...with style!

  1. Nirvana – Smells like teen spirit.
  2. Fat boy slim – Right here right now.
  3. William Orbit – Adagio for strings (Ferry Corsten Remix with first 2 mins cut off).
  4. The Prodigy – Breathe.
  5. The Prodidy – Firestarter.
  6. Chemical Brothers – Block rockin' beat.
  7. Chemical Brothers – Setting Sun.