Thursday, July 8, 2010

Azure big upload take 2

Since posting the last big upload post we realised there was actually a 100MB upload limit in Azure.  This isn't 100MB per user.. this is 100MB per server.  So if 2 users upload 55MB each say, they will most likely both fail.  I think this is because the location for the temporary files only has 100MB available.  Sure, you can configure another location in web.config but that's not really possible when you can only get a writable location at runtime.  We emailed Azure support and it's been about a week with only this response so far:
"...So far the problem you have reported is a known bug and there is no fix for the issue besides the following workarounds:

  1. Use 3rd party ASP component which does not use asp.net temp folder

  2. Use silverlight

  3. Create your own asp.net upload component which does not use asp.net temp folder..."



So.. where to now!?  I did a bit of research and came across a great post that allows you to bypass asp.net upload handling -  http://dimebrain.com/2010/01/large-or-asynchronous-file-uploads-in-asp-net-mvc.html.  The only problem with this solution is that it doesn't appear to handle the form fields which we also need.  I actually tried it too and found it threw an exception pretty early in the piece and because it didn't quite cover what we needed I made a version which handles any number of files, a file size limit (although this only applies to the size of the stream itself) and any number of form fields.

I also tried to make this in an ActionFilter, eg ...
[BigUpload(100)]
public ActionResult Upload()

... but it appeared that using an ActionFilter was actually forcing asp.net to start handling the stream itself which is what we didn't want.  I'm not 100% sure whether it was the ActionFilter that caused this or whether it was some call inside the ActionFilter that caused it to deal with the stream itself.

So the solution.  First the usage:
public ActionResult Upload() {
// I have a 20GB local resource configured for this web role called "UploadStorage"
var temporaryStorageLocation = RoleEnvironment.GetLocalResource("UploadStorage").RootPath;
// work with the underlying connection..
var context = ControllerContext.HttpContext;
var provider = (IServiceProvider)context;
var workerRequest = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));

var processor = new BigUploadProcessor(workerRequest, temporaryStorageLocation);
processor.UploadLength = 100 * 1024 * 1024; //100MB
processor.HandleRequest(context, context.Request.ContentEncoding);

// at this point you can now use processor.Fields["fieldName"] or processor.Files["fieldName"]

Then you just need the guts: BigUpload .  I've tested it in firefox, chrome and internet explorer and haven't had any issues but please comment if you try it and run into any problems.

This is provided for information only, use at your own risk.

Auto Draft

Friday, June 25, 2010

Azure uploading big files into blob storage

Update: Please see my updated azure big files post.

Azure is all about big files, solving big computational problems and being able to expand quickly without needing your own infrastructure.

Why oh why then is uploading largish files (anywhere from 4MB in size) to blob storage such a pain?  This is my third go and I'm still not convinced it's going to work.  Here's what I've done so far to enable largish files to be uploaded:

  1. Added a 20 minute execution timeout and 100MB file size maximum in web.config - <httpRuntime executionTimeout="1200" maxRequestLength="2000000" />

  2. Then on the CloudBlobClient I set the Timeout = new TimeSpan(2, 0, 0); (2 hours) and the ParallelOperationThreadCount = 2.


  3. It looks like you also have to add another web.config change as below:

    <system.webServer>

    <!-- This is a setting from this forum http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/f4575746-a695-40ff-9e49-ffe4c99b28c7/ -->

    <security>

    <requestFiltering>

    <!-- 100MB -->

    <requestLimits maxAllowedContentLength="2000000000"></requestLimits>

    ...


I've seen examples where people manually chunk the upload into a number of streams of 4MB size which I'm really hoping I don't have to do.  Fingers crossed.

Thanks wot u do - http://wotudo.net/blogs/wotudo/archive/2010/02/16/copying-files-to-windows-azure-blob-storage.aspx.

Update: Added point 3.  In the process of seeing if it works now.

Update: man this whole thing seems a little flaky.  The above seems to work now but let's see..

azure nhibernate

I'm currently setting up our project with nhibernate and have been trying to work out a couple of things.  Firstly, the application is spread over a number of assemblies and the configuration loading ended up in our Project.Framework assembly.

If I tried embedding our hibernate.cfg.xml in the Project.Web (Web Role) assembly, the configuration loading wouldn't work.  I ended up putting the hibernate.cfg.xml in App_Data in the Project.Web assembly, then when I load my config:

