Sunday, April 26, 2015

Ruby services in Docker using Passenger

This weekend I was working a little project I wanted to deploy to Digital Ocean. The app was a simple server written Ruby using Sinatra to server some JS. I already had an instance running in Digitual Ocean with Docker installed, so I figured I'd just copy one of my existing docker files and deploy it that way.

Having a look at the Dockerfiles I've used for my existing projects, I realised they all used the standard Ubuntu base and then used a dreaded curl | sudo bash install. I'd recently read this hacker news article about the state of sysadmin in a world with containers, and whilst I disagree with many of the points, I thought it was time to look for a more robust way of dealing with containers.

Enter Phusion and their base-image and passenger dockerfiles. Phusion aims to provide a set of stable, secure and better setup docker images then what most people would be used to. In my case this was definitely true.

The base-image is a standard ubuntu build with a number of tweaks to make it more docker friendly. The main thing I picked up on is they use a version of runit as a lightweight process supervisor to manage the processes running in your container.

The passenger images are aimed at application deployment. There are number of builds for different version of ruby, node etc, and it also comes with Nginx and a few other services bundled together.

Getting down to it, I decided I'd use the ruby21 passenger with everything disabled (ie., Nginx) and just use runit to start my app. This seemed to be the best way to get things up and running as I already had scripts setup to run my app using unicorn. I didn't really want to port the app over to use Nginx and Passenger just yet.

So my Dockerfile ended up looking like this. It's very simple which I like.

My run script was as follows:

And my start script simply called unicorn:

A few things to note:
* Don't put an Entry point in your file.
* Instead use the runit and my_init command that is built in. Basically, you use my_init to start and monitor your daemons rather than using an entry point.

The doco explains how to do this (add a script to /etc/service/my_service_name/run) and it pretty much works out of the box

... except it didn't. On running the service and tailing the logs I got the following:

*** Booting runit daemon...
*** Runit started as PID 9
Rack env: production
Running using: 8080 and rack env: production
Apr 26 05:58:08 67f2f5a43939 syslog-ng[21]: syslog-ng starting up; version='3.5.3'
Rack env: production
Running using: 8080 and rack env: production
master failed to start, check stderr log for details
Rack env: production
Running using: 8080 and rack env: production
master failed to start, check stderr log for details
Rack env: production
Running using: 8080 and rack env: production
master failed to start, check stderr log for details

So the runit process wasn't picking up that service was running, and was constantly trying to restart it. This is obviously not the desired behaviour.

I spent a fair bit of time googling around and reading the doco for the base-image. I also looked at runit in more detail to understand what was going on. It wasn't until I re-read the passenger page that I picked up on this:

Note that the shell script must run the daemon without letting it daemonize/fork it. Usually, daemons provide a command line flag or a config file option for that.

Oh. Right. runit wants to manage the process itself. It doesn't want to be looking for a pid file associated with a daemon that is already running as a daemon. It wants to treat it as a process. The solution is to drop the -D out of the call to unicorn as follows:

And there you go. Now I have a small Dockerfile from a well maintained repository that I can easily use to run any kind of ruby service, be it a worker or a web app.

TL;DR: If you have a ruby process you want to run using passenger--don't daemonize it!


Thursday, April 23, 2015

Scala Functional Toolkit: Handling exceptions in for comprehensions


As we develop more and more code in Scala, we are trying to stick to a few key principles. One of these is to avoid throwing Exceptions at all costs. In pretty much every case, this can be avoided by using Options or Eithers, however, sometimes it gets a little messy.

One such example we came across recently is when you are dealing with Futures, in particular doing something like a web request.

For example: Let's say you want to request some data from an API using Play's WebService library (or any HTTP library). Once you've got the result back you want to check whether the response was  a 200 or not, if so, you want to parse the JSON body. Finally, this all should be happening in side a Future so that it doesn't block your code.

In this case, the initial Future may succeed, but contain a 400, in which case you still want to fail.

Here is a naive implementation:

This is the kind of thing we don't want to do. Regardless of how it is handled by the caller, we'd prefer not to throw Exceptions anywhere in our code.

So we can get around this using Future.failed, however, as we are failing the future once the response has been received (that is the initial request future has now completed) we need to use flatMap instead of map. Otherwise our failure case would be Future[Future[JsValue]] and our success case would be Future[JsValue].

