<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sambroblog.</title>
	<atom:link href="http://sambro.is-super-awesome.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://sambro.is-super-awesome.com</link>
	<description>A Blog. With words. And maybe pictures.</description>
	<lastBuildDate>Wed, 01 Feb 2012 10:42:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Switching from Gnome 3 to MATE</title>
		<link>http://sambro.is-super-awesome.com/2012/02/01/switching-from-gnome-3-to-mate/</link>
		<comments>http://sambro.is-super-awesome.com/2012/02/01/switching-from-gnome-3-to-mate/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 08:57:56 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[MATE]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=217</guid>
		<description><![CDATA[So my Linux distro of choice for quite a while has been Ubuntu. Unfortunately it seems that lately Canonical has embarked on a mission to destroy the desktop experience with religious fervor. I have no qualms in saying that I think Unity is the worst thing to ever happen to Ubuntu - it's a complete [...]]]></description>
			<content:encoded><![CDATA[<p>So my Linux distro of choice for quite a while has been Ubuntu. Unfortunately it seems that lately Canonical has embarked on a mission to destroy the desktop experience with religious fervor. I have no qualms in saying that I think Unity is the worst thing to ever happen to Ubuntu - it's a complete unmitigated disaster. How it managed to become the default overnight without rioting in the streets is beyond me - but I digress.</p>
<p>Of course there are other alternatives in the Desktop Linux scene; offerings such as <a href="http://www.xfce.org/">XFCE</a>, <a href="http://lxde.org/">LXDE</a> and <a href="http://www.kde.org/">KDE</a> all have their place. I personally don't have the time to familiarize myself with yet another desktop environment, especially given that my goal is to be running a Mac at work and at home. I had grown quite fond of GNOME 2 in previous releases of Ubuntu, so my next logical step was to use <a href="http://www.gnome.org/">GNOME 3</a>.</p>
<p>The problem with GNOME 3 is that of immaturity. It's still pretty rough around the edges (it crashes at least a couple of times a day for me under regular use), has very poor display driver support, and doesn't quite have the community momentum for themes and plugins like its predecessor had.</p>
<p>I've been using GNOME 3 for the past few months (at work and home) with the hopes that my gripes with it would be addressed shortly but unfortunately I'm yet to observe even incremental improvements in stability or performance. My work machine (which I'm using 8 hours a day) constantly needs gnome-shell restarts, and sometimes it locks up so bad I actually have to kill the whole session and lose everything I had open.  Recently my patience has worn thin enough that I started conspiring to try something (anything, really) new on my machine at work. The proverbial straw was broken when somehow my NVIDIA display drivers (custom installed in order to address a host of issues with gnome-shell) was broken so badly by an Ubuntu update that I had to boot into recovery to fix it. But wouldn't you know it, recovery console isn't working with my setup for some reason - it wouldn't detect my keyboard!</p>
<p>I had read about the <a href="http://mate-desktop.org/">MATE</a> project on the Linux Mint blog a few months back, so today I wondered how it had come along. The prospect of a pure GNOME 2 environment running in the latest Ubuntu sounded very promising indeed. I decided it was finally time to make the jump.</p>
<p>With a small amount of tinkering, I had a fully functional MATE session up and running in Ubuntu 11.10.  It took a whopping 10 minutes to get MATE fully operational. All I had to do was the following:</p>
<ul>
<li>sudo bash -c 'echo "deb http://tridex.net/repo/ubuntu/ oneiric main" >> /etc/apt/sources.list'</li>
<li>sudo apt-get update</li>
<li>sudo apt-get install mate-archive-keyring</li>
<li>sudo apt-get install mate-core</li>
<li>Logout, select MATE from the session list and log back in</li>
</ul>
<p>The thing that struck me immediately is HOW INSANELY FAST IT IS. Especially compared to GNOME 3/Unity. After getting Compiz up and running and using the desktop for an hour or two, I suddenly realized just how sorely I'd missed the polished and refined awesomeness that is GNO- er, MATE.</p>
<p>I am in the process of installing MATE on my home machine now so I can get as much exposure to MATE as possible over the coming weeks. I will be documenting my experiences here, and sharing all the gotchas I find as I go.</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2012/02/01/switching-from-gnome-3-to-mate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Glassfish 2 &amp; Grails 2 Logging</title>
		<link>http://sambro.is-super-awesome.com/2012/01/31/glassfish-2-grails-2-logging/</link>
		<comments>http://sambro.is-super-awesome.com/2012/01/31/glassfish-2-grails-2-logging/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 08:32:42 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Glassfish]]></category>
		<category><![CDATA[Grails 2]]></category>
		<category><![CDATA[JUL]]></category>
		<category><![CDATA[Log4j]]></category>
		<category><![CDATA[Slf4j]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=209</guid>
		<description><![CDATA[Grails 2 is now released, and no doubt many people will be upgrading from 1.3.7 shortly. This blog post serves as a quick HOWTO on a fairly common issue involving deploying a Grails 2 app to a Glassfish 2 container. That issue is getting logging working correctly. A quick rundown on how Grails 2 logging [...]]]></description>
			<content:encoded><![CDATA[<p>Grails 2 is now released, and no doubt many people will be upgrading from 1.3.7 shortly. This blog post serves as a quick HOWTO on a fairly common issue involving deploying a Grails 2 app to a Glassfish 2 container. That issue is getting logging working correctly.</p>
<p>A quick rundown on how Grails 2 logging works:</p>
<ul>
<li><a href="http://www.slf4j.org/">SLF4J</a> is used to handle logging</li>
<li>By default Grails uses <a href="http://logging.apache.org/log4j/1.2/">Log4j</a> as the logging provider. </li>
<li><a href="http://commons.apache.org/logging/">Jakarta Commons Logging (JCL)</a> is redirected to SLF4J using jcl-over-slf4j</li>
<li>java.util.logging is redirected to SLF4J in dev mode, but disabled in production environment by default</li>
</ul>
<p>With this default setup, you'll quickly discover that Grails logging ends up in standard out in Glassfish, which means that you can't use Glassfish admin to configure log levels at all with your deployed application. This is obviously not an ideal situation.</p>
<p>Glassfish only supports java.util.logging, so we need to tell Grails to log to this in order to play nicely with Glassfish.</p>
<p>Previously in Grails 1.3.7, we were using the technique Reiney Sadder outlined in his <a href="http://blog.saddey.net/2010/03/27/how-to-deploy-a-grails-application-to-glassfish/">excellent blog post</a> to remove log4j and install slf4j-jdk14 to redirect all logging to SLF4J into JUL. Unfortunately this technique no longer works in Grails 2, as Log4j support in Grails no longer comes from slf4j-log4j, but rather a core Grails plugin called "grails-plugin-log4j".</p>
<p>So, how do we achieve this in Grails 2? Simple! Just add the following to your BuildConfig.groovy:</p>
<pre class="brush: groovy; title: ; notranslate">
// Inside your grails.project.dependency.resolution closure:

inherits(&quot;global&quot;) {
	Environment.executeForCurrentEnvironment {
		production {
			excludes &quot;grails-plugin-log4j&quot;, &quot;log4j&quot;
		}
	}
}

dependencies {
	Environment.executeForCurrentEnvironment {
		production {
			runtime &quot;org.slf4j:slf4j-jdk14:1.6.4&quot;
		}
	}
}
</pre>
<p>This will disable log4j entirely in production environment and add the slf4j-jdk14 JUL bridge. </p>
<p>NOTE: Make sure you definitely have the following line added to your Config.groovy:</p>
<pre class="brush: groovy; title: ; notranslate">
grails.logging.jul.usebridge = false
</pre>
<p>You really should have this disabled for production anyway, as <a href="http://www.slf4j.org/legacy.html#jul-to-slf4j">it's not very performant</a>.</p>
<p>The BuildConfig.groovy change above completely disable log4j, so any log settings you have defined using the Log4j DSL in Config.groovy will not be recognized at all. This is why I only enabled it in production environment, it's still nice to be able to easily tweak logging settings for your development environment. If you really want to though, you can configure your own JUL logging.properties and just enable the SLF4J JUL bridge permanently.</p>
<p>Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2012/01/31/glassfish-2-grails-2-logging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inotify + Node + FTP = Easy-mode remote dev work</title>
		<link>http://sambro.is-super-awesome.com/2012/01/21/inotify-node-ftp-easy-mode-remote-dev-work/</link>
		<comments>http://sambro.is-super-awesome.com/2012/01/21/inotify-node-ftp-easy-mode-remote-dev-work/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 13:11:55 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[inotify]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=193</guid>
		<description><![CDATA[Pre-ramble Haven't updated my blog in a while, but I had a fun little win tonight that I thought I'd share with the lovely readers of this blog (you know I love all 3 of you). I am currently working fulltime at Wotif.com in Brisbane, and I'm extremely fortunate to be immersed in the weird [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Pre-ramble</strong></p>
<p>Haven't updated my blog in a while, but I had a fun little win tonight that I thought I'd share with the lovely readers of this blog (you know I love all 3 of you).</p>
<p>I am currently working fulltime at Wotif.com in Brisbane, and I'm extremely fortunate to be immersed in the weird and wondrous world of Groovy/Grails for the majority of application development I'm involved in. To make things even more awesome-er we're currently working a on a project that uses CouchDB/ElasticSearch as our primary data provider. Life is bliss. Well, mostly.</p>
<p><strong>The Problem</strong></p>
<p>I still have work come in occasionally from a long-time client I respect enough to give some time to on the weekend. Unfortunately this work is in the form of PHP4 code most of the time. And no, the pain doesn't just end there, usually the work is on a fairly large production Joomla 1.0 site. Needless to say, the technical debt flows freely.</p>
<p>Anyway, this particular site is a real pain to work on, as it's not really in a state where it can be run up locally without a fair amount of pain and misery. I haven't done much work for this particular client in the last few months, and thus I didn't really have a proper LAMP stack running on my machine at home (nor do I really want to). A more recent project I'd done for this client last year was a Joomla 1.5 site, where I had the luxury of "doing it right" - I had set the project up to easily be run up locally using some bash scripts, <a href="http://en.wikipedia.org/wiki/UnionFS">UnionFS</a>, and a little bit of voodoo. But no such win was to be had for this Joomla 1.0 site.</p>
<p>The work I needed to perform on the Joomla 1.0 site was considerable enough that the prospect of firing up Filezilla and manually FTPing changes was unbearable. In the past I've used Eclipse with an obscure plugin called <a href="http://sourceforge.net/projects/esftp/">ESFTP</a> to push my changes to the server as I develop. However this still has an obnoxious required manual step of clicking a button every time I want to push a file to the server.</p>
<p>I figured there had to be an easier way. Then I remembered seeing some cool inotify stuff in Node.js a while ago.</p>
<p><strong>The Solution</strong></p>
<p>I thought to myself: "Wouldn't it be cool if I had a little Node app running that monitored my project on the filesystem and FTP'd changes to the codebase as I made them?".</p>
<p>So I decided to cook something up. A couple of hours later I came up with this:</p>
<p><a href="https://gist.github.com/1652663">https://gist.github.com/1652663</a></p>
<p>I didn't end up using the libinotify bindings for Node.js, as it was a little too low level for a quick prototype. The main pain point was the fact that inotify isn't actually recursive, so you actually have to put together your own code that recursively creates watch descriptors for the directory structure, glue in new watch descriptors as new directories get created, and delete old descriptors as directories disappear. I instead opted to use the awesome inotifywait tool (which comes from the inotify-tools package in Ubuntu) which handles all the un-fun parts of inotify and instead sends nice little status updates on stdout.</p>
<p>Oh, and I was getting bizzare issues with the <a href="https://github.com/mscdex/node-ftp">node-ftp</a> library from NPM, so I just grabbed the latest from the git repo and threw it in with the script.</p>
<p>So now I just fire up this script with the FTP details and paths. It just sits there patiently and creates/deletes directories as needed, and pushes file changes/deletions as they occur.</p>
<p>Now this could definitely have easily been done using pretty much any language, but I think it's a pretty neat and elegant little CoffeeScript/Node solution <img src='http://sambro.is-super-awesome.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Speaking of Node/CoffeeScript, I've been working on a little project in all the spare time I can get. I'm excited to blog about some of the cool stuff I've found/done in that regard in the coming weeks!</p>
<p>That's all for now, internets.</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2012/01/21/inotify-node-ftp-easy-mode-remote-dev-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Listening for end of response with Node/Express.JS</title>
		<link>http://sambro.is-super-awesome.com/2011/06/27/listening-for-end-of-response-with-nodeexpress-js/</link>
		<comments>http://sambro.is-super-awesome.com/2011/06/27/listening-for-end-of-response-with-nodeexpress-js/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 06:44:44 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[express]]></category>
		<category><![CDATA[Node]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[redis]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=186</guid>
		<description><![CDATA[I'm currently working with CoffeeScript, Node, Express, and Redis to deliver on a quick'n'easy contract I've been put in charge of. This is the first time I've used any of these technologies in a proper commercial deliverables type project, and I have to say, it's been an absolute delight. An issue I ran into was [...]]]></description>
			<content:encoded><![CDATA[<p>I'm currently working with CoffeeScript, Node, Express, and Redis to deliver on a quick'n'easy contract I've been put in charge of. This is the first time I've used any of these technologies in a proper commercial deliverables type project, and I have to say, it's been an absolute delight.</p>
<p>An issue I ran into was I wanted to reduce the boilerplate on handling requests, so I wrote a quick route middleware in Express to create a client connection to Redis, assigning the connection to the request object for easy use . I also wanted to be clever and have this same middleware clean up after itself when the request ended. That is, I wanted the middleware to QUIT the Redis connection when the response had been sent.</p>
<p>Consulting the Express/Connect/Node docs yielded no clues as to how to do this, the closest hint I found was from the Node docs indicating that a http.ServerResponse is a WritableStream. I noticed WritableStreams had a "close" event that is supposed to be called when the Stream is no longer writable. I assumed that if you call <strong>.end()</strong> on a response then it should trigger this event, so my initial middleware looked like this:</p>
<pre class="brush: plain; title: ; notranslate">
setupRedisClient = (req, res, next) =&gt;
	req.redisClient = require(&quot;redis&quot;).createClient()

	cleanup = =&gt;
		console.log &quot;it worked!&quot;
		req.redisClient.quit()

	res.on &quot;close&quot;, cleanup
	res.on &quot;error&quot;, cleanup

	next()
</pre>
<p>I tried using this middleware in a route, and was sad to see that the event was not being triggered.</p>
<p>As a last resort I started digging through the Node source, and lo and behold! I found what I was looking for in <a href="https://github.com/joyent/node/blob/master/lib/http.js#L714">lib/http.js</a>. Turns out when you <strong>.end()</strong> your http response, it will emit a "finish" event.</p>
<p>Now my Redis middleware looks like so:</p>
<pre class="brush: plain; title: ; notranslate">
setupRedisClient = (req, res, next) =&gt;
	req.redisClient = require(&quot;redis&quot;).createClient()

	cleanup = =&gt;
		req.redisClient.quit()

	res.on &quot;finish&quot;, cleanup
	res.on &quot;error&quot;, cleanup

	next()
</pre>
<p>Incoming routes that need a Redis connection simply add this middleware, and hey presto! They can use req.redisClient to their hearts content. Once a response is sent back to the client, or an error occurs with the request, the Redis connection will be cleaned up automagically! Hurrah!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2011/06/27/listening-for-end-of-response-with-nodeexpress-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Open Graph HTML5 Validation Problems</title>
		<link>http://sambro.is-super-awesome.com/2011/05/18/facebook-open-graph-html5-validation-problems/</link>
		<comments>http://sambro.is-super-awesome.com/2011/05/18/facebook-open-graph-html5-validation-problems/#comments</comments>
		<pubDate>Wed, 18 May 2011 02:37:37 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Facebook Development]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook like button]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[open graph]]></category>
		<category><![CDATA[standards]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=179</guid>
		<description><![CDATA[I'm currently working on a site currently that uses a few Facebook "Like" buttons scattered around the place. As such the pages that can be "Liked" need a modest amount of Open Graph metadata embedded in them. The fun part of this is that the Open Graph specification states that OG metadata should be embedded [...]]]></description>
			<content:encoded><![CDATA[<p>I'm currently working on a site currently that uses a few <a href="http://developers.facebook.com/docs/reference/plugins/like/">Facebook "Like" buttons</a> scattered around the place. As such the pages that can be "Liked" need a modest amount of <a href="http://developers.facebook.com/docs/opengraph/">Open Graph metadata</a> embedded in them.</p>
<p>The fun part of this is that the <a href="http://ogp.me/">Open Graph specification</a> states that OG metadata should be embedded on the page like so:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;meta property=&quot;og:title&quot; content=&quot;The Rock&quot; /&gt;
&lt;meta property=&quot;og:type&quot; content=&quot;movie&quot; /&gt;
&lt;meta property=&quot;og:url&quot; content=&quot;http://www.imdb.com/title/tt0117500/&quot; /&gt;
&lt;meta property=&quot;og:image&quot; content=&quot;http://ia.media-imdb.com/images/rock.jpg&quot; /&gt;
</pre>
<p>The stupid thing is this is actually invalid HTML5. The HTML5 spec states that meta tags must use the <strong>name</strong>/<strong>content</strong> attributes, and because OG is based off <a href="http://en.wikipedia.org/wiki/RDFa">RDFa</a>, an XHTML draft, OG mandates that its metadata uses the <strong>property</strong> attribute instead of the <strong>name</strong> attribute. After <a href="http://www.google.com/search?q=meta+property+invalid&#038;hl=en">Googling</a> <a href="http://www.google.com/search?q=og:title+meta+property+invalid+markup&#038;hl=en">around</a> a <a href="http://www.google.com/search?q=html5+open+graph+meta+property&#038;hl=en">bit</a> I came to the "conclusion" that the only way to get a page to validate with Open Graph tags was to switch to XHTML.</p>
<p>Screw that.</p>
<p>Instead I tried just changing the property attributes back to name and run it through the <a href="http://developers.facebook.com/tools/lint">Facebook URL Linter</a> tool. Turns out, Facebook will grumble at you, but they will still parse OG data out of standard meta tags, and Like Buttons will use that metadata just fine.</p>
<p>So, in summary, if you're authoring a straight HTML5 (non-XHTML) site, you have a choice between pissing off W3C, or pissing off Facebook. It's your call.</p>
<p>I've put up two examples for reference, one uses <a href="http://sambro.is-super-awesome.com/lolopengraph-openfailmorelikeit/doesntvalidate.html">meta property (non-standard)</a>, the other uses <a href="http://sambro.is-super-awesome.com/lolopengraph-openfailmorelikeit/doesvalidate.html">meta name (standard)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2011/05/18/facebook-open-graph-html5-validation-problems/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>No.de coupon</title>
		<link>http://sambro.is-super-awesome.com/2011/03/05/no-de-coupon/</link>
		<comments>http://sambro.is-super-awesome.com/2011/03/05/no-de-coupon/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 00:36:25 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[No.de]]></category>
		<category><![CDATA[Node]]></category>
		<category><![CDATA[SSJS]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=177</guid>
		<description><![CDATA[Huzzah! Got my no.de coupon in the mail a couple of days ago. Now I just gotta figure out what I wanna host at http://sammeh.no.de/....]]></description>
			<content:encoded><![CDATA[<p>Huzzah!</p>
<p>Got my no.de coupon in the mail a couple of days ago.</p>
<p>Now I just gotta figure out what I wanna host at <a href="http://sammeh.no.de/">http://sammeh.no.de/</a>....</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2011/03/05/no-de-coupon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a proper Buffer in a Node C++ Addon</title>
		<link>http://sambro.is-super-awesome.com/2011/03/03/creating-a-proper-buffer-in-a-node-c-addon/</link>
		<comments>http://sambro.is-super-awesome.com/2011/03/03/creating-a-proper-buffer-in-a-node-c-addon/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 23:14:53 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Buffer]]></category>
		<category><![CDATA[Node]]></category>
		<category><![CDATA[SlowBuffer]]></category>
		<category><![CDATA[SSJS]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=171</guid>
		<description><![CDATA[Despite the wordy title, it's actually a fairly simple problem, with a fairly simple solution. Let's say you have some binary data you want to provide to Node Javascript. No problem, Node has Buffers for that. Digging through the Node.js source code, you find node_buffer.h, which promises a utopia of an ObjectWrap goodness; you can [...]]]></description>
			<content:encoded><![CDATA[<p>Despite the wordy title, it's actually a fairly simple problem, with a fairly simple solution.</p>
<p>Let's say you have some binary data you want to provide to Node Javascript. No problem, Node has <a href="http://nodejs.org/docs/v0.4.1/api/buffers.html">Buffers</a> for that. Digging through the Node.js source code, you find <a href="https://github.com/joyent/node/blob/master/src/node_buffer.h">node_buffer.h</a>, which promises a utopia of an <a href="https://github.com/joyent/node/blob/master/src/node_object_wrap.h">ObjectWrap</a> goodness; you can even memcpy your binary data directly to it using Buffer::Data(bufferObject). </p>
<p>"Fantastic! I'll rock one of those buffers and simply return `bufferObject->handle_`!", I hear you exclaim. Not so fast stud.</p>
<p>If the client were to use this Buffer, they'd get a nasty surprise. It's not a Buffer. You see, Node.js has re-implemented Buffers since 0.2. The Buffer you're playing with from node_buffer.h is actually a <em><strong>SlowBuffer</strong></em>. As the name implies, it's working directly on the heap-allocated memory chunk, so alot of operations on it are quite inefficient. Worse still, the interface provided on SlowBuffer is actually different to the Node.js documentation. Allow me to explain.</p>
<p>The Buffer you're used to dealing with from Node.js user code actually originates from <a href="https://github.com/joyent/node/blob/master/lib/buffer.js">buffer.js</a>. These Buffers are actually just "views" on a proper SlowBuffer, so operations like slicing are literally as quick as allocating a new Buffer object that views the SlowBuffer at a different offset and max length.</p>
<p>So how do you create one of these badboys from C++ to pass directly back to JS calling code? Glad you asked. Like so:</p>
<pre class="brush: cpp; title: ; notranslate">
	// Some data we want to provide to Node.js userland code.
	// This can be binary of course.
	const char *data = &quot;Hello world!&quot;;
	int length = strlen(data);

	// This is Buffer that actually makes heap-allocated raw binary available
	// to userland code.
	node::Buffer *slowBuffer = node::Buffer::New(length);

	// Buffer:Data gives us a yummy void* pointer to play with to our hearts
	// content.
	memcpy(node::Buffer::Data(slowBuffer), data, length);

	// Now we need to create the JS version of the Buffer I was telling you about.
	// To do that we need to actually pull it from the execution context.
	// First step is to get a handle to the global object.
	v8::Local&lt;v8::Object&gt; globalObj = v8::Context::GetCurrent()-&gt;Global();

	// Now we need to grab the Buffer constructor function.
	v8::Local&lt;v8::Function&gt; bufferConstructor = v8::Local&lt;v8::Function&gt;::Cast(globalObj-&gt;Get(v8::String::New(&quot;Buffer&quot;)));

	// Great. We can use this constructor function to allocate new Buffers.
	// Let's do that now. First we need to provide the correct arguments.
	// First argument is the JS object Handle for the SlowBuffer.
	// Second arg is the length of the SlowBuffer.
	// Third arg is the offset in the SlowBuffer we want the .. &quot;Fast&quot;Buffer to start at.
	v8::Handle&lt;v8::Value&gt; constructorArgs[3] = { slowBuffer-&gt;handle_, v8::Integer::New(length), v8::Integer::New(0) };

	// Now we have our constructor, and our constructor args. Let's create the
	// damn Buffer already!
	v8::Local&lt;v8::Object&gt; actualBuffer = bufferConstructor-&gt;NewInstance(3, constructorArgs);

	// This Buffer can now be provided to the calling JS code as easy as this:
	return scope.Close(actualBuffer);
</pre>
<p>And that's all folks!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2011/03/03/creating-a-proper-buffer-in-a-node-c-addon/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Node.js</title>
		<link>http://sambro.is-super-awesome.com/2011/03/03/node-js/</link>
		<comments>http://sambro.is-super-awesome.com/2011/03/03/node-js/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 22:47:40 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Node]]></category>
		<category><![CDATA[Server Side Javascript]]></category>
		<category><![CDATA[SSJS]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=163</guid>
		<description><![CDATA[Since I haven't updated my blog for a few months I figure now would be a good time to do a bit of a brain dump on what is interesting to me nowadays. Currently I'm completely immersed in the weird and wondrous world of Node.js. If you are even remotely interested in anything related to [...]]]></description>
			<content:encoded><![CDATA[<p>Since I haven't updated my blog for a few months I figure now would be a good time to do a bit of a brain dump on what is interesting to me nowadays.</p>
<p>Currently I'm completely immersed in the weird and wondrous world of <a href="http://www.nodejs.org">Node.js</a>. If you are even remotely interested in anything related to web development/engineering, you should already know about Node. Briefly, it's a server side JavaScript (SSJS) implementation built on top of Google's V8 JavaScript engine. It's blisteringly fast, and has already been employed in some big projects to solve some pretty insane scaling problems engineers are facing in large websites.</p>
<p>Currently I'm just getting myself acquainted with Node.js, I've written some random libs that are on my <a href="http://www.github.com/samcday">Github</a>. Currently I'm writing a native Node extension called <a href="http://www.github.com/samcday/node-gitteh">node-gitteh</a>, which provides bindings to the excellent C library <a href="http://libgit2.github.com">libgit2</a>. I'll be using these bindings to manipulate Git repositories from Node as part of a little project I'm going to undertake (more on that later).</p>
<p>Writing these bindings has been interesting, given that I'm writing C++ code for the first time in years, and having more trouble remembering how to use an STL map<> than I am wrangling the bizarro V8 API. I think this definitely warrants a tip of the hat to Google, the internals of V8 are pretty accessible; my only gripe with V8 is a pretty painful lack of hand-holding documentation, however there were plenty of examples of stuff on Github from other kindred Node spirits who've written bindings for things like <a href="https://github.com/taggon/node-gd">GD</a>, <a href="https://github.com/Sannis/node-mysql-libmysqlclient">Mysql</a>, <a href="https://github.com/polotek/libxmljs">libxml2</a> and the like.</p>
<p>The thing that has impressed me about Node the most is the amount of talent the community is comprised of. Node is only just over a year old and there is already a mass of quality libraries and frameworks. One I particularly love is <a href="http://www.github.com/cloudhead/vows">Vows</a>, which has made TDD an absolute breeze in Node. If you're just starting out with Node, I thoroughly recommend you get into the habit of using Vows to test your code, ideally writing the tests before you even launch into your next Javascripty wet dream. Seriously, it's worth it.</p>
<p>Of course, Node is not without it's faults. The biggest one currently is lack of threaded-ness, or any kind of concurrency control from JavaScript. Many will argue this is a Good Thing, as it abstracts away the misery that is semaphores, locks, re-entrancy and other goodies that come with thread-safety. However I still think there should be first-class support for concurrent operations in Node user land (read: JavaScript code).</p>
<p>There are some solutions out there that utilize nodes ability to spawn child processes and communicate/control them effectively, to the effect of running a pool of Node processes. However I view these as a kludge, as Node processes do have a pretty decent memory footprint on initialization. Given that Chrome has a way of running completely sandboxes JavaScript execution contexts in parallel (that is, a blocking script in one frame wouldn't block other frames), I'm sure there's an elegant solution to be found.</p>
<p>That's all for now!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2011/03/03/node-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gotcha: Flash-based Upload widgets stopping mid upload</title>
		<link>http://sambro.is-super-awesome.com/2010/10/28/gotcha-flash-based-upload-widgets-stopping-mid-upload/</link>
		<comments>http://sambro.is-super-awesome.com/2010/10/28/gotcha-flash-based-upload-widgets-stopping-mid-upload/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 11:51:53 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[upload problems]]></category>
		<category><![CDATA[yahoo ui]]></category>
		<category><![CDATA[yui]]></category>
		<category><![CDATA[yui uploader]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=161</guid>
		<description><![CDATA[Posting in my blog for the first time in months. I just had to put this one up somewhere because it has been causing me to rip my hair out for the past 2 freakin' hours! I have a page accepting uploads (using Yahoo UI uploader) for large files. I had it working a while [...]]]></description>
			<content:encoded><![CDATA[<p>Posting in my blog for the first time in months. I just had to put this one up somewhere because it has been causing me to rip my hair out for the past 2 freakin' hours!</p>
<p>I have a page accepting uploads (using Yahoo UI uploader) for large files. I had it working a while ago but then I modified the whole design quite alot recently. All of a sudden when testing the uploader would randomly stop uploading after a couple of seconds, with absolutely no warning. I went so far as to trace the Flash logging output coming from the YAHOO uploader.swf to see what was going on - sure enough, it was spamming to the console the current upload status, and then randomly stopping out of the blue. No error messages. No warnings. No nothin'.</p>
<p>So it turns out I had the browse button sitting in a div with some text, and when the upload button was clicked, I was calling jQuery("#browseContainer").slideUp() to hide the text and browse button. Boom, that's what was causing it. No shit.</p>
<p>Turns out jQuery's slideUp() will put display:none on the animated element when it's done ... slideUpping it. Awesome story though - Flash plugins decide they shouldn't be running anymore when their parent element has display:block on it. No shit. This might be documented somewhere, but I'll be damned if it's common knowledge. Maybe I'm a total retard ...</p>
<p>Hope this helps someone.</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/10/28/gotcha-flash-based-upload-widgets-stopping-mid-upload/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Platform updates &#8211; w00t!</title>
		<link>http://sambro.is-super-awesome.com/2010/08/30/facebook-platform-updates-w00t/</link>
		<comments>http://sambro.is-super-awesome.com/2010/08/30/facebook-platform-updates-w00t/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 03:44:30 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Facebook Development]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook platform]]></category>
		<category><![CDATA[fbjs]]></category>
		<category><![CDATA[fbml]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=155</guid>
		<description><![CDATA[According to this blog post over at developers.facebook.com, some exciting changes are coming to the Facebook Platform. I'm a little slow on the uptake here, the blog update I'm referring to is now 10 days old. I haven't been in the Facebook dev world of late, so I hope you'll forgive me for regurgitating old [...]]]></description>
			<content:encoded><![CDATA[<p>According to <a href="http://developers.facebook.com/blog/post/402">this blog post</a> over at developers.facebook.com, some exciting changes are coming to the Facebook Platform.</p>
<p>I'm a little slow on the uptake here, the blog update I'm referring to is now 10 days old. I haven't been in the Facebook dev world of late, so I hope you'll forgive me for regurgitating old news.</p>
<p>The big update for me is in the 4th paragraph:</p>
<blockquote><p>
We are also moving toward IFrames instead of FBML for both canvas applications and Page tabs. As a part of this process, we will be standardizing on a small set of core FBML tags that will work with both applications on Facebook and external Web pages via our JavaScript SDK, effectively eliminating the technical difference between developing an application on and off Facebook.com.
</p></blockquote>
<p>This is excellent! I have actually been holding my breath for something like this for a while now. The restriction of FBML only content for tabs has been extremely restrictive, here are a handful of reasons why:</p>
<ul>
<li><strong>Very strict HTML parsing</strong> - because the Platform was rendering tabs inline previously, it of course had to be VERY careful in how it handled offsite data, to protect users from all manner of scams/attacks. Now full flexibility is available because your iFrame is yours to control.</li>
<li><strong>Insanely strict JS parsing</strong> - same as first point, application tabs could only leverage basic Javascript and the unwieldy, poorly documented FBJS (Facebook Javascript). Now, you're free to access manipulate your IFrame document/window objects, DOM manipulate, include third party JS libs, etc, all to your hearts content.</li>
<li><strong>Embedded media was a pain</strong> - Granted, the tab FBML *did* allow you to embed Flash and AIR apps etc, but there were countless threads on the forum outlining issues they were having interacting with the host page, etc.</li>
<li><b>Tab activation policies</b> - There were some extremely frustrating rules with the way tabs were allowed to be "activated". No JS/FBJS was allowed to execute until the user had interacted with the tab in some manner, such as focusing a form element or clicking somewhere. This made it very cumbersome to implement any meaningful interactions with the user; alot of obnoxious boilerplate code had to be written for various ways in which you may actually start doing anything meaningful from JS, like AJAX requests.</li>
<li><b>... and lots more</b> Everything from CSS parsing to the occasional time where the tab would just sit in an endless loading display when clicked. When I was writing a tab page I remember bashing my head against the wall trying to get some content to sit nicely in a cross browser fashion... it would have been easy under normal circumstances, but the Platform tab flavour was refusing to accept the *display: inline IE hack in the CSS. Joy.</li>
</ul>
<p>This is going to really open up some great possibilities for interactive, rich web applications. I really cannot wait for this feature to be rolled out.</p>
<p>This news does come with some disappointment however; the sixth paragraph on the developers blog states the following:</p>
<blockquote><p>Finally, due to low usage rates, we will remove application tabs from user profiles in the next couple months. Application tabs will continue to be supported on Facebook Pages.</p></blockquote>
<p>There are plenty of great use cases to have application tabs on a user profile page. My personal Facebook profile has a tab that displays my latest last.fm scrobbles, my latest blog posts, etc. Personally, I believe that if the adoption rate for user profile tabs is low, the Facebook team should be coming up with ways to increase user acceptance of this feature, rather than removing it all together. Besides, the functionality in Facebook Page tabs is pretty much identical to the user profile equivalents... Why not support both?</p>
<p>There's other goodies in the developer blog update too, such as <a href="http://developers.facebook.com/roadmap/deprecations">cleaning up the REST API</a> considerably.</p>
<p>All in all, exciting changes coming to the Facebook platform in the coming months!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/08/30/facebook-platform-updates-w00t/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