var configuration = new Configuration();

var configFilename = "hibernate.cfg.xml";

if (HttpContext.Current != null)

{

configFilename= HttpContext.Current.Server.MapPath("~/App_Data/" + configFilename);

}

configuration.Configure(configFilename);

configuration.AddAssembly("Project.Data");

return configuration;

In actual fact I'm using hibernate.[dev|tst|prd].cfg.xml and I'm wondering if this is the reason it wouldn't load.  In any case, this way seems to be secure so that's all I wanted.

Thursday, June 24, 2010

web.config tips

I'm relatively new to the whole web.config in asp.net, being more used to working with ye olde' WEB-INF/web.xml or perhaps even the portlet.xml. 

To do page timeouts in asp.net you can use the <httpRuntime executionTimeout="<timeout in seconds>"/>.

This is a great article about all things web.config http://articles.sitepoint.com/article/web-config-file-demystified

Azure error handling

This isn't so much about error handling in azure as it is error handling in asp.net.  Ok the title kinda lied.. :) 

Adding error handling in asp.net is easy:

  1. Create an error page in your application (eg error/Error.aspx). 

  2. In the <customErrors/> config, set the defaultRedirect="error/Error.aspx" and voila!

  3. You have a couple of opportunities to handle the error (when it happens, in the page, or in the application):

    • In the page: public void Page_Error(object sender, EventArgs e)

    • In the application (Global.asax: protected void Application_Error(object sender, EventArgs e)



  4. Then you can access the actual exception via Server.GetLastError().GetBaseException();


So at work our exceptions get mailed.  Since azure currently doesn't have mail servers, we opted to use SendGrid which seemed quite ok.

Full guide here http://support.microsoft.com/kb/306355.

Tuesday, June 8, 2010

CloudBlockBlob.DownloadToFile()

I've been using CloudBlockBlob.DownloadToFile() without a hitch for the last couple of months but I started running parts of the project locally to do some debugging and it looks like DownloadToFile has a bit of a problem with it.  When I try DownloadToFile on a CloudBlockBlob that isn't small small (it's actually 64MB), I get a System.IO.IOException: "Unable to read data from the transport connection: The connection was closed."

Looks like you need to use the stream version:

// This will override anything that already exists,

using (FileStream fs = new FileStream(filename, FileMode.Create))
{

// I'm using a one-hour timeout

fileBlob.DownloadToStream(fs, new BlobRequestOptions() { Timeout = new TimeSpan(1, 0, 0)});

}



Update: I did a bit of testing with the Timeout BlobRequestOptions and the TimeSpan you set is more of a guideline.. ;)  I set the timeout to be 1 second and it took about 10 seconds to actually timeout.  I'm guessing that they stream a certain amount (I think it was 4096kb) then check if the timeout has passed, then read a bit more if it hasn't.  In any case, it's working now.


Update 2: Stupidly I wasn't closing the file stream which caused the file to be cut short!  argh!  Anyway, wrap it in a "using" like usual to call the Close().

Monday, May 24, 2010

Side-by-side they fall

The project I'm on at work finally went to actual Windows Azure over the weekend.  This was the media server component which converts and thumbnails media that gets sent to it using a combination of ffmpeg, ImageMagick and Lokad.Cloud for message queuing.  This was our first test in the full azure environment and I found a very annoying problem.

We got ImageMagick working ages ago by putting the executables (convert.exe, identify.exe) in cloud storage, then when the application needed to use them, it would download them to local scratch storage (I'll do a bigger post on this later).  This works really well on my local machine but upon testing on actual Windows Azure convert.exe and identify.exe stopped working, quoting:
The application has failed to start because its side-by-side configuration is incorrect..  Please see the application event log ...

My first thought was to follow the application event log, so I grabbed Azure Diagnostics Manager [http://www.cerebrata.com/products/AzureDiagnosticsManager/Default.aspx] and added some code to my WorkerRole.cs/WebRole.cs OnStart...
DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration();
dmc.WindowsEventLog.DataSources.Add(Constants.ApplicationName);
dmc.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
DiagnosticMonitor.Start("DataConnectionString", dmc);

...and found nothing!  I couldn't get the event log and after a little bit of playing around I decided to give up path!  The problem is that every time you do small changes to azure the deploy process takes AGES - like 5 minutes or so.  So trying little things and failing them then having to wait 5 minutes between can get very frustrating.  I'm sure if I read the full how-to post (http://blog.toddysm.com/2010/05/collecting-event-logs-in-windows-azure.html) I would have worked it out but I had a feeling that the event log wouldn't tell me much regardless.

So back on track I looked into the side-by-side error and found some information about it.  Basically side-by-side errors mean that some config/assemblies are missing (http://msdn.microsoft.com/en-us/library/ms235342.aspx).  So I started along the long path of finding the missing references to ImageMagick.  By the way, the actual problem is that the VS2008 C++ Redistrib packages didn't exist on Azure whereas they existed on my system (ImageMagick download page states this at the very bottom http://www.imagemagick.org/www/binary-releases.html).  I don't think I can just install them on azure so I went about the problem by gathering all the required assemblies.

So, to investigate side-by-side issues you have to use the "sxstrace" tool.  I set up a new blank Windows 7 VM to ensure vs2008 redistributable packages weren't there, then ..
1. Run cmd elevated (Start -> type "cmd" -> right click on cmd -> Run as Adminsitrator).
2.  cd into your executable directory
3. Run "sxstrace trace -logfile:sxstrace.ctl" (without quotes)
4. In another cmd, run your side-by-side failing program (identify.exe in my case)
5. Press enter to stop tracing for sxstrace
6. The trace is a binary file that needs to be parsed.  Parse it:  sxstrace parse -logfile:sxstrace.ctl -outfile:sxstrace.txt
7. Open up sxstrace.txt and you'll find your problem.

In my case, identify.exe required a couple of dlls and some .manifest files.  You end up having to copy required manifests from c:\windows\winsxs\manifests to your executable folder then grabbing all those dlls.  Run sxstrace again (as above) to find more problems.  Here's what I ended up  with to get identify.exe and convert.exe working (my wordpress images directory isn't working so the filenames are just given below):
convert.exe
identify.exe
identify.exe.manifest (not sure if this is needed)
Microsoft.VC90.OpenMP.MANIFEST (this was renamed from the respective manifest file in c:\windows\winsxs\manifests as I was looking specifically for this name from the sxstrace log)
mscvm90.dll
msvcp90.dll
msvcr90.dll
vcomp90.dll
x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022.8_none_bcb86ed6ac711f91.manifest

Happy to provide more details if anyone needs.

// Redirect Event Logs to your storage account

DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration();

dmc.WindowsEventLog.DataSources.Add(Constants.ApplicationName);

dmc.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

DiagnosticMonitor.Start("DataConnectionString", dmc)            // Redirect Event Logs to your storage account

DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration();

dmc.WindowsEventLog.DataSources.Add(Constants.ApplicationName);

dmc.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

DiagnosticMonitor.Start("DataConnectionString", dmc);

Thursday, May 13, 2010

ffmpeg output

I have to do some video and audio conversions for a project I'm working on at work.  We're using ffmpeg in the project (.net) and I thought I'd write a couple of things down for my convenience:

1. ffmpeg outputs to StandardError.  This is ok, you just have to make sure you redirect the stream and read from StandardError (of course!) like so:
using (Process p = new Process()) {
p.StartInfo.FileName = "ffmpeg.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.Start();
p.WaitForExit();
string response = p.StandardError.ReadToEnd();
}

2. The response given by ffmpeg are horrible!  I can't seem to find any way of formatting the response so it's pretty painful to parse.  Here's a regex that a guy at work came up with to get the length of a given video:
// To get the length, you just need to pass in the input file like so: ffmpeg -i somefile.avi
// This will give you a huge response to stderr, but the line we're interested in goes a little something like..
// Duration: 00:02:12.00, start: 0.000000, bitrate: 118 kb/s
Match match = Regex.Match(error, @"duration:.*?(?'hours'\d+):(?'minutes'\d+):(?'seconds'\d+)\.(\d+)", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
if (match.Success) {
int hours = Convert.ToInt32(match.Groups["hours"].Value);
int minutes = Convert.ToInt32(match.Groups["minutes"].Value);
int seconds = Convert.ToInt32(match.Groups["seconds"].Value);
}

I barely work with regex so I have to look up what everything does each time I use it.  In the above example you'll see the ?'hours' which explicitly names the group which makes things a lot more readable.  Thanks for the example http://weblogs.asp.net/dneimke/archive/2003/05/07/6575.aspx.

Tuesday, May 11, 2010

azure routing

I spent this morning trying to get routing working in an azure asp.net web role (these are basically just asp.net web applications).  I thought I'd be able to use some combination of HttpHandlers and <location> to get the routing happening but alas it wasn't to be.

I remembered that I did some research into asp.net mvc apps a bit ago and remembered that they used routing so I thought I'd be able to rip it directly off that (or use the mvc libraries).  After a little digging around, routing is available to asp.net 3.5 sp1 (which is azure's current platform) just by using the standard libraries.  Actually Michael Kennedy has already posted about azure & routing perfectly - http://www.michaelckennedy.net/blog/2009/05/27/ASPNETRoutingInWindowsAzureUsingWebForms.aspx.

The crux:

  • Reference System.Web.Routing and System.Web.Abstractions

  • Create a Global.asax in your web role

  • Modify your Global.asax like so


protected void Application_Start(object sender, EventArgs e)

{

RegisterRoutes(RouteTable.Routes);

}

public static void RegisterRoutes(RouteCollection routes)

{

var routeHandler = new WebFormRouteHandler<Page>("~/Test.aspx");

routes.Add(new Route("evidence/{environment}", routeHandler));

}

protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
var routeHandler = new WebFormRouteHandler<Page>("~/Test.aspx");routes.Add(new Route("evidence/{environment}", routeHandler));
}


  • Create the WebFormRouteHandler


using System.Web;

using System.Web.Compilation;

using System.Web.Routing;

namespace SuperTravio

{

public class WebFormRouteHandler<T> : IRouteHandler where T : IHttpHandler, new()

{

public string VirtualPath { get; set; }

public WebFormRouteHandler(string virtualPath)

{

this.VirtualPath = virtualPath;

}

#region IRouteHandler Members

public IHttpHandler GetHttpHandler(RequestContext requestContext)

{

foreach (var aux in requestContext.RouteData.Values)

{

HttpContext.Current.Items[aux.Key] = aux.Value;

}

return (VirtualPath != null)

? (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(T))

: new T();

}

#endregion

}

}


  • Create a Url routing handler that overrides IIS7's default action


using System.Web;

using System.Web.Routing;

namespace Supertravio

{

public class RoutingHandler : UrlRoutingHandler

{

protected override void VerifyAndProcessRequest(IHttpHandler httpHandler, HttpContextBase httpContext)

{

}

}

}


  • Update your web.config to use the handler (from Michael's post)


<system.webserver>

<modules runallmanagedmodulesforallrequests="true">

...

<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule,

System.Web.Routing, Version=3.5.0.0,

Culture=neutral,

PublicKeyToken=31BF3856AD364E35">

</add>

<handlers>

<add name="UrlRoutingHandler" precondition="integratedMode" verb="*" path="UrlRouting.axd" type="Supertravio.RoutingHandler, Supertravio">

</add>

</handlers>

</modules></system.webserver>

You're done!

The only thing now is accessing the routed parts.  So in my example (new Route("evidence/{environment}") I would get the parts from my page using (string)HttpContext.Current.Items["environment"].

Tuesday, May 4, 2010

Tuesday, April 20, 2010

Windows 7 + Oracle = good times.

Edit: Ok, I think some of the issues I mentioned should go away if you use the 11g 32bit ODAC rather than the 10g client as I was trying at the start.  I no longer have to run toad as administrator, and it also works from c:\program files (x86)\ too, so I think that must have been fixed with 11g?  Good hunting anyway :)

I had a lot of fun in the last couple of days trying to set up my dev work machine with Oracle and Toad.  My work machine is Windows 7 64bit, toad is 32bit and oracle client is just all round terrible - always.

A problem I encountered was that Toad installs to c:\program files (x86)\Quest Software\ which Oracle finds offensive (not sure if it's the spaces or the brackets) and throws weird errors.  Some of these problems include "TNS ..." but these are tricksy red herrings (usually means it can't find tnsnames.ora but in this case it was an actual bug).  See below for my installation instructions:

  1. Install your oracle client.  Make sure it's 32 bit (so that toad and oracle can be besties).  I needed the .net Oracle.DataAccess.dll so I installed the 11g 32bit with ODAC package.  It may fail the prerequisites but do a google search to fix that.

  2. Copy your tnsnames.ora file somewhere

  3. Set up the environment variables: PATH (must include your oracle home and \bin), ORACLE_HOME, TNS_ADMIN (directory containing the tnsnames.ora)

  4. Install Toad

  5. Copy toad from c:\program files (x86)\Quest Software to c:\toad (or somewhere without spaces!)

  6. Run toad from c:\toad\toad for oracle\toad.exe as administrator!  I suggest you pin this shortcut to your taskbar and everytime you run toad, make sure you elevate!

  7. Connect to your database


I will update the above instructions with very specific working instructions but I don't want to touch it now that it works because it was just such a chore.

Toad was initially complaining about my 11g oracle home saying it couldn't find oci.dll.  I ended up copying all the files that were in the same directory as oci.dll into bin\ and this worked.  High five ;)

I also had a hellova time getting .net to talk to oracle too.. I think this was mainly because I'd been installing so many different versions of oracle and that makes oracle moody.  I ended up removing anything to do with oracle from the gac (run visual studio command prompt and "gacutil -u " the heebies out of anything with "oracle" in it, including the Policy.Oracle...!).

Hopefully you can glean something from the above to get your setup working.

Monday, April 12, 2010

Azure: where's my blob at?

Currently from a fresh azure project, accessing blob storage fails:
InvalidoperationException: SetConfigurationSettingPublisher needs to be called before FromConfigurationSetting can be used

This is pretty well documented over the net, but for my reference - open your WebRole (it is the class that extends RoleEntryPoint) and insert the following into the OnStart() function:
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>

{

configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

RoleEnvironment.Changed += (sender, arg) =>

{

if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>().Any((change) => (change.ConfigurationSettingName == configName)))

{

if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))

{

RoleEnvironment.RequestRecycle();

}

}

};

});

CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>

{

configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

RoleEnvironment.Changed += (sender, arg) =>

{

if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>().Any((change) => (change.ConfigurationSettingName == configName)))

{

if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))

{

RoleEnvironment.RequestRecycle();

}

}

};

});

Sunday, January 31, 2010

Day 11: Captain's Log.

Captain's log, 31/01/2010  23:50, Madd-O Quadrant.

The wonder of Jude's new life has quickly become a sleep-deprived reality :)  I'm so glad that I wrote those first few posts when the amazement of it all was still sharp as he has become a little bundle of joy at 3.00am in the morning. Ruth wakes me up with a beaten look and Jude already in my arms, ready to be settled.  I then employ one or more of my three "baby settling" techniques to ensure we all get a good night's sleep:

a) "The Godfather": this is a tried and true traditional Italian technique that was shown to me by Nonno Giorgio.  It involves the settlee upright on the settler's shoulder.  The settler then twists and bends, creating a calming motion.  The technique has a high difficultly though and incorrect application of the technique can lead to further unsettling.  The technique has been demonstrated to settle a baby within 5 seconds (the current record).
b) "Baby hustler": this technique involes the settler walking a circuit jostling the baby up and down with quick repitions.  The settlee is again in the shoulder position.  This has had much success but does take at least 30 minutes and may require more than one attempt at the final "put down", which results in the technique needed to be re-applied.
c) "Beaten Settler": this techique is by far the easiest on the settler.  The procedure is to simply give the baby to the other spouse.  This has mixed success.