Ok. This is better. We are no longer throwing exceptions. We are now using the Future.failed method instead. However, it is a bit clunky. We can make this a slightly nicer using a for comprehension, however to do this we need to create a predicate method:

This method takes a boolean condition and then depending on the result either evaluates the success block, or returns a failed future with the exception specified. Using this we can now re-write the function as follows:

You can play around with this a little to create more versatile or specific variants. Whilst in the end this is all syntactic sugar, it has been a useful in making our code more concise.

Sunday, October 26, 2014

A letter to the Australian Government regarding metadata collection

26th October 2014

Circulation:

Teresa Gambaro
George Brandis
Scott Ludlum
Christian Milne
Bill Shorten

I am writing to you today to express my deep concern regarding the proposed data retention bills that are soon to be presented to the Senate. I want to make it clear that I am not writing to discuss the question of whether metadata collection constitutes surveillance. Nor do I wish to discuss the morality of mass surveillance and whether it violates a fundamental human right. Finally, I am not going delve into the ease with which this surveillance can be circumvented using readily accessible technologies such as Tor or VPNs.

Although all of these issues are concerning to me, there are others who can frame more elegant and knowledgeable arguments on these points. My objection to these changes stems instead from my firsthand experience as a Software Engineer; in particular, my previous experience as a developer of security software and my current experience working with big data analytics.
My concerns are pragmatic and relate to the realities of delivering the infrastructure required to support the proposed legislation. In particular:

·       The cost to the ISP and the end user

·       The risk to the Australian people posed by collecting and storing this information

·       The potential for unseen follow-on effects resulting from decreased competition between ISPs.

The scale of the metadata to be collected is enormous. One estimate puts it at around 1 petabyte per day. If you try to store this on Blu-Ray Discs, you would need 20,000 discs Each day. In my current job we deal with terabytes of data and I have firsthand experience of the difficulties involved in managing this volume of data (which is much smaller than the daily volume required to support this legislation). The cost of storing this data alone is significant, let alone the cost to move that data around. 

This is the point. The data is useless unless it is accessible.

To be accessible it has to be indexed efficiently and readily available. Or, it needs to be archived and stored on media that can be loaded when needed. Both of these approaches present issues; one is computational, the other is physical (for example storing 20,000 Blue-ray Discs per day). There are then considerations around redundancy and back up. For this to be useful, the services recording this data need to be highly available, as do the services storing the data.

All of these technological hurdles can be overcome. Companies such as Google, Facebook and Amazon deal with these volumes of data as part of their daily business. These companies succeed because they have world leaders in technology, building and maintaining systems to allow them to do it. But ISPs don’t. This isn’t their core business and it delivers no value to them or their customers. There is no way for them to recoup the costs of managing this volume of data, other than being subsidized by the government or by passing on costs to their customers. Either way, the taxpayers of Australia foot the bill.

Let us say that these obstacles are overcome and that the impact to the consumer is somehow managed so as not to drive the cost of Internet connections to high. We are now in the situation where vast amounts (in fact all) of the metadata describing the online behavior of Australia’s citizens are stored in a small number of locations hosted by the ISPs. This represents a sizeable target to anyone with nefarious intentions. In the past 18 months we have seen two serious vulnerabilities appear: first OpenSSL’s Heartbleed, and more recently, the Shellshock vulnerability in Bash. OpenSSL and Bash are two technologies that form the cornerstone of computing. They power an enormous amount of the Internet, yet despite being built and maintained by some of the leaders in the field of computer science, they still had flaws and these flaws were exploited.

These two cases are presented to illustrate the difficulty in securing software. The data that these laws require the ISPs to retain is of critical importance. So much so that many Australians feel uncomfortable with their own government possessing that data. How would these people feel if this data was obtained by a third party that was not bound by the laws of Australia? This is the very real risk of metadata collection. Once again, the ISP is being asked to take on a significant burden that is not part of their core business and that they are not equipped to handle. In this case the responsibility is higher as the risk is greater and they will be competing against a potentially highly skilled adversary.

