Thursday, 5 September 2013

Monodevelop 4.0 and dark themes

Monodevelop 4.0 (or "Xamarin Studio" if you're one of the blessed Mac or Windows users) was released a fair while back with great fanfare as the new, awesome major re-designed version of Monodevelop. I think it's fair to say that I wasn't impressed.

Aside from the ever-present nightmare of building the damn thing (turns out you need to already have a version of monodevelop installed or the new version spews out a ton of errors when you build it), the folks behind Monodevelop managed to produce an IDE that was utterly unusable for me. Why? Because it only partially followed the system themes. Following themes is a really nice feature - it makes the application fit in with your working environment nicely and (if you're me) allows you to run it with a nice, dark look that doesn't give you a headache by lunchtime. I find the standard black text on glaring white background to be a great way to increase painkiller sales at my local shop.

Totally ignoring themes would be annoying, but hey, I can live with it. At least you can still get on and work, right?

Monodevelop 4 does neither.

Monodevelop 4 applies some of the colours to some of its interface. Which leads to the joy of trying to read light grey text (following my system theme) on a light grey background (ignoring my system theme). Some of the fancy new components that Xamarin have created to bling up the interface have partially hard-coded colour schemes. It's inexcusable, really; an inexplicable error to put in a supposedly polished, high(ish)-profile release. I can only assume that nobody ever thought to check what happened when you applied dark themes.

Maybe Xamarin have fixed it in later releases. Maybe not. I don't know, and I don't really care, because everything after 4.0 relies on having access to mono > 2.10.8.1 - and since Ubuntu (the platform I'm working on) hasn't had an update to mono in repos for the last three centuries or something I'd have to build mono to use it - but everything I work on needs to be capable of running on the version in repos. Yes, I could run parallel monos on my desktop, but just to fix a colour scheme? Really?

Personally I think it's totally understandable that those who use Mono/Monodevelop on Linux are beginning to feel like Xamarin has hung us out to dry. But that's an argument for another day. The point of this post is: You can hack the monodevelop sources to make your dark theme work enough to use 4.0. This isn't a fix as such; if you change the theme, you'll need to hack the sources again and recompile. I don't know my way around the monodevelop sources well enough to properly fix it (plus it's not my job to spend the time learning my way around and, fuck it, they don't see linux support as worthwhile, I don't see why I should spend my time fixing their shoddy engineering).

The Hack

To make Monodevelop usable with your dark theme (I use Nodoka-Midnight) you'll need to modify a few of the source files. The motherlode of hard-coded colours is in src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Styles.cs. I've used rather a blunderbuss approach, and some of the following changes may not strictly be necessary; feel free to apply them one by one and see which steps can be skipped:
  • Swap over the values of BaseForegroundColor and BaseBackgroundColor (lines 33 and 34)
  • Darken ThinSplitterColour (I set it to 31,31,31)
  • Darken the TabBarBackgroundColor (I used 2e2d2d)
  • Darken the BreadcrumbGradientStartColor (I used 484444)
  • Darken all the DockTabBar... colours (I used variants on 45d / 255d, 44d / 255d, 44d / 255d and halved the numerators for the ...Shadow... colours)
  • Similarly darken PadBackground, DockFrameBackground and BrowserPadBackground
That should get most of the interface at least usable. There's also a tab strip sitting under the main edit window in the default debugging layout which is almost impossible to read without changing its background colour, so in src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs, line 40 darken BackgroundGradientStart to something like 45d / 255d, 44d / 255d, 44d / 255d

Now make & make install monodevelop and you should be able to use it with a dark system theme without half of the interface being illegible.

As I said, this is NOT a fix. It's a horrible hack. Monodevelop shouldn't be using hardwired colours at all - or it shouldn't be applying colours from the system theme at all. The way it's implemented is a textbook case of a half-baked feature being worse than none at all.

Saturday, 25 February 2012

Asynchronous HTTP GETs being slow

Note to self:

If asynchronous HTTPS GETs from the same browser (in multiple tabs, say, or from an ajax site) seem slower than they should be - for example, if request roundtrip times get multiplied up by the number of tabs open - then it's very likely a bottleneck being caused by the browser cache. Firefox and Chrome at least (not tested any others) seem to only allow cache writing through a critical section or something. So the entire browser has a single, locked cache. And seems to lock it for the *entire* duration of the GET request. Which means aysnchronous GETs end up forming an orderly but very slow queue.

Turn off caching in the http request object and the problem goes away (though, of course, you don't get to cache anything any more).

Came as a surprise to me. Couldn't find an explanation for the behaviour when it cropped up - I assumed for ages our server was to blame. It wasn't.

Thursday, 22 December 2011

Ill-Considered Smartphone Griping

My current phone, a Samsung Galaxy S, is the first smartphone and by far the most expensive phone that I've owned. And sometimes it hacks me off far more than any past phone. Let me start by saying that smartphones are amazing devices. They're so far beyond phones it's not funny. And that's sort of the problem; there's so much potential there, and the phone forces your expectations high by being so neat in so many way.

I'm likely to invest in a backup phone soon which is just a phone purely so I have a more rugged, less expensive phone with a less fleeting battery life. I just can't get comfortable heading out on the bike for a day with my SGS tucked in the back of my jersey. Aside from anything, if I didn't remember to fully charge it before setting out then who knows if it'll still be working when I need it late on after disaster has struck. But I think that's fair enough, and not really a criticism of the SGS - or smartphones in general. Complaining that a smartphone doesn't work well as a long battery life, cheap, bombproof emergency backup phone is like complaining that bread makes a lousy sandwich filling; simultaneously right and dumb.

Some of what annoys me about the SGS is probably device-specific. Some of it is probably OS-specific. And some of it isn't the phones fault at all. But I still blame it, because it's the point at which the annoyance enters my life. So where to start...?

I suppose at the beginning. The SGS, as delivered, was shit. When I first got the SGS, it rapidly became apparent that various bits of it just didn't work. Samsung had cunningly designed a device whose GPS performance was so flaky as to be useless. Use it to navigate and you'd find your apparent location hopping around between neighbouring streets. Recording routes showed similar problems. An entire feature of the phone was working so badly, it would have been a better experience if it hadn't been implemented at all. Several months later - somewhere between six months and a year - and the GPS was finally fixed enough to use. Another massive problem with the phone was the file system: In their wisdom, Samsung decided to use a half-baked in-house mess called RFS (essentially FAT with an attempt at journalling tacked on). It's utter shit, and very rapidly access times plummet to the point that the phone lags whenever accessing storage. The community cooked up various lagfixes fairly quickly, but the experience out of the box was significantly worse than one would hope for. On top of all that the official support software for the phone, the route used for official updates, was so bug-ridden that it took me hours (including hacking the registry) to get it to work at all. And, of course, I had to boot a Windows VM to use it anyway since there's no support for linux hosts. Again, the community stepped in and have provided a variety of functional alternatives.

There were other issues too, but those were the headlines. And here's the thing.

I cannot - absolutely cannot - understand how a flagship device was released in such a state, or how it was left for so long without being officially fixed. I can only assume that no one in Samsung ever bothered to test any of this stuff before release. It's inexcusable, in my opinion, for such fundamental and blindingly obvious problems to be present especially in an ostensibly high-end device. I have NO desire to go through a similar process of cobbling my phone into functionality over a period of months again. I don't mind hacking it to tweak it, but in my opinion the above isn't tweaking. It's getting the damn thing working in the first place.

Moving on. There are things about the phone that even now hack me off. The one that annoys me most regularly, oddly, isn't strictly the phones fault at all but the BBCs. When listening to catch-up radio on my phone.... LET ME TURN THE FRICKING SCREEN OFF. The Beeb, in their wisdom, implemented (and by "implemented" I mean "hacked together and pretended they'd thought it through") iplayer for Android in flash. Which (a) means my wifes phone can't use it *at all* and (b) means it's shit. I mean, it works, but it's hideously inefficient and also keeps the screen turned on whilever it's running. Even if you're just listening to the radio. Power drain much? It pisses me off *so* much that Android is stuck with this shit when Apple devices aren't. I know the Apple ecosystem more established, but it's the BBC for fucks sake. They should be providing the same quality of service to all the major smartphone platforms. Anyway. More annoyances: When the battery runs low, the phone turns the screen on to tell you. And pops up a popup. Which won't dismiss until you press the appropriate button. And keeps the screen on until you do. When the battery is low. WELL PLAYED SIR. Also, even without the shonky file system, for no reason I can figure out the device briefly becomes laggy and unresponsive. Then recovers. Given I've owned less powerful PCs (fairly recently) than this device, I expect more than groaning as it tries to render a webpage because it's doing whatever housekeeping in the background.

And moving towards a more general point... I think largely what annoys me with the SGS, aside from the specifics, is any time I notice it pretending to be a phone not a computer. I mean, honestly, it's a pocket computer. It should act like one. And this is where I think lots - if not all - smartphones are going wrong (for the likes of me). Whenever I want to do something to the phone but I can't because I'm not allowed... that hacks me off. I'm used to computers that I *own* (like I own my phone!). That I can do anything to because they're fricking MINE. Now, yes, you can root an android phone to get this fundamental right of ownership back. But why should I have to? It's MY DEVICE.

Updating the SGS seems far more difficult than it should be. Maybe apt has spoiled me, but what I expect from my device is, basically, that the OS and all the software on it updates with no faff. Every Android update has been a hassle, with some of them randomly stopping various applications from working (and you'll only find out if you try to run them). And there's always eother the threat or promise of data loss. Unacceptable! Sort it the fuck out. ESPECIALLY if you're going to lock down the system for the average user so it's hard/impossible to fix stuff if it does go wrong. In fact, why do I have to stick with Android? Why can't I pay for the OS of my choice? It's just a little computer, after all.

One of the big things I was interested in doing before getting an SGS was writing stuff for it. I figured once I've actually got a device I can have a think about what I want to do with it. Yet since getting the SGS I've written *nothing* for it. There are a few reasons for this, one good, one bad, one indifferent. The good reason is that there's an awful lot of stuff already out there. I didn't need to write many of the apps I wanted. That's nice. The indifferent reason is that I *hate* writing the same thing twice. And almost everything I've wanted to do that I CAN do (see below) has been better served by just writing a web app. Then I can use it from anywhere, on any phone. The bad reason really annoys me, and although I knew this when I was getting the SGS it's only become more annoying as I've used it. And this is the big one. Fix this, and I'll buy your phone:

GIVE ME USB HOST SUPPORT, AND LET ME WRITE STUFF THAT USES IT.

They're COMPUTERS. Think of what we could do if we could use them to control USB devices! IT WOULD BE AWESOME. There are *so many things* we could do. And I keep thinking of them, and having to dismiss them because mobile phone manufacturers are knobs.

I'm fairly sure there was other stuff I wanted to grouse about, but I thought a quick stream of consciousness rant that actually got written was better than a well considered, complete but nonexistent essay.

Tuesday, 26 July 2011

Why is ASP.net on mono like a new pet that hasn't been house trained?

...because it leaks all over the place.

We've been working for a while now on an MVC (initially MVC2, now MVC3) application running on mono 2.10.2 with FluentNHibernate 1.2 sitting on NHibernate 3.1, built as a web app but also available via a kiosked browser on the server. This effectively means we've got a web browser pointed at the server 24/7. In addition, it's a fairly heavily AJAX-ed application, pinging for data every second or so, which means we've got a browser sending requests to the application every second, 24/7. Still, not exactly heavy usage.

We've had a very, very hard time getting this working stably, and all of our troubles seem to be coming from the mono stack (possibly nhibernate as well, but even with that problem, it looks more likely that mono is the root cause). If you're putting together a web application using mono, you should probably look out for the following:


Memory leaks when running with sessions enabled

This seems to be something to do with CacheItems being created at a phenomenal rate without (apparently) ever being garbage collected. Even if you see no reason whatsoever why your application would be generating CacheItems, something under the hood will be there merrily churning them out. This will, eventually, bring your system to its knees before the mono process is killed. Switching garbage collectors to sgen (newer, better, see below...) doesn't help. This is almost certainly why mono web applications mysteriously stop working under heavy load according to the mono project.

Workarounds:

 You can, as suggested in the above link, restart your mono process every so often to release the memory. Not an ideal solution, obviously. Alternatively, if you don't need sessions you can run sessionless, which seems to stop this leak from happening (so it seems the CacheItems are being generated by something in the session code...). Or you could figure out what the fricking bug is and fix it.


An apparent race hazard when starting up a web app

If you choose to accept that you'll need to restart mono every so often, the next thing to watch out for is an intermittent exception when starting up. This occasionally manifests as an object not set to an instance of an object exception, but most commonly will appear as duplicate key exception thrown by the RoleManager - even when you aren't using roles for anything. To be honest, this being a race hazard is a total guess, I have no idea what the problem is, but something which is so intermittent just smacks of a race hazard. Since we didn't need sessions enabled, we simply switched to sessionless mode and stopped pursuing this one. Interestingly, since addressing all of the other problems listed in this post we've not seen any of these problems. So perhaps again something to do with the session code in mono...?

Workarounds:

 No idea. This seems to have just gone away as we've worked around all the rest of the weirdnesses. Best of luck to you if you're trying to solve this one. Sorry I can't help more.

Running the MVC sessionless is broken in mono

You should be able to run sessionlessly simply by adding the tag
< sessionstate mode="Off" > 
inside the system.web node in your web.config file. Providing you're not actually using TempData for anything, this should be fine. However, you'll get the following exception:

System.ArgumentNullException: Argument cannot be null.
Parameter name: httpSessionState
  at System.Web.HttpSessionStateWrapper..ctor (System.Web.SessionState.HttpSessionState httpSessionState) [0x00000] in <filename unknown>:0 
  at System.Web.HttpContextWrapper.get_Session () [0x00000] in <filename unknown>:0 
  at System.Web.Mvc.SessionStateTempDataProvider.LoadTempData (System.Web.Mvc.ControllerContext controllerContext) [0x00000] in <filename unknown>:0 
...

Workarounds:

According to the mighty Stack Overflow this has been fixed in .net. Alas not in mono. We worked around this by creating a dummy temp data provider
public class DummyTempDataProvider : ITempDataProvider
  {
   IDictionary ITempDataProvider.LoadTempData (ControllerContext controllerContext)
   {
    return null;
   }
   
   
   void ITempDataProvider.SaveTempData (ControllerContext controllerContext, IDictionary values)
   {
   }
  }

And then making sure all controllers overrode the CreateTempDataProvider function (since all our controllers inherit from a common base, we just stuck it in there).
protected override ITempDataProvider CreateTempDataProvider ()
  {
   //return base.CreateTempDataProvider();
   return new DummyTempDataProvider();
  }


Using the nHibernate WebSessionContext leaks memory

Our application uses nHibernate for persistence. Unfortunately, for some reason we've not been able to identify, if you use the WebSessionContext (which is what you should be using for a web application), you'll find that you are, once again, leaking memory. 

Workarounds:

 
We found that the ThreadStaticSessionContext has no such trouble and - on a hunch - tested out a hybrid session context we had lying around from an earlier project. This works fine, no leaks. The only real difference between this and the WebSessionContext seems to be that our HybridSessionContext uses the Items hashtable in the HttpContext directly to store the session whereas the WebSessionContext creates a new hashtable inside the items hashtable which uses the ISessionFactory as the key to the Session. Why this should cause a leak is a mystery; it may have nothing to do with the leak. But it's the only obvious difference.
internal class HybridSessionContext : CurrentSessionContext
 {
  [ThreadStatic]
  private static ISession threadSession = null;
  private const string webSession   = "YourNamespace.YourProject.WebContext";
  
  
  public HybridSessionContext(ISessionFactoryImplementor factory)
  {
  }
  
  
  protected override ISession Session
  {
   get 
   { 
    return (HttpContext.Current != null) ? HttpContext.Current.Items[webSession] as ISession : threadSession;  
   }
   
   set 
   { 
    if (HttpContext.Current != null)  HttpContext.Current.Items[webSession]  = value;
    else         threadSession        = value; 
   }
  }
 }


The boehm garbage collector causes further leaks

After all that, you may still be seeing leaks. We've found that the boehm garbage collector that mono uses by default is rather easily confused, especially, for some reason, when it comes to web applications. 

Workarounds:

Try switching to mono-sgen, the generational garbage collector (see the link above). We found this moved us from a still inexplicably-leaking application to one behaving normally... while testing on xsp. Because...



mod_mono causes even more leaks

After all of the above were resolved, and everything looked peachy testing locally through XSP, we pushed the system onto a target machine and ran through mod_mono instead.... and got yet more memory leaks.

Workarounds:

Run through xsp and use mod_proxy to serve it via apache. And you'll get back to not having leaks.

To summarise

Currently, I'd say that ASP.net on mono is a bit of a mess. You can work round the problems to some extent, but we've spent a ridiculous amount of time dealing with them. Unfortunately the mono mailing list on this subject seems to have gone very quiet (Dan in the list is the other part of the "we" that I refer to in this post), and we're sufficiently out of time that we simply cannot continue to bughunt for the underlying causes of these issues without at least some support from folks who know their way around the guts of mono better than we do.

Monday, 13 June 2011

svn switch --relocate for a git-svn repo

Today, to my great annoyance, I discovered that if you're using git locally hooked up to a remote subversion server and you find yourself in a position where, if using svn only, you'd want to do svn switch --relocate ( for example, if the server has its address changed), git-svn presents you with a world of pain. Since the svn url gets baked into all the commit logs, and these are used to keep your git repo synced with the svn server, you can't just edit the .git/config file and change the url as you'd do for a normal git remote.

I'm not going to claim any credit for figuring out what the hell was going on; after a brief period of free-form jazz swearing at the machine with twenty-odd suddenly disconnected git repositories, I found a handy post explaining how to resolve this bloody annoying state of affairs.

Since I had a lot of repos to switch, I thought it best to write a little bash script to sort it all out for me. Here it is so you, too, can ease the pain of the unexpected subversion repository renaming with less hassle. Or, alternatively, utterly hose your repo. Seriously, this rewrites your commit logs and could do all kinds of the nasty. At least back up your local repository first before using it. And even then, you use it at your own risk, etc, etc:


#!/bin/bash
# git-svn-switch
# by Justen Hyde based on this blog post:
#
# http://translate.org.za/blogs/wynand/en/content/changing-your-svn-repository-address-git-svn-setup
#
# Use at your own risk. For the love of cthulhu, back
# your repo up before letting this loose on it.

if [ $# -ne 1 ]
then
  echo "Usage: `basename $0` {new subversion url}"
  exit -1
fi

if [[ $1 = "--help" || $1 = "-h" ]]
then
  echo
  echo "Usage: `basename $0` {new subversion url}"
  echo 
  echo " Changes the url of the subversion repository a git-svn repo is connected to." 
  echo " Analogous to svn switch. Potentially a weapon of mass destruction. Use with care."
  echo " Run this from within your git repo. You only need one argument: the new url of the svn repo."
  echo " git-svn-switch will attempt to verify that the url is at least a svn repo before starting the switch"
  echo " but don't depend on it to stop you from doing summat daft."
  echo
  exit 1
fi

# get the current subversion url
SRC=`git svn info --url`
if [ -n "$SRC" ]
then 
  FROM=`echo $SRC | sed "s|/trunk||"`
  REPO=`svn info $1`
  echo "Checking $REPO is actually a subversion repository..."
  if [ -n "$REPO" ]
  then 
    echo "The new URL looks valid."
    echo "Rewriting the git history with the new url..."
    SED_FILTER="sed 's;git-svn-id: "$FROM";git-svn-id: "$1";g'"
    git gc
    git filter-branch --msg-filter "$SED_FILTER" $(cat .git/packed-refs | awk '// {print $2}' | grep -v 'pack-refs')
#Couple of pointless checkouts - on some repos the log changes seem to need flushing by an operation like this
    git checkout trunk
    git checkout master
    echo "Rebuild git-svn internals and updating the repo"
    rm -rf .git/svn 
    sed -i~ 's|'$FROM'|'$1'|g' .git/config
    git svn rebase
  else
    echo "Error: $1 Does not appear to be a subversion repository."
  fi
else
  echo "Error: This doesn't appear to be a git working directory, or it's a git repo that hasn't been created using a git-svn bridge"
fi
EDIT: I've added a couple of checkouts to the script which don't serve any obvious purpose, just before rebuilding the internals. This is because I've found on some repos that for some reason git doesn't seem to notice the logs have been rewritten (git log shows you logs with the old address, but attempt to re-run the rewrite and git will behave as if the logs have been rewritten). Subversion seems to get the old version of the logs in this case, and so any operations trying to use the subversion address in the logs fail. Doing these checkouts seems to flush the logs properly and allow git-svn to behave as expected. Weird. Unfortunately, this does mean you have to have a reasonably standard repository structure (i.e., one that actually has a trunk that can be checked out) or the script will fail.

Wednesday, 27 April 2011

Templates, inheritance and nested classes

I've recently had a world of fun and confusion with a strange combination of templating, inheritance and nested class in c++. The error messages along the way were rather weird, so in a bid to save time in future, here's the story:

Let's begin with a pretty standard templated class. It does useful things to some data which it keeps a hold of during its lifetime.
template <class T> class Foo
{
  public:
    Foo()  { /*...*/ }
    ~Foo() { /*...*/ }
    void SetStuff(T *data) { /*...*/ }
    void DoStuff(T *data) { /*...*/ }
    T *ViewStuff() { /*...*/ }
  private: 
    T *data;
}
OK, now let's assume that we have a set of helper functions that are only useful with the data in Foo while it's in Foo, and which should never be used externally but are always used whenever Foo wants to do stuff with the data. So we'll define a little nested helper class and squirrel the data away in it:
template <class T> class Foo
{
  public:
    Foo()  { /*...*/ }
    ~Foo() { /*...*/ }
    void SetStuff(T *data) { /*...*/ }
    void DoStuff(T *data)  { /*...*/ }
    T *ViewStuff() { /*...*/ }
  private:
    class DataWrapper
    {
      public:
        DataWrapper(T *data) { /*...*/ }
        ~DataWrapper() { /*...*/ }
        void HelperFunction() { /*...*/ }
        T *GetData() { /*...*/ }
      private:
        T *data;
    }
    DataWrapper *data;
}
Note that DataWrapper doesn't need to be templated; that's taken care of because it's already nested inside a templated class. Now let's imagine that SetStuff and DoStuff aren't safe methods to call all the time, and that sometimes you need to make sure that you can only use the safe methods, like viewing stuff. We just need a FooView. Fine, let's make a base class of Foo that has a copy constructor and only provides the safe methods. Then we can just take a FooView copy of Foo which we know is safe to hand over for use elsewhere. We want FooView to be the base of Foo, which is possibly slightly counterintuitive, because Foo does everything that FooView does and more besides.

template <class T> class FooView
{
  public:
    //Copy constructor to allow us to create views of a Foo
    FooView(FooView & source) { /*...*/ }
    ~FooView() { /*...*/ }
    T *ViewStuff() { /*...*/ }
  protected:
    //It doesn't make sense to create a FooView unless we give it something to 
    //copy. The descended Foo class will need a default constructor, though.
    FooView() { /*...*/ }
    class DataWrapper
    {
      public:
        DataWrapper(T *data) { /*...*/ }
        ~DataWrapper() { /*...*/ }
        void HelperFunction() { /*...*/ }
        T *GetData() { /*...*/ }
      private:
        T *data;
    }
    DataWrapper *data;

}
template <class T> class Foo : public FooView <T>
{
  public:
    Foo() { /*...*/ }
    ~Foo() { /*...*/ }
    void SetStuff(T *data) { /*...*/ }
    void DoStuff(T *data) { /*...*/ }
}

DataWrapper needs to be in the FooView class since both Foo and FooView need to understand it, but nothing else should (perhaps it's code that would be unsafe if used outside a FooView object). So far, so simple. But as soon as we try to implement anything in Foo that uses a DataWrapper, we end up in a world of pain.

Our first problem is that inside Foo, the compiler doesn't understand what a DataWrapper is. Let's add an implementation to SetStuff:
template <class T> class Foo : public FooView <T>
{
  public:
    Foo() { /*...*/ }
    ~Foo() { /*...*/ }
    void SetStuff(T * data)
    {
      DataWrapper *wrapper;
      wrapper = new DataWrapper(data);
      this->data = wrapper;
    }
    void DoStuff(T *data) { /*...*/ }
}

...which will result in the compiler error "DataWrapper was not declared in this scope". The issue is that we're in a templated class and the compiler doesn't know where to look for the definition of DataWrapper (which is also in a templated class). So let's give it a hint:

template <class T> class Foo : public FooView <T>
{
  public:
    Foo() { /*...*/ }
    ~Foo() { /*...*/ }
    void SetStuff(T *data)
    {
      FooView<T>::DataWrapper *wrapper;
      wrapper = new FooView<T>::DataWrapper(data);
      this->data = wrapper;
    }
    void DoStuff(T *data) { /*...*/ }
}

Which is pretty ugly. And leads to the baffling error "wrapper was not declared in this scope".

Huh?

But... but... that IS the declaration of wrapper!

Somehow the compiler has become so confused by the templating and whatnot that it's totally failed to parse
FooView<T>::DataWrapper *wrapper;
as a declaration. It's trying to perform some operation on wrapper as if it were already declared. I've no idea what. If you switch T for a type, the problem goes away -
FooView<double>::DataWrapper *wrapper;
works fine, apart from being a bit totally useless. So it seems that the compiler has missed the fact that
FooView<T>::DataWrapper
is a type name. Fortunately there's a keyword available to convince the compiler that no, honestly, it is a type name:

template <class T> class Foo : public FooView <T>
{
  public:
    Foo() { /*...*/ }
    ~Foo() { /*...*/ }
    void SetStuff(T *data)
    {
      typename FooView<T>::DataWrapper *wrapper;
      wrapper = new typename FooView<T>::DataWrapper(data);
      this->data = wrapper;
    }
    void DoStuff(T *data) { /*...*/ }
}

This is clearly absurd. If you're using DataWrappers in many places, your code is going to end up looking like it's been beaten to death with an ugly stick. Fortunately we can avoid all that nonsense by using a private typedef inside Foo:

template <class T> class Foo : public FooView <T>
{
  private:
    typedef typename FooView<T>::DataWrapper DataWrapper
  public:
    Foo() { /*...*/ }
    ~Foo() { /*...*/ }
    void SetStuff(T *data)
    {
      DataWrapper *wrapper;
      wrapper = new DataWrapper(data);
      this->data = wrapper;
    }
    void DoStuff(T *data) { /*...*/ }
}

And now you can just use DataWrapper inside Foo the same way as you would inside FooView - and as you probably expected to be able to use it in the first place. Obvious, eh?

EDIT - The typename keyword exists specifically to address this sort of situation, according to the description here. I guess it's one of those things that you either know (and hence will understand why you get an error about an undeclared variable from a line which you think is a declaration) or you don't and will be totally baffled by. It's not an error message that helps you towards an understanding of the source of the problem, that's for sure!

Monday, 28 February 2011

Mootools and the Closure compiler

I (and Dan over at teadriven) have been battling with the Google Closure Compiler for a few days now. I say "we". As the more javascript literate Dan has been doing the vast majority of the work while I poke things with sticks and apply googlefu to trying to find solutions to problems.

The first interesting thing is that, if you search for information about how mootools works with the closure compiler, you'll find next to nothing. There's a very brief post from 2009 claiming that mootools + closure compiler "behaves quite nicely", and a couple of posts stating that you can only use advanced optimisations on closure if you've designed your code for it, and you know what you're doing. Setting the "you need to know what you're doing" part of it aside for a moment the implication is that mootools and closure don't behave quite nicely together at all. This tallies with what we've seen. Initially we were thinking we just needed to provide an externs file for Mootools and we were a little surprised that one didn't exist in the closure contribs. Then Dan started trying to make one while I blithely disappeared to try to fix my bike, which is a whole different story. A story punctuated with increasingly irate/despairing IMs popping up on my phone as the fundamental differences of opinion between Closure and Mootools started to become apparent.

We're nearly at a point where our js has been hacked to work, but it's not a case of having made Mootools and Closure work well together. And here's some of the reasons why:

  1. Javascript sucks at object orientation. Why is that a problem? Because there's no standard way to do object orientation in javascript. Mootools and Closure approach the problem differently. Closure requires javadoc tags to help it to parse the javascript correctly, and there's currently no tag that allows you to describe a mootools-style object definition. Therefore Closure doesn't like Mootools.
  2. Closure doesn't like you messing with Element. More accurately, it doesn't like you overloading the w3c Element. Mootools does overload Element (I know, technically it doesn't, it redefines it). Therefore, Closure doesn't like Mootools.
  3. There is no externs file for Mootools. If you want to use Mootools without compiling it in to your code, you need an externs file. Currently, none exist. Therefore, Closure doesn't like Mootools. Until the other problems are solved, there's no point making one which I suppose explains this.
The last problem is relatively trivial but the first two are real issues. For the first, the best way I can see around it is for the Closure compiler code to make explicit provision for the Mootools way of doing things, probably through a specific javadoc tag. I'm sure this isn't high up the priority list for The Google. We've pulled the source, though, so there's at least the chance we'll find the time to attempt to hack such a thing in. You can sort of hack your javascript into line, though.

To create a class in Mootools, you pass in an object of properties and functions to the Class function, which then spits out a new one of the things defined by the object you passed in. There's nothing there that's inherently wrong from Closures point of view, except you need to somehow tell Closure that this is a class instantiation based upon the object you pass in (it is expecting you to be a little more traditional and create a class with a constructor function which you tag with a @constructor javadoc). Closure is, therefore, confused by what "this" you're referring to inside the class. This can hackily be resolved on a case-by-case basis by liberal use of the @this javadoc tag, which is messy. It'd be much nicer to be able to tag something as a mootools-style constructor in Closure, and that would also allow Closure to understand the object inheritance tree (which is sort of broken with this hack).

As for problem two - again, I can't really find anything on the web that talks about this. I suppose nothing else (other than mootools) really tries to overload Element, so no one else has this issue. Not entirely sure why Closure protests, or how one is supposed to tell it that you're overloading/redefining Element and no, really, that's fine. I suppose going through Mootools and renaming Element as "Mooliment" or something could, potentially, be a workaround.

Slightly frustrating to have no definitive resolution to tail this post, but there's so little information out there about this problem at time of writing that even a "mootools and closure don't work well together" post seemed like a useful contribution of sorts.

Monday, 11 October 2010

Browser game development.

For the past....oooh, three quarters of a year? I and a couple of friends have been working on a little project in our spare time. I've played a few browser based MMPORPG in the past, and I've often criticised them. In some cases - such as the now-defunct Nexus War - because I've just enjoyed the game so much that the bits that I'd do differently become huge in my mind. In others, like Shintolin it's more that I'm frustrated that the developer seems to have lost interest before an interesting concept has really reached fruition. There's also an element of arrogance, I suspect, in that I know best and all these people are doing it wrong (that's almost - but not quite - entirely a joke). Of course, it's easy to be a backseat coder so earlier this year I, with a couple of like-minded, foolhardy friends, decided to put my build chain where my mouth is and write a browser game. I liked the idea of a stone-age sandbox-y game so, with apologies to Shintolin, began work on a project currently bearing the working title "Henge".

There're quite a few things that I've learned along the way - work on the game has seen my try out (and hate) Seam, has seen me tinker with and discard Eclipse, Netbeans and ultimately Java itself. Which is noteworthy mainly because part of the motivation behind this project was to learn Java. Ho hum. On the other hand, my game has definitely been raised in the C# stakes - I've moved from rather disliking the language to an appreciation that it is, in fact, fricking cool. I've learned a lot about NHibernate, which was really handy for work. Sadly, despite it proving extremely useful for non-Henge purposes it became apparent (at least to two thirds of the team) that even with NHibernate, a SQL database was forcing too many compromises on us, so we ditched it almost entirely in favour of db4o. My word, there was a decision that led to a ludicrous amount of work. On top of that, Henge has allowed me to get to know and to love git. I've moved from cvs to subversion to git over the years and each step has been a massive leap forward. As much as I've championed subversion in the past I have to say - these days, if you're not using git you're almost certainly doing versioning wrong.

And after all that - and a lot more - we still don't have a playable game. As it stands at the moment, you can create a character, walk around a map, starve to death and drown. But it's getting there. There's an awful lot of architecture in place now. Hopefully one day you'll be able to play it and see what all this effort has been for. But one of the big things this has shown me? All those one-man bands who managed to design and build their own browser game, from the sophistication of Nexus War to the simplicity of Urban Dead and even the semi-complete mess (sorry, really I am, but look at the code. It needs a rewrite!) of Shintolin... they all all managed to do an amazing thing. Getting one of these things up and running is bloody hard work. Or, at least, that has been my experience of it so far.

Hopefully I'll find the time and motivation to write a little more about the design of henge before I forget too much about it; it's already started to happen - there are things that I've had to spend a long time figuring out twice because I forgot why we did them the way we did them in the first place. If not, I hope at least to get enough working to let some people poke it with sticks until it falls over.

Updating a Samsung Galaxy S i9000 the "official" way

Before we start, I'd say that going through this is beyond painful. The only reason to do it this way is if you particularly care about being able to claim on your warranty with Samsung if things go tits up. That or a sense of bloody-mindedness.

What You Will Need:

  • One i9000 (rooted or not shouldn't matter, but you'll probably need to be running stock firmware. For the record the one device I've got this working on was running stock, Orange-branded firmware, was not rooted but was SIM unlocked).

  • One Windows machine, physical or virtual. I was running XP pro on a VMWare virtual machine in an Ubuntu host but also verified every step except actually blowing the image on a physical machine; they behaved similarly. The VM was, if anything, a better experience than the physical machine. All windowses involved are 32bit, ymmv with 64 bit (I have seen reports of problems running on a 64 bit machine).

  • Patience.

How To Make The Damn Thing Do What It Should:

First, Install Windows Media Player 11. If you don't have this, one of two things will happen. Either kies (the samsung piece of crap you're about to use) will simply refuse to install or it will install perfectly happily, but will be unable to communicate with the phone. The symptom of the former is that the install process will hang waiting for a .cab file to be downloaded (sitting at 0% progress) and then abort with the error message "Installation Aborted". The symptom of the latter is that when you plug your phone in to the machine ready to connect to kies, Windows will detect a new MTP device and begin installing hardware but never complete the process. Should you end up in this state, just press the home button on your phone and disconnect it. Windows will eventually give up trying to install the hardware and tell you that it may not work properly. I've also noticed mysterious shutdowns happening on the phone a couple of minutes after disconnecting it when this second situation occurs. You may need to yank the battery to bring it back to life since the phone may well not respond to the power button.

If you've already hit either of the above problems but haven't installed Windows Media Player 11, you don't need to uninstall kies - just install WMP 11. You'll need to reboot the machine after installation, but then things should begin to work.

Now download Kies and install it. I used version 1.5.3.10093_80. When Kies starts up it may ask you to let it update itself (or it may not; on my VM it didn't on my physical machine it did). I didn't manage to get it to work after updating, though that isn't to say that it wouldn't; simply that I hadn't figured out all the rest of the workarounds yet. Regardless, you can certainly update your phone without running an updated kies. It's up to you if you want to take a punt and update. Close Kies down again and open up the registry editor (enter "regedit" into the Run... dialogue on the start menu). You need to add two registry keys in order to stop the firmware update software from recursing its way into a stack overflow as it tries to look for them when you start the upate process:
  • In System/HKEY_Local_Machine/Software/Samsung add a new key named FUS
  • In System/HKEY__CURRENT_USER/Software/Samsung add a new key named FUS
Close the registry editor and restart kies. If you don't do this, the firmware update will stall at 0% trying to download binaries, and eventually you'll get an error message about MSC.Thunder.FirmwareUpdate running out of memory. If this happens to you don't worry; the updater hasn't actually started doing anything to your phone yet. Once it's crashed you can just unplug your phone.

Over to the phone now: Switch your phone to Samsung Kies mode in the USB settings menu (which is hidden inside the "About Phone" menu in the main settings menu) and switch your launcher to TouchWiz or Kies won't play nice. I set it as the default for the upgrade, just to be safe. Navigate to the homescreen and plug your phone in to the PC. If you're lucky, you'll get the MTP screen up on the phone with the message "Initialising" shortly followed by "Connected". If you're unlucky your phone will, at this point, go mental and start rapidly switching between the homescreen and the MTP screen. In this case, unplug the USB cable and go on the phone to settings->SD card and phone storage->Internal SD card. Unmount and format the internal SD card. Plug the phone back in to the PC, and you should get to the "Connected" screen. Kies should now see your phone pretty quickly, and offer you a firmware update (if one is available). It should be plain sailing from this point, just go through the update process marvelling at the incomprehensible language used in the dialogues. Don't mess with your phone at all until the update is complete.

Once the update is complete, your phone will sit on the S splash screen for what seems like an age. It'll also be extremely unresponsive after it finally starts up. I assume it's doing some book keeping behind the scenes, since this will pass after a short while.

Saturday, 14 November 2009

Hiding in the attic

I'm hiding in the attic at the moment. I'm not cool with other people. Any of them. Which is really fricking weird, because almost everyone I know is at least a bit lovely. I know that. But I'm still hiding in the attic.

I'll get over it in a bit, I guess, it's really not that much of a big deal - but earlier today, in the middle of the village I live in, I nearly got into a fight in the street. It's so weird. More than a little my own fault, I guess: Two youths were walking along the street, and one of them said something along the lines of "alright, ginger" to me, and barged me for no good reason. I can't remember what I said exactly, but something along the lines of "what the hell was that for?".

All a bit of a blur after that, but I end up standing with some scrawny teenager doing the aggressive talk thing about me in some way "acting like the big man, innit"so close to my face that the tips of our noses touched. I guess I was supposed to back off at this point, but I'm strangely not that bothered by the proximity thing (I guess years of jitsu took care of that) so despite being properly freaked out, the only thing not really bothering me is how close he is.

I'm having trouble at this point understanding what the hell he's saying between the "innit"s - seriously, it was probably English but I have no idea what he was saying. I think he wanted me to start a fight with him or something, or he was threatening to beat me up, or... something. In broad daylight. In the middle of the village. What the fuck. What. The. Fuck.

So aside from "what the fuck?" I don't really know what to say to him... I'm certainly not going to hit him unless he attacks me, mostly because I'm a wuss and partly because I'm enough of a wuss that if I *do* have to hit him I'm not going to dick around playing nice; I'll be going for his eyes, windpipe, groin and (given the opportunity) stomping on his knees. Which is going to get me in Deep Shit. And I just went out for a walk on a Saturday, and my brain is swimming in What The Fuck??? and I'm having flashbacks to school, and on top of that I can't get over the incongruity of the situation, that someone so much smaller than me is trying to get into a fight with me, and they're treating me like I'm someone to be bullied in the playground...

So I gave him a hug. Prizes to anyone who can figure out what on earth possessed me there.

Strangely, this didn't effortlessly defuse the situation. It did seem to freak him out, and then piss him off even more (so now there were accusations of both gayness and molestation hidden in the mostly unintelligible stream of noise coming out of his face-hole). Back to another round of him mouthing off and me, basically, saying "what the fuck??" over and over. I think this, combined with my squeaky terrified/exasperated voice, may have blown my chances of intimidating him into going away. Eventually he plain came out and demanded that I hit him if I was, indeed, such a big man. I pointed out that of course I'm not going to hit him. I think that was taken as a submission, because he started to proceed Fucking Off To Buy Booze at this point, slowly, shouting threats at me still while I (positively drunk with confusion now) told him that he was welcome to hit me, but I wouldn't be hitting him back (this bit would be a lie; I don't know that I'd have gone apeshit had he hit me, but I don't know that I wouldn't either). I suspect perhaps the evil bit of my subconscious had, at this point, noticed the CCTV camera pointed at us and wanted to give him every opportunity to get nicked.

So then I went home, a bit shaken up. Just a bit, so I thought. Except I now don't want to see any people again ever and would prefer to live my life sitting here at the keyboard and never go out. This is not the response of a sane and rational mind. Now it's out in words, though, I feel considerably better. I suppose writing about things really does help.

...That plus I totally gave his description to the police. Little bastard.

Thursday, 8 October 2009

Follow me!

Despite my often-stated Not Knowing What I'm Doing, sometimes friends are around who want to play on bikes and there's no-one with The Know kicking around to assume a position of authority and show us where to go. Since I live here, naturally I'm the fallback leader in such situations (and I hope the idea of me leading a ride even of only two people amuses you as much as it amuses me). I have to say, I think that due to lack of planning on my part I can't really call the two expeditions I have under my belt complete successes, but I think there was more success than fail.

The first one was with Ian (hi, Ian!) who got the train over to Oxford a couple of weekends ago. I managed to start this one pretty badly by being late to the station. D'oh. Apologies out of the way, I made some more apologies pretty quickly: I hadn't found the time to ride all (or even most) of the route before, and some of it was a complete guess as to whether it was rideable or not. There were definitely rideable and fun bits in there that I'd been to with the club, but there were also some sketchy paths that were marked but for all I knew could be ploughed fields. Plan B was to take roads to the bits I was more confident about being both rideable and easily findable. But Ian was cool with exploring and, hey, we had all afternoon. We set off up the Thames path in search of a pub to get some lunch from. The Thames path runs from pretty much round the back of Oxford station to the edge of the village, and while it's flat (being a path next to the Thames what else would you expect?) it's still more enjoyable than riding along the road. The weather was glorious, so the ride up from the station to the Trout was extremely pleasant. We stopped off at the pub, ordered some burgers (tasty) and chips (so-so), and had a chat about where we were headed. Since we'd have another five miles-ish of riding along the river, we figured digesting wouldn't be a problem.

After lunch as we left the more well-travelled part of the path, the realisation hit us that the ripply floodplain surface of the ground, baked by the sun over a fortnight of no rain, was going to prove a bit of a boneshaker. Not a fun boneshaker. Just a bit sapping. On top of that, the sun was just unbelievably hot. It was a great relief when we got back into the shade of some trees. Reaching the 'Sham, we cycled straight through to Chill Bridge Lane, and off the end of it onto a bridleway which connected us up to a minor road west of the village. Not a particularly interesting bridleway, and honestly I can't remember anything about it at this point. Apart from it'd been diverted down the edge of a field on one section. Once on the road again we were looking out for a right onto one of the total unknown tracks on the map. We found it... straight over the middle of a field. It wasn't so much a trail as a line of cleared vegetation across a once-ploughed (and baked solid) surface. I take back what I said about the thames path being a boneshaker; this really, really was. Didn't last too long before getting into more of a trail, though, once we were across the field. It didn't seem well frequented by anyone except horse riders though, and the terrain really didn't smooth out that much. The surface was just about dry, and I guess at any other time of year it would've just been a mud bath. Again, not so much fun as hard work, though. Out of the other end of this, we had another short section of road before picking up the next path - or so I thought. We took one look at the nonexistent path and decided to make for the next one along. And then we did the same again. Third path along, we decided to have a go. The problem was, the actual route of the path was... ambiguous. We set off up a likely looking trail that seemed approximately right only to find it terminated in a dense thicket. Bugger. Looking down across the field next to us, it seemed there was a gap in the hedge... so back we went to the start of the path and tried again, going the opposite way around the field. Again, no joy. I got off and had a walk... turns out the path runs directly through the middle of the field. Bah. So we plodded along the edge, through the gap, and then round the edge of the next field onto the path leading up to the road. Here we were planning to cross over the A40 and go on a bridleway past the western side of the parkand of Eynsham hall. Cleverly, though, I chose this moment to notice the wide variety of thorny twigs I'd managed to collect in my tyres. My back wheel was fine, but pulling the thorns from the front rewarded me with multiple hisses. I was packing a couple of spare tubes, though, so all was well... Until we found that Ian had two flats, no repair kit and only one spare tube. And needed tubes with different valves to me.

Toss.

I hightailed it back along the A40 to Eynsham to the magic hardware shop to buy more tubes, and Ian followed as best he could. The shop was crazy busy, so it took me a while, and as I headed back out of the village with the spares, I met Ian on his way back. We replaced his other tube, and decided not to bother going back out to another potentially unknown bridleway and instead to take the roads up to Stonesfield to go to the quarry I've written about before. We got up there, belted down the bridleway, crossed the river and climbed up through the wood to the top of the quarry I've fretted publicly here about riding before (from the opposite side to the one I first rode). From behind me, I heard the sound of quiet expletives. Apparently, it looks one hell of a lot bigger in real life than in photos. To his credit, though, Ian rode it. After a brief stop in the bottom of the bowl to look up and marvel about our continued survival, it was time to head down the rest of the descent - which for my money is actually more worrying and difficult than the chute. It's a longer but shallower (still very steep) slope which ends in a sharp left. If you don't make the turn, you plough straight into a fence. Since it's longer you have plenty of room to balls it up, and you actually have to control the speed of the bike so you can make the corner at the foot of the slope - and on top of that, it's quite a loose surface, so you don't get that much grip when you start braking before you're skidding down the slope rather than rolling down it. A brief run along the foot of the hill, and we climbed back up and round to the quarry again, this time from the opposite side. From this approach, the descent after the chute is longer, smoother, straighter and much more zoomable. So rather than stopping, we just flew down, through the bowl without stopping, and down the trail back out of the wood and to the bridge over the river in a lovely, flowing blast. We went back up the bridleway we came down, headed back into East End, and picked up the bridleway across to Hanborough. This is a nice, undulating trail - not amazing, but pleasant. As we reached the other end, Ian ran out of water and we noticed the light was beginning to go. The time had come to head back to the village on the roads, and then on to Oxford so Ian could get the train back home.

I must confess, one of the other problems with not planning the route was the unexpected length. Over 30 miles for Ian and probably about 40 for me! Oops. I promise I'll plan something saner next time!

This Wednesday I had my chance to rectify some of my poor route choices, as Claire had agreed to come over for a ride. After we'd arranged this I found out that I had to be in the office in the day, so we were looking at doing the whole thing in the dark. This was a bit of a worry for me, since I'd be leading and still (still!) failed to go out and properly figure out the route beforehand. I was planning to stick to stuff I'd ridden at least once before (if not necessarily in the same direction), though, so I thought the worst case would be the occasional overshoot, missed turning or accidental cutoff of interesting sections.

Wednesday came, and I found that the main feature of the ride was not to be my dodgy guiding, but instead Mud. After three weeks or so of little-or-no rain, it absolutely tipped it down all day. But, we'd done Arranging and everything, so off we went. I decided after the ride with Ian that nothing south of the A40 was really worth the effort, and curious to ride the bridleway by Eynsham Hall that I'd planned to go up with him, we headed out on the cycle path alongside the A40. I'd been down the trail we were heading to a couple of weeks previously after a club ride - they pointed me down it as they were heading off back to Witney with the advice "watch out: there's a couple of muddy, rutty sections, so don't go too fast. Other than that, it's fine. Oh, apart from the deer. Try not to hit any deer." I hadn't found it too bad, though there were indeed some muddy sections even after all the good weather and the ruts were definitely worth being wary of. So on this occasion, I was hoping that the mud hadn't become too horrific. It was certainly tougher going; between ruts and roots and mud, the bike was sliding around a fair bit, and there were a couple of points where going slightly off-piste was the only viable choice. I was finding it pretty fun, though. Claire was... maybe not having so much fun. Despite having a much more expensive lighting set-up than me, it wasn't working so well. On top of that, she seemed to be having more trouble with the mud than me. I dunno if that's because I've ridden on more mud or because of her bike (fancy full-sus affair, but something was amis with the drivetrain; she was having trouble with it jumping gears unexpectedly from time to time). The trail climbs gently from a farm, rolls down for a while, then climbs back up to the road. Very very light gradients, but still a reasonably fun route. I think I actually preferred the muddy version, oddly.

At the end of the bridleway we popped out of the woods onto a road, crossed it and cycled through North Leigh. I was pretty sure I could spot a short trail that would connect us up to East End as we went - and I did! Woohoo! Now, with the club this route drops into a bmx park someone's made in the woods, but somehow I managed to miss the turn (I think this is near where the steps I've ridden down are, but I didn't find those either) and we ended up on a trail next to, and slightly above, the park. I suggested we drop down into it, but Claire preferred to keep on the route we'd hit, so very shortly we were out of the wood and crossing the road to East End common. There's a twisty maze of trails round here, and I'd sort of planned to go deeper into the countryside and curve back to join the route I took with Ian down to Stonesfield, but in the dark and wet I missed a right - possibly after the annoyance of finding that my shifter was on the blink and only pulling cable when it felt like it - and instead joined the road again further down East End after a fun ride along an undulating turfed trail and some nettley singletrack. So instead, we just followed the road to the head of the bridleway. I'd not ridden down it in both dark and wet conditions before, and the zoomy fun became a little more worrying, with a wide variety of unpredictable-depth puddles. I unfortunately ploughed into a deeper example about two-thirds of the way down which scrubbed a good deal of my speed off. We regrouped at the bottom of this section to go through the gate and onwards down the hill alongside a field and over to the bridge. We heaved the bikes over the style, and crossed over to the woods. Now, it's not exactly the easiest of climbs up this side at the best of times. Totally doable, and not that long, but you definitely feel like you're working at it. Claire decided to walk the first, steepest section, and about halfway up, so did I when I realised I was pedalling and the wheels were going around, but the bike was going backwards. When the slope slackened off somewhat, we got back on and continued, but the bikes were trying very very hard to slide sideways off the trail and down the hill - especially with their tyres all gooped up with mud and slicked even further with wet leaves. It soon became clear we should probably just walk some more. So we did, until we got to the level top of the slope. From there it was an easy ride to the top of the old quarry. It's becoming quite the old friend, wouldn't you say? Claire really wasn't keen to ride it - and given the conditions, I can't say I blame her. And whilst I was happy to ride the first, steep section, the longer descent to the sharp corner was definitely giving me pause for thought, what with the traction issues I'd been having already. Not like I had much choice; it wouldn't have been at all right to hoy off into the darkness and leave her to find her own way out of the woods! Instead, we walked around the top of the quarry to the opposite side, and started to ride down the rockier, rootier trail that we would've used as our climb back up to the quarry for our second run at it. I'd never ridden down this, and was delighted to find it was really fun. It's a shame there's no way to use it as a descent without either walking around the top or going up and back down it. Part of the way down, Claire spotted a much smaller bowl with steepish sides (maybe two-three feet deep?) that she thought looked more doable. I needed to change my batteries, so I suggested we stop here while I do so, and then we could both try rolling into it. I went first, and apart from a very leafy, loose roll-out at the bottom, it was nice and easy and safe feeling. Probably a good taster or warm up for someone not prepared for the big steep rolls further up the hill. After a little encouragement, Claire went for it, and rode it with ease but declined to go back for another run at the big 'un. I think maybe better weather conditions would have made a different story (it was tipping it down the first time I came here, and it really helped to freak me out). We rode down the rest of the trail, and out onto the road. With all the walking on the last section, it was now far, far later than I'd expected, so we pretty much just had to crank it home along the road - so the second half of my planned route was a write off. I think, honestly, that given the weather much of it would've been a mudbath and not so much fun anyway. I spent a few minutes butchering a map with a colour-coded guesstimate of the route (red = planned on-road that we rode, blue = planned off-road that we rode, brown = unplanned on-road-ness, yellow = planned off-road we didn't ride, green = planned road we didn't ride):

Professional, eh? You should probably definitely not try to use that as a workable map, by the way. Much of it was drawn by me going "er... well I know there's a trail somewhere there that connects up to somewhere over here..." and so some of it (especially the yellow sections) are Highly Dubious.

So, what have I learned? Mostly that I should plan my routes more! Also, I don't know my way around that well still. But it's getting there! By next summer, hopefully I should be able to give any visitors a reasonably entertaining tour provided they're not expecting anything too adrenaline-y or technical - and there's a couple of bits of trail further to the North West I'd like to link into a bigger loop like this, I just need to figure out how to do so (and where exactly they are). Thanks to Ian and Claire for coming through and putting up with my dodgy route planning - I had a lot of fun, and I hope you both did too!

Tuesday, 6 October 2009

Dear Jim...

Dear Jim,

Will you fix it for me to know why we have such stupid, restrictive laws in England which prevent cyclists from using the vast majority of the public rights of way network?

Someone pointed out to me that you no longer actually promise to fix it, so I sent a letter to my MP too, some chap called David Cameron:


I was wondering what your position is (if any) on the right of access to the countryside by cyclists and specifically a change in the law allowing cyclists to use footpaths. As it stands, in England cyclists have access to only about 20% of all public rights of way, with the vast majority being footpaths and therefore off-limits no matter that most footpaths are perfectly suitable for cycling along. When compared with the Scottish system (cyclists and walkers sharing all the same routes with no discrimination), the English legislation seems needlessly proscriptive, and given it's an aim to get people more active and to use sustainable transport more, seems positively obstructive for no good reason. Provided that cyclists are required to cycle responsibly (as in Scotland), I don't see any rational argument against allowing them to use footpaths. Bicycles don't cause any more erosion of trails than walkers do, and judging by the Scottish system, even near major cities such as Edinburgh cyclists and pedestrians seem perfectly capable of co-existing on the same paths without trouble - as they already do on bridleways and other byways in England. Just not footpaths, for some arbitrary reason.

I should make it clear I'm talking about right-of-way footpaths only, not pavements next to highways.

Some background information:

http://www.ctc.org.uk/resources/Campaigns/0604_DMox_NCAF_Future_of_Cycling_final.doc

http://www.ctc.org.uk/DesktopDefault.aspx?TabID=4632

Thanks for your time.

Yours sincerely, etc.


Imagine my glee when I got a reply in a fancy Houses of Parliament envelope!


Thank you for your email dated 16 Septmeber 2009 about changing the law to allow cyclists to use right-of-way footpaths.

I can understand why you feel the current system is unfair to cyclists. As you mention, whilst legislation currently allows cyclists to use bridal[sic] paths, they are not permitted to use right-of-way footpaths, which are reserved for pedestrians.

There are problems with changing existing legislation to allow cyclists to use all right-of-way footpaths. Whilst many of these footpaths may be suitable for cyclists, others are not and allowing cyclists to use them could have significant safety implications for both themselves and pedestrians.

I do certainly think that local authorities should encourage landowners to volunteer to allow cyclists to use footpaths that run through their land. Similar initiatives have been used successfully around the country, and I believe this is a more cost-effective, local solution of opening up the countryside to cyclists.

I am a keen cyclist myself and encouraging people to cycle more will be a major priority for a future Conservative Government. My party will reform the much-criticised Transport Innovation Fund, to free local authorities to use £200 million a year to encourage the development of new green transport schemes such as cycle routes and corridors. These measures will help improve road safety and promote cycling as a safe alternative means of travel.

Thank you again for taking the time to write to me.

David Cameron


So, first of all, thanks to David Cameron for taking the time to reply. But I don't really agree with any of the reasons he gives for maintaining the status quo. I'll get my thoughts in order, then post my criticisms in a bit. I may even write back (not that I think it'll do much good), so if you have any evidence/arguments you think I should include then let me know. Or, if you particularly want to, write to your own MP. Yes, even if you're in Scotland, since hilariously your MP in Westminster gets to have a say on English laws even if my MP doesn't get a say on Scottish laws.

Tuesday, 1 September 2009

Darkness

Hot on the heels of the weekend expedition, I got an email just before finishing work today saying there was a club ride tonight, 7-9. The first of my lights arrived the other day, and this seemed to be the perfect time to try them out. The club always seems to ride the same routes (so I was told) so I knew at least that despite the dark I'd be covering ground I'd ridden before.

Due to the late notice, though, this was going to be another ride without any food beforehand. I grabbed the crust of bread we had left over and bolted it down while I nipped over to the co-op with my shiny pound coin to buy a couple of chocolate bars. I scoffed one as I jogged over to the garage, got the bike out, and headed over to Witney. It's about six miles from the garage to the meeting point, and I had a whole 20 minutes to get there in, against a headwind. So once again, the trip started with a manic dash to catch people before they set off without me. Fortunately I made it just before they left, and with the briefest of greetings we were off to get out of town. The guys were in such a hurry to be off I didn't have chance to strap my light to my helmet, but I figured there'd be time for that later - it was only just beginning to get dusky. And we wouldn't get to anywhere wooded for a while yet.

About five minutes later, we turned left. In itself not unusual, but we'd never been down that road before when I'd been out... and why was everyone tanking it so fast? Oh well, head down, zoom along after them. Probably just eager to get to some fun stuff. Soon enough, we turn off the road... straight onto a wooded track. Arse. Oh well, still not that dusky, I should be fine... ooh crap, why is my bike sliding all over like a demented thing as I ride?

Turns out this track is strewn with lots of pebbles. Everyone slowly pulled away from me as I struggled to bully my legs into picking up more speed with the promise of chocolate as soon as it feels like I'm more than 50% in control of where the bike's going. Zooming out of the track and back onto the road, the two folks in front of me bunny-hopped up the curved curb ahead without breaking their stride. Determined to keep up, I do my best to do the same, and happily despite my failure to time it anything like right, and a gut-wrenching sideways lurch as the back wheel and the curb meet, I'm up and over and all is well.

At about this point I figured out it was likely that I wouldn't be having the easy ride I was hoping for. And then we turned into the jumps someone had cunningly made in the woods. I'd fallen a bit behind the two lead bikes, with the other guy behind me, and had no idea this was coming. I couldn't see their route through it, and we'd joined the run sort of in the middle. I figured out what I thought was sensible line through it all and just in time realised that if I carried on the way I was going, I was about to hit a deep double at the perfect speed to plough into the other side. Somehow I managed to squeak around it (and so did the chap behind me, who had also not noticed what we were riding into). Commenting about it later, it turned out the other two had ridden across and round the jumps - i.e., gone the sensible way. Oh well. Quickly we were on to the next bit, and another new experience for me: Going down steps. A flight of about six of them. The two lead guys shot off down them, and as I did a slow turn in the clearing before the steps to clip in, the final one of my companions disappeared down the gap in the foliage. I figured it was probably a bit late now to ask advice about how to ride them, got my weight back, dragged the back brake and with a mutter of "ah, screw it" went for it before I had a chance to think better of it. About three steps in I realised the suspension was working harder and harder each step... I was hoping I wouldn't end up running out of spring and pitching over the front bars, which felt ever more likely, and then with great relief, I got to the bottom and hared off after the others. A short run of roads and we were on a nice, zoomy, undulating turfy path with bumps just begging to get you a little air. I wasn't really expecting this, so squandered it for the most part (next time, maybe...).

I was beginning to get an idea of where we were now... just coming to the top of the rocky bridleway I mentioned last post. It seems we were now back on ground I'd actually ridden before, but doing it the opposite way. I was amazed at the difference in character going down compared to going up; what looked trivial features when climbing seemed to have grown over the past couple of days, and the gentle-ish climb was now a fairly speedy descent. I think it was down here that I managed to jump in the wild for the first time (if I actually got both wheels off the ground, that is). And nearly fell off; I really have to stop turning the front wheel while I'm in the air.

As we got to the bottom of the hill, a sinking feeling came over me. We were heading to the woods near Stonesfield again, where I'd been out alone at the weekend. I had been looking forward to this, but it was beginning to get really dark now... and we were going at it backwards. So I'd be going down the other side of the hole... bigger, steeper, rockier and new to me. In the dark. Eek.

I finally got my light fixed to my helmet at this point, crossed the river and into the half-light of the wood. The climb up this side was much much steeper than the route I'd taken before, which was probably good - I had no time to worry. At the top, the guys asked if I was up to riding down, or if I wanted to go round. It couldn't be more worrying than the steps, I thought. Ah screw it, lets go. Dropping in from this side sets you up for a jump at the bottom, and the guy in front of me got some monster air from it. My standard issue inability to plan my exit line well meant I missed the jump. But I made it down, no crashes, feeling pretty comfortable. Result!

The next section, a sweeping downhill through the woods to a sharp turn at the bottom was, if anything, more worrying than what I'd just ridden; it was properly fast. I didn't feel like I was shedding enough speed, but wasn't keen on hitting the brakes any harder. What to do? Turns out I had slowed down plenty, and made the turn with just the slightest skid (I should emphasise that everyone else did it much faster than me - the wuss is still strong in me). A twisty turny climb back out to the entrance to the wood, and we were back on the road for a bit. It was now getting properly dark as we hit a more protracted stretch of road riding, and my light got dimmer and dimmer. As soon as we pulled onto the next bridleway, I stopped to switch batteries. The next section is a bit of a blur to me... it wasn't boring, just nothing special as we trundled along the sides of a couple of fields. Soon enough we were in Hanborough and one of the group was turning for home.

Not the rest of us though. Time for the last wood of the day - Pinsley. Much flatter than the others, but much bigger, and with the feeling of the speeder bike sequence from Return of the Jedi as you weave around the trees - especially in what was now completely pitch darkness aside from our lights. I was trailing the two experienced guys relatively slowly now - I couldn't figure out how they were even able to follow the path at the speed they were going, much less negotiate the roots and stuff. If I didn't have their lights to follow, I'd have been totally lost pretty quickly. Just before the bomb hole run in the middle of the wood, we stopped and turned out the lights just to appreciate how dark it was. And then onto the main event: Two bomb holes, in succession, with a slight dip and turn between them. Going down the first one in the dark was a fantastic experience - just hurtling into pitch black and then the trail appears in front of you from nowhere like a wall as you hit the climb out the other side. After the second one, you just have to turn around at the top and head back through them. Whee! I got totally freaked out by hanging ivy as I hit the bottom of the last hole on my way out; in my peripheral vision I thought it was a branch, and swerved madly to avoid it. Lost my momentum, and had to walk the last part of the exit. Oh well. Unfortunately as we left the wood, I made exactly the opposite mistake - what I thought was ivy was a branch. I ducked as the trailed dipped under it, but forgot that I had a light on top of my helmet, meaning I was taller than I thought. Didn't hit it too hard, but enough to be a warning not to make that mistake again in a hurry!

Then we were out of the woods, and off towards the roads home. I got back about three hours after setting off, starving, and elated to have been out on my first ride in the dark and to have managed to nerve myself up to trying everything I was presented with. Riding at night is such a different experience; it's nerve wracking as things leap out at you from nowhere, and trails you think you know take on a different character but also really, really beautiful. Even though you can't see much. A great experience.

Then I got home, et tea and wrote this. Then probably went to sleep.

Sunday, 30 August 2009

Fear

Having chilled the hell out after last post, I was inspired by Iains comment to get off my whiney arse and just find some fun. I mean, if he can provide options from the other end of the country I can surely just grab a map and go looking, right? With a couple of hours to spare, I was sure I could at least try to figure out a reasonable route to and from one of the near-ish bits that I'd been shown by the local club. I did have another motive, too: The big hole in the ground near Stonesfield scares me. I'm not even close to going down the Big Side of it, but even the not so huge drop terrifies me. Until this expedition, I'd been there twice with the club. The first time it was dusky and rainy and very very wet. It was my first time out on my bike. I'd set off without having had chance to eat anything that evening, and we reached the woods about an hour and a half after I'd set off from home. I was already shaky from hunger, and by the time we'd climbed up through the woods (about 5 minutes of fun) to the main event, looking down it there was just no way I was going to ride it. None. I made my apologies, and one of the guys showed me the way around.


Second visit, again with the club, was at least a sunny evening. There were a few more people around, and as we rode up through the woods I could feel the apprehension growing. By the time I got to the top, I was absolutley bricking it again. This time, I was determined to ride it. I know in my head it's not that big, and it's not that hard. Just keep my weight back, hands off the front brake, let the bike do its thing. It'll be fine. Plus, you're at the top now. Too late to turn back. Nice one! You've totally fooled yourself into going down! Ahahahahaaa!

Unfortunately I was so caught up tricking myself into actually trying it that I hadn't bothered to check out how to ride it out once I reached what I thought was the bottom. It's not, there's another much moroe gentle drop after it that you need to turn into. If you don't turn, you end up ploughing straight into the other side of the bomb hole. Straight into a wall of roots. Which I did, then fell off and spent the next five minutes changing the inner tube that I popped with my crash-stop.

So, on the whole I'm feeling a bit better about it - hey, I mostly rode it. I actually got it together enough to try it. But, if I'm going to be honest, I didn't really ride it. It was a mess, I didn't have my head together, and mostly I just chucked myself over the edge before I noticed. And I'm not really feeling that much better about it... It still scares me. A lot.



So. The only sensible thing to do is ride it more, right? And now, with my determination to go out and ride is the perfect time. Perfect. I'm a little worried about going out by myself, but I'm pretty sure that I'm not going to manage to mangle myself that much if it goes wrong. So I tell myself as I talk myself into going.

Now, it's a fair ride out there, mostly on the roads. I'd spotted a byway that looked like it might get me a bit of the way there with some stuff to keep my mind occupied on the way, but when I tried to ride it it turned out to be pretty much impassable due to the four-foot-high nettle and thorn beds that had grown right across the track as far as the eye could see. I struggled through it a little way in the hopes it would clear up, but it seemed like a hopeless (and painful) job. I turned back, and resigned myself to just following the roads for half an hour. The whole time, I could feel the apprehension rising. By the time I reached the woods I'd worked myself up to a ridiculous state. I really, really didn't think this was going to go well. But I realised that if I turned back now, this was just going to get worse. A brief text message to some friends (just so I didn't feel like I was as alone as I actually was at this point), and I began the climb.

By the time I got to the top, I was feeling physically sick with apprehension. But screw it, I came this far. Time to do it. Weight back, off the brakes, check the exit line, pretend like you want those roots to be there... GO!

...and I made it. The adrenaline rush, having worked myself up so much, was just insane. I was whooping like I'd just pulled the most insane stunt in the world, not ridden down something that - honestly - isn't really worth fretting about as much as I had. Now the big drop, over to the left... yeah. Maybe one day.

Here's the top bit:
I went down the leftish way (right as you look at it) - over the roots, not down the way my bike is blocking in the picture.

After that, I settled in to a nice hour of pootling around various bridleways on my way home. There's a fun rocky trail up to East End past the site of a roman villa which, while easy, at least feels like you're doing something (if you catch my drift), and the bridleway to Hanborough had enough uppy-downy ness to keep the euphoria of still being alive up. I burst into fits of laughter at my one bail of the day though - a totally hidden rut just next to the trail that I acidentally rode into. It was a little over wheel width, and deep enough that even with pedals level, I grounded instantly. Fortunately I was going slowly at the time, so just had to hop off.

I had planned to head over to another wood for some more fun, but time had caught up with me. Time to head home on the roads, pausing only to provide directions to lost motorists on the way.

Thursday, 27 August 2009

"Adventures" off bikes

I've been trying my damndest to get some off-road cycling in. I tracked down a club near here, and I've been out with them twice (once in pouring rain, I chickened a few things, once in not pouring rain, and I rode everything I'd chickened the last time round - huzzah! I'm planning to take photos of the interesting bits, so I might post more here when I've done so). The problem is, whilst I really enjoy it, I don't really know where to ride, aside from the club (who I don't know yet) don't have anyone to ride with nearby, and on top of that, having ridden very little I'm not very good at it. That's fair enough; ride more and all will be well.

I have friends who are range from very good to jaw-dropping (in my eyes), but none of them live near here, so I only get to play with them when I go a-visiting. They also have lots of fun stuff to ride over near them, so I'm eager to get good enough to be able to ride that without bricking it the whole time. Again, that's going to come with time and experience, I know. I've been trying for months now to put in the time and get the experience, but it feels like such a non-starter sometimes that I can't help but get a little discouraged by it. We've had such mental weather on the nights that the club has been riding that a few times I've just not bothered to turn up (Hey, I made it to the pouring rain one, but thunderstorms, and high wind + bucketing it down extreme weather combos are a bit much for me - I don't mind getting wet, but since I have almost 0 confidence in good conditions, riding in a storm just doesn't feel appealing). In addition to that, aside from literally three small bomb holes (pictures to follow, as promised above), the local riding I've been introduced to is far from technical. If you're cool with riding on medium-chossy bridleway, or slaloming a little through a flat wood then you're going to be pretty much sorted for everything round here, it seems. Not that it isn't fun, it is, I just don't really feel like I'm going to learn much from it, and more importantly from my point of view it's not going to help me build confidence on the bike. I've tried to hook up with a variety of people when Up North, but between more Extreme Weather, financial woes (mostly of others), and the pressures of fitting things in around family time it's just not been happening.

This week, I realised that I'd left it somewhat late to sort out lights. I don't have any suitable to get me through even a dusky ride when we get to the fun bits (my recent experimentation has revealed), and it's getting darker from here on in. I've ordered some lights, but they're not going to be here by tonight, so that's going to be another week of not riding anything at all. I'm heading off up to Scotland early next Friday morning, and given I want to take both my bike and my Stuff with me, I'm not sure that I'm going to be able to fit in the 7-9 ride next Thursday either. I've also been looking at going on a skills course to try to learn something (anything!), but so far that's been comprehensively stymied by every fricking course I could make it to being Women Only.

I tried blowing off some steam about this to a couple of friends yesterday, and got pretty much blank incomprehension from them both. One outright said they couldn't understand why I'd want to do a skills course when there was nothing technical to ride round here anyway, and the other seemed to have pretty much the same opinion, but just didn't come right out and say it. Neither seem to really get why I'm so totally frustrated - both thought I should just "go out and ride more". It's easy to say that when you're surrounded by excellent riding and in the company of lots of other mountain biking folks all the time. I suspect I'm just annoying people by being all whiney at them. This is, I admit, pretty much par for the course for me (sorry). But I'm conscious that in a week and a half, I'll be back up where there are interesting things to ride, with people who are easily capable of riding them, and I'll be back to where I was pretty much where I started when I went up last time (i.e., terrified and clueless) due to lack of practice between then and now. By the end of the weekend, I'll hopefully feel a bit more confident again, and be having fun... only to come back home and do lots more Not Riding and lose it all. Again.

Thursday, 6 August 2009

Adventures on Bikes

I planned to keep a bit of a log of my two-wheeled adventures. The problem is, I've left it so long since I was going to start this that I've got a bit of a backlog to get through. So we're going to have to do a touch of pretending we're back in time for this...

28th June - The Chilterns Challenge

Very very late in the day - just a couple of weeks before - I got a message from Ed saying he and Beth would be visiting that weekend. So how about doing this years Chilterns Challenge? Since I'd hoped to do it anyway, and was already training for a 100 mile ride from York later in the year, I leaped at the chance. The route was similar to last years and I'd really enjoyed that.

I say really enjoyed.

It was a nice route, but it damn near killed me getting up those hills... Admittedly, I'd been doing almost no exercise that time round, and was riding a heavy rustbucket of a bike, but still. It was tough. So I had a little trepidation (to say the least) about how I'd find it this year. All the more because the weather forecast as the day approached kept tending more towards "you are going to melt". I can't remember what temperature was threatened, but it was alleged to be feeling well in excess of 30 degrees.

The ednbeth arrived late on Thursday night in advance of the ride. We decided to leave the bikes in the car and sort out taking them round to the garage the next morning. Which we did - along with my shiny new secondhand Kona Caldera which they'd brought down from Glentress for me (yup, I got the bug... although where I'm going to find mountains round here is anyones guess - more on that in subsequent posts, I suspect). Unfortunately, Ed decided to ride Beths bike round to the garage while simultaneously pushing his. And fell off, tacoing his front wheel, bending his bars, mangling his grip tape and nearly severing the cables on that side. Fortunately, he had a couple of days in hand to Do Fixing and by the time Saturday night came, his bike had been bludgeoned back into something approaching a rideable state.

The night before the ride, we cooked Epic Pasta and resolved to get up before six, in a bid to beat the worst of the afternoon heat. Shockingly, we did so. After a couple of false starts (forgetting such vital tools as a pump the first time round), we were off.

Arriving at Henley, we found the tiny car park at the start absolutely rammed with cars, but through some sneaky parking-on-the-driveway we managed to bag a plot and begin assembling our glorious steeds. A brief queue for registration, and a mere quarter of an hour or so of faffing around later we were off!

...for all of about three minutes. And then we realised we'd forgotten the sunscreen. Ed, bless his enthusiastic little socks, decided he was the person to ride back to the car, grab the cream, and catch us back up. Beth and I were to pootle along until he caught up. And pootle we did. After a little while, we were beginning to get concerned that he'd maybe missed the first turn. We were just about to turn back and go searching when we saw him in the distance, bombing up the road. It turns out that our pootle was a bit more like a brisk zoom, and poor Ed was now wrecked already from trying to catch up with us. Oops. Still, he had some respite while we gooped up. But not much. For we'd managed to stop at the start of the first big climb of the day... now, I remembered this with much trepidation from last year. The two big hills on the route had very nearly finished me off, and I'd been worrying that this year would be no different despite the training. I was both surprised and delighted to scoot up the first one pretty easily - so much so that I found the energy to wonder why the fellow in front of me was insisting on wobbling all over the road rather than just dropping gears and spinning more, like I had. It's not like he was going any faster than me, and I was having a much easier time of it... As an aside, I should mention that this is something I really don't get about a lot of road cyclists. They seem to actively want to make life harder for themselves by not having a triple chain set. Now, I sort of see that for the top-end elite cyclists that not having that tiny amount of extra weight might make a difference. And they're elite, so they don't need a granny ring. But, honestly, the majority of the folks I see out aren't elite. They're just in pain. I suppose that part of the answer might be that it's not fashionable to have all the gears at the moment, so it's hard to find bikes with them. Anyway.

Zooming down from the first hill, the road was beginning to feel a little sketchy, and since I wasn't sure how far it was to the junction I started to slow down a bit. Ed zoomed past me (probably with a "why are you slowing down?"), and then realised - just as I did - that we were about to hit the T junction at the end of the road. Fortunately, our brakes were up to the job.

Excitement over, we settled in to a merry pace, chatting as we went. Seemingly in no time at all we were at the first food stop. We zoomed straight past, deciding we didn't need to stop, only to stop a mile or so down the road (I think Beth ran out of water and needed a transfer, but I'm not sure now). We timed that perfectly so we were just setting off again as we passed the event photographer, who somehow managed to completely miss us.

Now we were hitting the BIG climb of the ride. Last year it was at the start of the route, and I remember it being pure purgatory and seeming to go on forever. I started to realise as I overtook a few people on the way up it that either my new bike was awesome compared to the old one, or I was far, far fitter this year. I suspect mostly the former. Once we were all up that hill, we were fast approaching the route split. We'd all signed up for 100km, but for some reason the organisers had Ed and Beth down for 100 miles. Destiny maybe? We decided not, and opted for the short route whilst confidently proclaiming we'd do the 100 miles next year (which, incidentally, Ed and I had confidently proclaimed last year too. We were now onto the swoopy downhill fun-run I remembered so fondly from my previous attempt at this ride, and swoopy swift fun it was. We ate up the miles to the next food stop, where we paused for a re-gooping and to swipe some supplies. There were zip-vit energy gels being given out, and I bagged a few in case I needed them later. Curious as to their effect, though, I decided to scarf one down straight away to see what it was like.

Oh my word.

I'm assuming that these things are designed for people who are on the verge of collapse. To someone very far from that point, they had the effect of making me giggle hysterically as I rode for about the next twenty minutes, weaving around like a drunken loon. The next section of the ride is a bit of a blur, and soon enough we were pulling over at the lunch stop. Pasta and doughnuts all round! By the time we set off again, it was beginning to really get warm. Whilst we were moving, all was well since we were at least getting some airflow, but whenever we stopped at junctions it was like stepping into an oven. Also at this point, we were beginning to hit the really chossy roads that I'd been fortunate enough to be packing front suspension for last year. I really do mean chossy, too, with quite a lot of the section between lunch and the last food stop seemingly midway back to turning into a dirt track. The heavy rain from last night was clearly in evidence too - the roads were covered in bits of branches, stones and earth which had been washed into the road by the torrential rain. Not fun riding for the full-on road bikes, but since we were riding a tourer (Beth) and a cross bike (me) we weren't to bothered. I distinctly remember Ed complaining about the bumpy surfaces on his audax bike (with the trashed bars), though.

Midway through this middle-of-nowhere only-barely-still-a-road section, we found the highlight of weird for the journey. A traffic jam behind a land rover which had fallen partly into a field. Rather than the other drivers get out to help, they thought it best to stop the cyclists who were mid-way through an event to get them to push the car back out of the field. Nice one, guys. Being pleasant types, push we did.

As we were approaching the last food stop, we saw a marvelous sight: A family out on their bikes. With a child trailer! And balance bikes! Sweet! I slowed down to have a chat with them, only to be overtaken by a pair of tandems. If only there'd been a trike and a unicycle too, I'd have had the full set...

After the last stop, the heat was beginning to tell. whilst the terrain now was mostly flat, I found this section to be a long grind (partly, I guess, because I knew most of the fun stuff was over). Up one last, then down a track to the river and we were back into Henley, and nearly at the finish. Since it was regatta time, the traffic was insane, and just before the town centre I was separated from the rest of the posse. Since we were nearly done (and the traffic was scary-busy), I headed off to the finish alone. Once again, I missed my chance to get a photo as the tandems pulled into the finish just ahead of me, with many oohs and ahhs. The photographer didn't even notice me slinking in past them. I claimed my medal, and then stuck around waiting for the others. Just a couple of minutes later, Ed rolled up, and then Beth... who stopped just short of the line, and made to start taking her bike apart and put it back in the car. She hadn't noticed the huge inflatable finish line, and just assumed that entering the car park again was the finish. We shouted her over, and she walked across the line, and we'd finished! Huzzah! Time to pick up our t-shirts and medals, splat down on the grass for a rest and marvel at the sheer number of bugs we'd managed to glue to ourselves using sunblock as we rode.

All in all, excellent fun. But only 100km, and I still felt pretty tired by the end of it so I was still far from confident that the 100 mile ride from York later in the year would go so smoothly...