Jude has already become quite the crowd favourite :)  He slept through the entire meet and greet at church but we knew better.  On the way home in the car he woke up and made sure we knew he was hungry.  During the day its not so bad, but at night when you're trying to sleep too, it is a little like torture.

Cry baby!

Sometimes all you can do is try to remind yourself about better times..

better times.

Captain Quirk out.

Friday, January 22, 2010

According to trav...

I have been itching to put fingers to keyboard to tell the humble beginnings of our young Jude while it's all still fresh.  I hope that in future we can look back at each birthday and say "Well, at 4.17 this morning, you were born..." with some level of certainty in what actually transpired leading up to his birth.  Also, people are still saying to me that it was so unfortunate that Ruth had a c-section (cos we wanted natural!), and I was like "what you talkin bout willis?"  Ruth had a totally natural birth!  So, I give you "The First Epistle of Jude According to Trav".

Chapter 1.

1 It all began in the early hours of a summery Tuesday morning in Perth, in the "new West Perth" suburb known as "Maddington" or "The Maddeaux" (pronounced "Maddo").  The date was the 19th January, one day after my bet that Jude would be born (I lost a lot of money on that, Jude..).  It was so hot that night that we were sleeping under the air con on the couch in the living room but it was playing up a bit and turning off in the middle of the night causing Ruth no small discomfort.  I had probably played some fifa 10 or modern warfare 2 for a couple of minutes before bed to sooth me into sweet game filled sleep and I believe we had both fallen asleep around midnight.
2 Jude was, by this stage, overdue by 5 days (14/01/2010 was the expected date) and Ruth was heavily pregnant and getting uncomfortable.  It's a weird feeling when the due date passes because you have this date that you're expecting a baby to be there by... and it's not there... and every day that passes is another day you're wondering why this "expected date" was getting further into the past without a baby - what are we doing wrong!?  Perhaps like when it's your birthday and you're expecting all these presents on the day, but nothing comes!  Then they come days later and were wondering if you had been naughty?  PS mum I still remember the time that you went to josh's school camp in Rotto and noone remembered it was my birthday and I got up, had breaky alone, rode to school and came home without such much as a "happy birthday" on my birthday :)  I forgive you, Josh was your favourite, but it's anyone's game these days and I think I have the upper hand ;)  Where was I, ooh also the family birth centre (FBC) has a policy that they will only take natural births there from 3 weeks before and 2 weeks after the expected date otherwise they send you on to King Edwards so we were desperately trying to make sure it would happen, although there was very little we could do!
3 At around 2.30am on the 19th, a slightly excited but distressed wife woke me up saying it had started!  She had had some contractions and super travio husband mode kicked in and I quickly downloaded a stopwatch app for my phone (making sure it had at least a 4.5 star rating, there were a couple with good stars, but bad comments that I steered clear of obviously) and started timing the contractions using the "lap" function of the stopwatch (ingenious you say?  elementary my dear readers...).  We called up the FBC straight away and got Naomi who told us to just monitor them for a while and see if they were building.  At the start, we were clocking them around 7 minutes apart, then 6, then 5 but they kinda petered out ("Peter, just Peter.." only a select few would have heard my "Peter" rendition of MJs "Beat it" and understand that) so we called up the FBC again and they told Ruth to try to get some rest and see how it goes on the morrow.  We were pretty disappointed because the contractions had gotten to the stage where we could have nearly come in to the FBC, but then had just fizzled.  We took their advice though and tried to get some sleep but it was pretty hard.
4. I remember waking early the next morning excited that it would all be oooon but Ruth was only having sparse contractions, nothing in the 5 minute apart zone, so we were bitterly disappointed.  We had no petrol (well, gas) so I quickly ducked out to the gasso just in case, refilled, picked up some twisties and salt & vinegar chips and some iced teas on request, then grabbed a maccas breakfast for us both and headed back.  I called in sick to work saying I was looking after Ruth, nothing more and stayed with Ruth all day but the contractions were few and far between.  We hadn't told a soul at this stage that Ruth was starting labour as I didn't want to put any pressure on her, having the chinese whispers combined with the fully operational church grapevine (is "chinavine" offensive?  do I have to call it a Grass Tree Vine?) calling us congratulating us on birth of our new baby elephant before we even knew.  And no, it was a regular baby boy if you are confused at this point!  Mum had even used her spidey senses and messaged asking how Ruth was going, but we coyly replied that we were still just waiting.  I get the feeling that there are emotional things that effect childbirth so I was trying to give it the best chance even though we were screaming to tell people it was starting!
5. Night fell on the 19th January and by 8pm, the contractions had started taking hold again.  We were later told this was the real start of her labour.  I helped Ruth get through the early ones by breathing with her and keeping absolutely still (they can smell fear).  She later had a spa bath which kept her relaxed and was quiet enough for me to have a few rounds of 20 minute a side fifa 10 which I never win on professional.  I look back on the early contractions with fondness as it only gets much worse from there :)  They seem like playful tickles by the end of it, but you find the strength to get through it all!  We kept in close contact with the FBC and by 11.30, they told us to come in for a checkup to see how things were going.  I was excited but I thought it probably wasn't the night and was just trying to keep a lid on it just in case we had to go home.  We had prayed that the labour would be quick and that everything would go alright.
6. The drive in to the FBC in Subiaco was really exciting.  I tried not to get too anxious or excited driving, but I was probably doing 10 over most of the way on albany highway and ran a few (safe) red lights although this is totally denyable in a court of law as I am currently under duress and under the age of 18.  I think we dropped off two videos on the way in :)  Fan Boys, terrible 1/2 star and Simedawg Millionaire 4 1/2 stars.  We may have gotten flashed by a speed trap just where that ferris wheel is but it looked more like the flash of a camera trying to capture Jude moments before he was born.  In any case, we're not paying for the photos, thankyou!
7. We were so happy when we reached the FBC to find that Naomi was on shift that night!  She was one of the midwives we had during our first visits and we actually secretly wanted her to deliver the baby.  Don't get  me wrong, everyone at the FBC are great but there are people you just click with and are really comfortable with, and she was one of them.  At this stage it was about 12am on the 20th Jan and Ruth was about 4cm (yes, tall...).  Ruth was comfy in the shower which is where we ended up having our little boy.  So after an 8 hour labour or so, our boy Jude was born at 4.17am.  Naomi was excellent, so calm, helpful, friendly and professional.  She was kind of my strength which is why I can't praise them enough, and I was Ruth's strength.
8. Ruth ended up needing some repairs which made it necessary for us to be moved to King Edwards instead, which is unfortunate, but ended up being a bit of a blessing as Ruth was able to stay for a couple more nights and I was able to get some rest and blogging done ;)  I feel privilidged to have had the opportunity to have Jude for at least 2 afters while Ruth was in theatre, that was very special.