As a final point, in the event that ISPs are able to implement a highly secure and cost effective solution to meet the requirements of this legislation, these requirements will form an enormous barrier to entry for any future ISPs wishing to enter the market. The cost overheads this legislation would place on the operation of an ISP would not only be a strong deterrent to entering the industry, but could also result in the exit of smaller ISPs from the industry. The net result would be a smaller number of ISPs operating under punishing business conditions.

In the end it will be the consumers who suffer. The true cost of this legislation includes the time and resources to create the infrastructure, but also the risk to the Australian public that their data is compromised by a third party. The net effects result from decreased competition and lower service levels. Australia already lags behind much of the developed world with our Internet infrastructure. The scrapping of the NBN ensures that this will remain the case. These laws risk pushing us further behind.

As a result of these concerns I have the following questions:

·       What estimates have been done on the cost of this metadata collection? This includes costs for the ISP and for the government body accessing the data when required? What safeguards will be put in place to ensure that these cost are not passed on to the consumers? In short, can the government guarantee that these changes will not directly or indirectly increase the cost of Internet in Australia?

·       What specific measures are being taken by the government to ensure the metadata is secure and only accessible by those authorized to access it? Have the security protocols been agreed on; if so, what are they? These details should not be concealed under the guise of national security—obfuscation does not create secure systems. Secure systems are built through strong collaboration with industry and constant peer review.

·       What protections are being put in place to ensure that competition between ISPs does not suffer because of the dramatically increased cost of collecting and managing this metadata. What thought has been put into the approval and verification process that would be required by new and existing ISPs to ensure they meet the standard of the metadata collection? What body will oversee this and how will it be administered?

I expect that these questions have already been raised while discussing the legislation. If not, this legislation is nowhere near ready for passage through parliament. If they have been discussed then the answers need to be shared with the Australian people so that they fully understand the impact on the cost of living, the risk to their personal data and the threat to competition that this the legislation poses.

Sincerely


David Healy

Monday, June 17, 2013

Bash history made better

The following can be used to set up a much more useful bash history search. Simple to set up, it basically gives you the "ctrl-r" style command search simply by pressing the up button. 

Eg: Typing $ vim and pressing the up arrow will return all commands that start with vim. So simple, so powerful.

Setup:

$ cd ~
$ touch .inputrc

Add the following to .inputrc

"\e[A": history-search-backward
"\e[B": history-search-forward
set show-all-if-ambiguous on
set completion-ignore-case on

That's it! Now you have awesome history search.

Monday, May 06, 2013

Good bye Unity, hello Xmonad

About 8 months ago I began working on a Ruby project and as a result made the switch from Windows to Linux as my daily driver OS. This is something I've been wanting to do for a while but up until now the project I've been working on have necessitated a Windows box. 

Once I got my head back into the Linux world I loved it. I can't see myself going back, however, I did developed a healthy distaste for Unity (which seems to be par for the course). Co-workers of mine were using Xmonad and during the downtime I decided to give it a go. 

It's the best. 

It took me about half a day to get my head around how it really worked, but now that I have I found other OSs clumsy in the extreme. This is especially true if your working on the command line a lot or working with tools such as a Vim or emacs. In fact, that's not even quite true, even if you aren't working with the command line a lot it's great, but working with terminal so much nicer with Xmonad that I think you'll find yourself doing it more. 

Hyperbole aside, the one thing about Xmonad is that it isn't exactly trivial to set up. So I'll try and out line as simply as possible the steps I went through to get mine working. 

First up, I'm using Ubuntu 12.04 (Percise). No guarantees these instructions will work on earlier or later versions.


Install