Hope you enjoyed the read and I'll be putting more pictures up when I have them.  I've got a video of us putting Jude into his carseat and taking him home today (well, yesterday) which was really special.  Josh will have something of when we arrived at home with him so stay posted.  Really enjoying this time with our little boy! :)

Thursday, January 21, 2010

Hey Jude!

On Wednesday 4.17am 20-Jan-2010 my little boy, Jude, was born.  I went through the whole birth close by my wife and am proud of her beyond words.  She amazingly got through the whole thing with nay but warm shower water on her back and my soothing voice wafting in her ears :)  She got through it without any pain relief and when it was all done and dusted and Jude laying against her, she was smiling and crying and saying "ooh that wasn't too bad".  I think it had been raining a little on my face too so to an observer it probably looked like I too was crying (easy mistake).  I'm no Mark L... no, too obvious... I'm no M Lauthier :)  Perhaps the labour I saw that's now etched into my memories was different to her "not too bad" one she was at ;)  Perhaps the "tagging out" WWWF-style and "can I go home now?" was all but a figment of my imagination :)  In any case, she's all well now and we're both so happy.

Labour is one of those things in life that once gone through, you feel like you've been initiated into some elite club, "the real world" perhaps?  Kinda like paying for your first bill with money you've earnt yourself (ok, more painful), spreading your wings for the first time when you get your driving licence (less fast, lots of waiting too though so similar in that respect), getting married (less ceremonies, food and generally a lot more uncomfortable).  I look at women with kids now and think, "you, ma'am, you have gone through so much to bring those children into this world!  They better appreciate it!".  I try not to look at women without kids :)

So, I'm sitting at home alone (well, not quite alone... with our hairy "first-born", who was actually adopted and smells like a dog...) while Ruth has one final night at the hospital and am trying to put in words how I feel, but it's very difficult.  It reminds of the hymn "Because he lives" which simply says it all (and now has a feeling attached to previously meaningless words):

"How sweet to hold a newborn baby
And feel the pride and joy he gives;"

I think all of Jude's uncles and aunties and grandmas and grandads are touched the same way we are and we're looking forward to sharing him with them.. and possibly scoring some free babysitting perhaps two nights a week at least and some movie tickets or at least some vouchers (Auntie Julie (Quirk)) :)  So far only family have visited cos we've been too tired and need time to rest and recover, so please be patient, you'll see him very soon!  Carrie and Ava got lucky and had an appointment at King Edwards right when Ruth was in theatre and I was alone, cold, sleepy, hungry (in survivor mode) and nervously waiting for my wife, so I was very appreciative of the company and the lunch.

I drive away from hospital missing him and just wanting to turn back and be with my family but am happy they're all healthy and happy.  When I drive towards hospital to see them I think someone might be making lasagne in the car, cutting up onions or something?  Either that or my eyes are getting sweaty!  Anyway, suffice it to say that I am just so proud of everyone and could not be happier with the little guy, with Ruth and with how things turned out.  Ruth's recovery has been really quick.