Use apt-get to install both xmonad and added plugin called gnome-panel (you'll need this if you are running a gnome/xmonad session).

$ sudo apt-get install xmonad
$ sudo apt-get gnome-panel

At this point xmonad will be installed but you'll need to log out to change the session. Before you log back in select the window manager using the button on the top right hand corner of the login box. Choose "Gnome/Xmonad" (or similar).


Configure

Once you're in you'll need to configure things a little. First up you'll probably be greeted with a black screen and nothing else. 

Alt+Shift+Enter opens a new terminal. By default alt is the Meta (mod) key, you can change this later (to Windows key for example).

Create the config:

$ cd ~
$ mkdir .xmonad
$ touch .xmonad/xmonad.hs

Edit the config:
Below is the config I use. You should be able to copy and paste this into your xmonad.hs and it will work.

import XMonad
import XMonad.Util.EZConfig
import XMonad.Hooks.SetWMName

myMod = mod4Mask
myWorkspaces = ["1","2","3","4","5","6","7","8","9"]


main = xmonad $ defaultConfig {   
    modMask = mod4Mask,
    workspaces = myWorkspaces,
    startupHook = setWMName "LG3D"
    }
    `additionalKeysP`
    [("M-x f", spawn "firefox")]


A few points:

  • I set the meta key to windows key by using mod4Mask (mod1Mask is the Alt key)
  • The setWMName call is used to ensure Java Swing apps (such as RubyMine or InterliJ) render correctly.
  • The firefox start is an example of setting up your own application hot keys.

Done!

Now you probably want to look up the Xmonad key combos to find out to do things. It will take a while to get used, but not as long as you think and once you're up and running you'll love it.

Finally a much detailed explanation of all this can be found on the Xmonad Gnome page.




Monday, April 02, 2012

Android Unit Testing - A slightly painful experience

After a few months of mucking around with Android it came to build something substantial. Things have been going fairly well until I started trying to add Unit Tests.

Android provides a complete framework for unit testing which builds on JUnit 3. All in all, this seems pretty good and things are fairly straight forward. The thing that caused the pain and frustration was in resource management.

First of all, let's summarise the test I was trying to implement:

  • My app executes REST requests against a web service. This returns JSON that is then parsed by a Proxy class into my model classes.
  • The REST queries themselves are executed by the Proxy via a RestUtil class.
  • To facilitate testing of the parsing code, the RestUtil class is defined by the interface IRestUtil. The Proxy constructor accepts an IRestUtil object.
  • This allows me to create a MockRestUtil that implements IRestUtil. This can be passed to the Proxy in my unit tests to allow testing of specific responses.


So with that in place I came to implement MockRestUtil. The aim was to get the MockRestUtil to load saved chunks of JSON stored locally as assets. This way I can test a whole variety of responses from the web service easily.

Once it came time to load the resources though, I never got anything back but null. I had been trying to use ClassLoader.getResourceAsStream(), however this returned nothing but null. I also tried making a static application context and using getContext.getAssets(), again nothing but null. I tried a lot of things, however, it wasn't until I hit upon the following Stack Overflow article that I finally got things working: http://stackoverflow.com/questions/9898634/how-to-provide-data-files-for-android-unit-tests

To summarise (based on Eclipse):

1) Right Click on your Test Project and select Build Path -> Configure Build Path
2) Under the Source tab click "Add Folder" and select the Assets directory. Note: Since Version 15 of the ADT plugin, the Assets folder is NOT include in the build path by default. You have to add it manually.
3) Create your data files and add them into the /Assets directory of your test project.
4) To access them in the test case use the following:

String assetPath = "assets/data.json";
InputStream stream = this.getClass().getClassLoader().getResourceAsStream(assetPath);

And there you go. Now you have an easy way to store local data for use in Unit Tests.

Friday, February 03, 2012

Implement a Week Iterator in C# using DateTime, IEnumerable and Extension Methods

I had a problem to solve. It wasn't a difficult problem, it was just one of those yucky problems I've done numerous times before and for some reason just always feels hacky.

The problem was this: For a given date range I wanted a list containing the date of the start of each week within that range. To be clear: The first date did not need to be within the range. Rather, the first date would normally be the Sunday of the week in which the first date fell.

This isn't an unusual thing to do and it is something that is done often in reporting tools.

This is also the perfect case study for writing an Extension method on DateTime that returns an IEnumerable. Doing this results in an easy, elegant and reusable solution that is no longer a hacky function buried in a class somewhere, but an extension to an already ubiquitous class (DateTime).

First up, this is implemented uses an Extension Method on the DateTime class. In C# extension methods allow you to add methods to an existing class without having to derive from the class or change and recompile the class. A couple of things about Extension Methods:
  • They are always static (that includes class in which they are defined and the method itself)
  • The first parameter is always the class which the method operates on proceeded by this.
  • Extensions are only in scope when you import the namespace in which the method is defined with a using statement. 