No doubt there's photos on friendface or bookfriend or whatever it's called (Ps Simon might be able to help me out with the name...) ;)  But there's some more on josh's blog http://blog.joshuaquirk.com.au; Hayley's flickr http://www.flickr.com/photos/25331735@N00/ and probably anywhere you can find a Carrie ;)  Here's some of Giorgio Maria's Casarotto's photos (famous Italian photographer and grandfather, and alledged perth mafia godfather)!  There'll be no shortage of photos with nearly every relative owning a pro camera and knowing how to wield it :)

[caption id="attachment_111" align="alignleft" width="300" caption="Jude (one day old)"]Jude (one day old)[/caption]

[caption id="attachment_117" align="alignleft" width="300" caption="Jude punching nonno (Grandad George)"]Jude punching George[/caption]

[caption id="attachment_119" align="alignleft" width="300" caption="Jude and Aunt 'Ayley (Westssidee)"]Jude and Aunt 'Ayley (Westssidee)[/caption]

[caption id="attachment_122" align="alignleft" width="300" caption="Sweet Jude"]Sweet Jude[/caption]

[caption id="attachment_115" align="alignleft" width="300" caption="Jude and Meme (Grandma Janine)"]Jude and Meme (Grandma Janine)[/caption]

We're very very appreciative to Naomi from the Family Birth Centre, and all the other staff there of course and to everyone in King Edwards now too who we're finding are also such caring and helpful people too.  I had a quick visit there after the birth (ie the family birth centre) with Ant & Hayley and Josh & Julie to say thanks and show some photos and just in case any of my companions needed some questions answered... although I think they are still at least 3 months away from revealing anything ;)

That's enough about feelings though, so welcome to the family, Jude.  You're already shaping up to be a really cool little guy, we've already fallen in love with you!  Everyone says you're just gorgeous and you've been a very easy little guy so far!  He's very alert and watchful already :)

I'll try to get some photos on my blog in the next couple of days but I have a feeling I'll be sleep deprived and otherwise busy!  Looking forward to all our friends coming to visit... in the alloted visiting times :) ... will see everyone soon.

I have to finish with a programmer's joke that noone will get and people will think my dad jokes are really lame, but Jude says "Hello World!".

Btw, feel free to call me on 0411 780 222 or @supertravio (for twits?) or supertravio@travio.net to say hello and come visit.  Today (22-Jan) will probably not be a good day, but call anyway and we'll see how we're going.

PS:

Nappy count:

Trav 2
Ruth 0

Bathing Jude counts:

Trav 1
Ruth 0

PPS noone's counting

PPPS I think you're going to have to start pulling your weight, Ruth ;)

PPPPS birth notice will be in today's (22-Jan) "The West" or "West Australian" for those that like to keep those things.  We have a copy of his birthday's "The West" from thoughtful Uncle Josh and Auntie Julie.  Did anyone spot the "Do you know this man..?" on the front cover!?  He's on the back page, seriously try it!!!

PPPPPS I was trying to do this today on the internet at King Edwards just outside the cafe downstairs but the 'L' and '.' keys at least weren't working so it was almost impossible to get to anything and proved too frustrating.
Wednesday 4.17am How sweet to hold a newborn baby
And feel the pride and joy he gives;

Wednesday, January 13, 2010

travio jnr update

With the due date looming (tomorrow) I thought i'd update the status of the baby bets.  Sadly only the following bets are still alive!  Looks like no first name rights to you Dad!

Still good..

Mum 14/1/2010
Trav 18/1/2010
Josh 16/1/2010
Julie 15/1/2010
Rach 16/1/2010
Clancy 16/1/2010
Mark 15/1/2010
Brent 16/1/2010

(Losers :) )

Dad 11/1/2010
Hayley 9/1/2010
Rhys 9/1/2010
Ruth 12/1/2010
Ant 6/1/2010
Ishi 8/1/2010
Trista 12/1/2010
John 10/1/2010