So, the prototype for my new extension method will look something like this (I'm calling the method EachWeek):

namespace Extensions
{
  public static class MyExtensions
  {
    public static IEnumerable EachWeek(this DateTime start, 
    DateTime end)
    {
       ...
    }
  }
}

In our calling code, this means I can now use this function as follows:

using Extensions

...
DateTime endDate = DateTime.Now.AddMonths(2);
IEnumerable weeks = DateTime.Now.EachWeek(endDate);

Iterating over weeks will now return each of the Sundays from the first Sunday before DateTime.Now to the last Sunday before endDate.

Using the above template, it's now simple to extend this to implement EachDay, EachMonth and EachYear.


The implementation of the function itself is as follows:

public static IEnumerable EachWeek(this DateTime start, DateTime end)
{
  // Remove time info from start date (we only care about day).
  DateTime currentDay = new DateTime(start.Year, start.Month,

  start.Day);
           
  // Get the dayOffset and subtract this from the current day,
  // this will give us the start of the first week.
  int dayOffset = (int)start.DayOfWeek;
  DateTime currentWeek = currentDay.Subtract(new TimeSpan(

  dayOffset, 0, 0, 0));
  while (currentWeek < end)
  {
    yield return currentWeek;
    currentWeek = currentWeek.AddDays(7);
  }
}

For more information on Extension methods see:
http://msdn.microsoft.com/en-us/library/bb383977.aspx
http://msdn.microsoft.com/en-us/library/bb311042.aspx

For more information on IEnumerable and Yield return see:
http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx
http://www.dotnetperls.com/yield

Saturday, December 31, 2011

Starting afresh

4:40pm 31st December, 2011 - Not a particularly bad time to start a new blog, and begin learning a new language. Well, symbolic it's a good time, practically not so much.

In any case this is a new start. After 10 years of back end and web service development it's time to try something new. During this time I've worked as a software engineer, team leader and sales / marketing / product management guy. Throughout it all I've been developing primarily in .Net with sporadic Java phases interspersed.

To be honest, I love .Net. The .Net 4 framework with C#, Visual Studio and Resharper is an elegant and rapid way to build software. Whilst the FOSS crowd might hate to admit it, Microsoft has it over most other languages when it comes to IDE and tooling support.

But all good engineers need more than one string to their bow. This is especially true for .Net enterprise developers. We live in an isolated world clinging to legacy code and outdated standards (like SOAP, ugh). Things are changing and the tide is turning (Windows RT and Metro promise to upset many a boat), but there is still a need to broaden horizons. With this in mind it's time to delve deep into an alien world of web apps, open source software, languages, tools and OS's. I'm hoping that some of the learning's I get from this will be useful to others who are in a similar position.

The only way to learn is by doing. So I will do. My aim over the next 3 months is to learn a new language and framework, namely Ruby and Ruby on Rails. Why? Because it's the golden boy at the moment. I also believe it will be handy to have at least a rudimentary understanding of the framework on which many others are at least partially based.

I have a project in mind as well. A project that incorporates all aspects of a modern application - a simple web interface, a RESTFul API, a back end data store and a native mobile interface. That's a lot in 3 months, but what are we without ambition?

Wednesday, December 16, 2009

Holiday in Cambodia.


Angkor Wat at sunrise

The Dead Kennedys first recorded the song "Holiday In Combodia" in 1980. It's a song which is heavily critical of eastern Militarism (eg., Pol Pot's regime) and Western complacency and is particularly critical of self righteous young Americans. It contrast their pretentious ways against the brutalities which were occurring under the regime in Cambodia with the inference being that their convictions would be sorely tested were they to experience the horrors of such a regime.

So, it was with this song playing in my head that Wookie and I landed in Siem Reap, the town which has sprung up around the ancient wonder which is Angkor. The drive from the airport into the town confirmed what most people would suspect - a holiday in Cambodia is now definitely achievable and actually quite a pleasant experience. This is made evident by the sheer number of hotels and spas which have sprung up around the town. The road from the airport is lined with two hundred room western run Megaplex hotels which provide everything that a well to do traveller would require. I feel that this all lends a certain irony to the song and to the original intent.

Anyway, enough of the diatribe - what was Angkor like? Simply amazing - it lived up to every expectation. After a day getting settled in, Wooky and I headed for the first of what would, for us, be three days at the temples. Before I describes this, I might add a little bit about  Angkor.  Firstly, Angkor Wat is only one of about 20 or so major temples which make up the Angkor site. The majority of these temples are contained within the “Big Loop” which is a road about 26 kms long which encircles the main sites.

Our chosen method for seeing the site was by bike. The distances weren’t too great and the area is completely flat, so it seemed like a good option as it gives you a lot freedom to go and see what you want when.

So with this in mind, our first day was a scouting operation, with such a large area and so many sites to see we wanted to get a feel for the area before James arrived. After a day of riding we a good feel for the place and the next day when James arrived we got straight into it. All in all we spent around 8 hours riding, we managed to see the main temple complex of Angkor Wat and the Bayon (both amazing) and also some of the smaller sites. Having the bikes allowed us to take some of the less travelled paths which always ended up leading somewhere interesting and less touristy.


The overgrown ruins of Ta Prohm

A Buddha face scene from the all but abandoned north entrace of Ta Prohm
 

Bass-reliefs at Angkor Wat


Finally, on the third day we hired a tuk-tuk (two days riding was more than enough) which took us to Angkor Wat for sunrise. Again, this is a must see experience. It's incredibly busy and we had to fight hoards of tourists, but it was totally worth it. There is a reason people get up at 4:00am to go out and watch the sun rise behind this amazingly ancient pile of stone. After sunrise we spent the day exploring some of the further out and more interesting temlpes, but by midday we were completely templed out. There are only so many bass-reliefs and Buddha / Hindu statues you can look at before they all start blending together.


Yet another rampant tourist photo. 

And that was Angkor, tomorrow we get up early and head for Thailand. Our next stop is Chang-Mai where we would meet up with Nat and then head off into Northern Laos to catch a slow boat. As a fair well to Siem Reap we decided it was time to go out for some dinner and drinks and Siem Reap has a lot to offer in this respect. The main street of the Psar Chaa district is teaming with bars, restaurants and tourists. In fact, it's sadly getting somewhat of a Khao San road feel to it (made all the more evident by the fact the main streat is called "Pub Street"). Even so, it's a good place to get some good food and beers. Speaking of good food, I'll leave you all with a tip - anyone traveling to Cambodia should definitely try Lok-Lak. The menu describes this dish as "grilled beef with Cambodian BBQ sauce" - but it's so much more. It's been a long time since I ate something which really blew my mind, in fact it's hard to describe what it tastes like, just that it taste amazing.

On that culinary note I'll leave it there. Next stop Chang-Mai.

Saturday, December 05, 2009

Welcome to KL

Kuala Lumpur, the city of ... of what exactly? I'm not quite sure. Prior to arriving in KL I'd read or heard very little about it. The most anyone could tell me was a) it's great for shopping and b) it's got the Petronas Towers, the second tallest building in the world. And after 4 days in Malaysian this still pretty much all I know about KL.

This is largely due to the fact that I abandoned KL almost as soon as I landed. After landing, I was looking at spending a lot longer in KL then I had intended to (due to some unexpected circumstances). What was originally meant to be a 2 day stopover had quickly turned into 4 days while I waited for Wooky to arrive. 

After discussing KL with a few people at my hostel, I came to the conclusion that whilst it seems like a fairly cool city, nothing was really drawing me in. I decided to get up first thing the next morning make my way to the bus station and head... somewhere.

In the end I opted for the Cameron Highlands, an area about 200km North of KL, and I'm glad I made the choice. The area is hilly and covered in tea / strawberry plantations interspersed with thick jungle. It's a nice change from the heat, humidity of KL. I also hit upon a an excellent hostel - Father's Guest house. Great place with friendly staff in an awesome location.





One of the many tea plantations in the Cameron Highlands



Interesting (read basic) accomodation in Cameron Highlands. Despite the look of the doorms it was a great pace to stay though.


The surrounding is pretty spectacular and is excellent for trekking. The thick jungle and unending hills, coupled with a lack of signs and the overgrown nature of the paths makes it a far more adventurous experience than first thought. Sadly, the views from the top of the mountains are somewhat spoiled by the fact that the development in this area has happened in a sprawling and haphazard way. As a result pristine jungle is often cut away by large tower block style apartment buildings or cuttings made to prevent mud slides onto roads. 


Thick forest of the Highlands


Friendly creatures too...

Having said that, in places the jungle is so thick and the terrain so impassable that, once we made it over the ridgeline and Tanah Rata was hid from view, we were presented with a massive expanse of apparently untouched jungle. We also had a nice suprised when we got slightly lost and stumbled across and Orang Asli village. The Orang Asli are the original inhabitants of the Malay peninsular and it was intersting to happen across one of the villages huddled in the hills.



Orang Alsi Village.


All in all, it was definitely a good choice to come up here for a few days. It was a great relaxing ay to start the trip, nevertheless, tomorrow I have to get moving again. I will be heading off to meet Wooky in KL before we fly to Siem Reap (Angkor Wat) on Wednesday morning – and that’s where the fun really begins.

Tuesday, December 01, 2009

Here we go again.

It's that time of year, summer is here, uni is finished, Christmas is coming and I'm leaving. This time we four intrepid adventurers are heading out into the vast uncharted jungles of south east asia... actually... hang on. Hmm, turns out these vast jungles have been chartered, quite heavily in fact, and even by one of our group.

Well it's still going to be fun and this time I'll be trying to keep this blog a little more up to date. For various reasons (mostly technology related), this blog ended around half-way through last trip. This time however, I've made the transition for dirty backpacker to yuppie backpacker. I'm travelling with a brand new NetBook and an iPhone which should make things a lot easier. We'll no longer need to spend interminable hours in internet cafes struggling with intermittent access, rather we'll spend interminable hours in our hostel fighting over this laptop.

In any case, I'll make sure that our (mis)adventures are captured and posted. For now though, I need to board a plane. Next posting will be from somewhere in Malaysia.

Dave.

P.s. you may notice a very recent posting below from Africa. No, I didn't make a side trip to Africa, but what I did find was a nearly complete entry I never posted. So there it is!

Sunday, November 29, 2009

There is no error in God's computer...

And apparently we are all wizards. Well that's according to the crazy lady we met in Stonetown, the capital of Zanzibar. She seemed quite harmless and, to be honest, her confusion didn't seem that out of place in Stonetown - the hectic mix of Islamic, Indian and Africa cultures means that it has a somewhat confused identity (and apparently some of residents are a little confused about religion too).


Zanzibar and it's amazing white sandy beaches.

So, crazy ladies aside, we had finally arrived in Stonetown in preparation for New years. Our journey here had an epic feel to it, even in comparison with the other monumental transit we'd done previously on this trip. I've mentioned before that travel takes time here, and one thing we've learnt about this is that it's best not to delay the travel or try to break it up. Push on through is the motto. Adding a rest day just makes things longer and you still feel wrung out at the end.

With this in mind we set out at 7:00am Christmas Eve from Chitemba on the sures of Lake Malawi with an audacious plan - we would aim to be Mbeya in southern Tanzania by 2:45pm in order to catch the twice weekly train to Dar Es Salaam. This gave us a total of 7 hours 45 minutes to make our way to the north of Malawi, negotiate the border, then on to Mbeya. A total distance of around 400km.

What ensued was something straight out of the Amazing Race with James, Wookie (Father / son), Nick and I (dating goths) barging our way across the country, running for busses, arguing with money changers and bus drivers and finally remembering an extremely inconvenient time zone change which we'd forgotten about (hence one our less to make the journey). The final push occurred when we arrived at the train station at 2:43 with train waiting at the platform. James and nick sprinted for the ticket offices while Wookie and Igot the bags ready to load onto the train, we'd made it...

Or had we? A distressed look from James and Wookie and a quick conversation confirmed our worst fears, the train was booked out. Christmas was ruined. We'd have to spend Chistmas in a hotel in Mbeya, or on a bus - boring.

But wait, at the last minute our shining star arrived, the station master, who nonchalantly wandered over and informed us, actually yes, there was a 1 first class cabin (4 berth) available and we could now by a ticket. After this he was dubbed the station master who saved christmas (we also had a taxi driver that saved christmas and later the swiss girl who saved Christmas, but that’s another story).


A merry Christmas message from Nick coutesy of his amazing light writing skills


Christmas was saved and we celebrated with some serious amazing race style high fives once we got into the cabin.




One last chapter the story: out train broke down for 18hours at one point. So what do you do? Frisbee that's what.