<?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>Record and Reverie</title>
	<atom:link href="http://www.cod3r.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cod3r.com</link>
	<description>General things I find interesting</description>
	<lastBuildDate>Tue, 17 Apr 2012 02:34:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>What Objective-C can learn from Java, Part 5 (Exceptions)</title>
		<link>http://www.cod3r.com/2012/04/what-objective-c-can-learn-from-java-part-5-exceptions/</link>
		<comments>http://www.cod3r.com/2012/04/what-objective-c-can-learn-from-java-part-5-exceptions/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 02:32:47 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=526</guid>
		<description><![CDATA[This is one past the last is a series of blog posts I’m writing on things that Objective-C can learn from Java. I&#8217;m writing this because I&#8217;m seeing a series of ignorant tweets stating how much Java sucks. The other parts can be found here: Part 1 (Generics) Part 2 (Abstract Classes) Part 3 (Single [...]]]></description>
			<content:encoded><![CDATA[<p>This is one past the last is a series of blog posts I’m writing on things that Objective-C can learn from Java.  I&#8217;m writing this because I&#8217;m seeing a series of ignorant tweets stating how much Java sucks.  The other parts can be found here:<br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-1-generics/">Part 1 (Generics)</a><br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-2-abstract-classes/">Part 2 (Abstract Classes)</a><br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-3-single-source-file/">Part 3 (Single Source File)</a><br />
<a href="http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/">Part 4 (Namespace)</a></p>
<p>Anyone who programs in Java for a short period of time becomes well aware of Java&#8217;s exceptions.  To the new programmer, they may be a bit of an annoyance, but to anyone designing enterprise-level code, they are a necessity.  Objective-C has exceptions too, but they are so weakly defined in the language and so overlooked, it&#8217;s almost as if they were nothing more than an afterthought.  In fact, one can argue that the exception handling in C++ is superior to what one would find in Objective-C.</p>
<p>In Java, the exception handling is of the familiar:<br />
<code><br />
try {<br />
 &nbsp; &lt;code that throws exceptions here&gt;<br />
} catch (ExceptionTypeA e) {<br />
 &nbsp; &lt;code to handle exception type a here&gt;<br />
} catch (Exception e) {<br />
 &nbsp; &lt;code to handle other exceptions here&gt;<br />
} finally {<br />
 &nbsp; &lt;code to execute regardless of whether an exception was thrown or not&gt;<br />
}<br />
</code></p>
<p>Of course, in the above, the catch statement is optional if one wants the exception to propagate outside of the block and the finally is optional if one doesn&#8217;t have code that needs to be executed in all cases.  This block is even more powerful in Java 7, with its try-with-resources ability, but I&#8217;ll leave that point out for now.  In Objective-C, the block looks like the following:</p>
<p><code><br />
@try {<br />
 &nbsp; &lt;code that throws exceptions here&gt;<br />
} @catch (ExceptionTypeA e) {<br />
 &nbsp; &lt;code to handle exception type a here&gt;<br />
} @catch (Exception e) {<br />
 &nbsp; &lt;code to handle other exceptions here&gt;<br />
} @finally {<br />
 &nbsp; &lt;code to execute regardless of whether an exception was thrown or not&gt;<br />
}<br />
</code></p>
<p>It looks very similar. At a first glace, one may think that the two are the same, but appearances are deceiving.  In Java, there are two different kinds of exceptions, checked and unchecked.  Checked exceptions are ones that a function may throw, that all callers must handle.  This is the familiar <strong>throws</strong> declaration.  Objective-C only has unchecked exceptions, or runtime exceptions.  Additionally, exceptions are heavily discouraged in Objective-C, to quote the documentation:</p>
<blockquote><p>In many environments, use of exceptions is fairly commonplace. For example, you might throw an exception to signal that a routine could not execute normally—such as when a file is missing or data could not be parsed correctly. Exceptions are resource-intensive in Objective-C. You should not use exceptions for general flow-control, or simply to signify errors. Instead you should use the return value of a method or function to indicate that an error has occurred, and provide information about the problem in an error object.</p></blockquote>
<p>One part that is missing from the above is that a thrown exception bypasses ARC, meaning that throwing an exception will very likely cause a memory leak.  It should be noted that stack objects are freed and even have their destructors called in C++ when an exception is thrown.  Here is a case where C++ is superior to Objective-C (I never though I&#8217;d see myself write that).</p>
<p>So, from this, one can conclude that the use of exceptions in Object-C is discouraged at best, worthless at worst.  Apple&#8217;s documentation encouraged using an error object, but this method is very lacking.  These error conditions are rarely checked in practice, and the object tends to be used again causing more errors that are not checked, and so forth.  In a system using exceptions, where one is forced to handle the exceptions, the error handling can be put in a single location for all the functions in the frame which can throw that exception, avoiding the tedious error checking after every single function call.</p>
<p>Additionally, returning an error code is lacking in terms of context.  Java&#8217;s exceptions contain stack traces and the ability to nest exceptions.  One common method, especially in library code, is to contain a thrown exception inside another exception, providing additional information, and throw the new resulting exception.  Then, when this exception is finally caught, a lot more information is available than a simple &#8220;this type of error occurred.&#8221;</p>
<p>So, what does it take to fix this?  The changes are likely very significant.  Apple did improve exception handling in Objective-C 2, but they still failed to bring it up to where Java has been in the beginning.  Their changes seem to suggest they knew that Objective-C&#8217;s exception handling was lacking, but they didn&#8217;t invest enough resources to bring it up to par.  This either means they don&#8217;t care, or that the changes were too significant.  I&#8217;m going to lean toward the latter since my knowledge of the Objective-C runtimes leads me to believe that it cannot really be made to handle exceptions properly.</p>
<p>Impact on Runtime:<br />
Guessing here:  Significant.  The runtime would need to be completely reworked to handle exceptions at every stage.  ARC would need significant work and throwing/catching exceptions would need to be made significantly cheaper.</p>
<p>Impact on Code:<br />
Adding checked exceptions to the code would require adding more syntax sugar to method calls and a lot of code would need to be reworked to handle exceptions instead of checking error codes.  Random errors would be less likely to be swallowed, and users will have a better idea as to the true nature of their problem (no more stepping through assembly in a library tracking down what should have been a thrown exception as I&#8217;ve had to do in the past).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2012/04/what-objective-c-can-learn-from-java-part-5-exceptions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Switched to Linux</title>
		<link>http://www.cod3r.com/2012/04/switched-to-linux/</link>
		<comments>http://www.cod3r.com/2012/04/switched-to-linux/#comments</comments>
		<pubDate>Sun, 01 Apr 2012 02:54:25 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=522</guid>
		<description><![CDATA[In one of my previous posts, I had mentioned how to install FreeBSD on ZFS. I was doing this for my file server, which I ran in this configuration for quite some time. It worked well for a while, but then I decided that FreeBSD was too constraining. This came when I was attempting to [...]]]></description>
			<content:encoded><![CDATA[<p>In one of my previous posts, I had mentioned how to install FreeBSD on ZFS.  I was doing this for my file server, which I ran in this configuration for quite some time.  It worked well for a while, but then I decided that FreeBSD was too constraining.  This came when I was attempting to setup a process to rip media from DVDs and BluRay disks.  I noticed that Handbrake doesn&#8217;t run natively, but is available via a port.  The port doesn&#8217;t contain the GUI though; everything must be done on the command line.  Then I looked at the tools necessary to rip from a BluRay disk, most notably MakeMKV.  I could not get this tool to run on FreeBSD at all.  Lastly, I could not execute any SWT-based java application because there is no native library for SWT in FreeBSD and the linux compatibility layer didn&#8217;t cut it.</p>
<p>So, I changed the server to run Ubuntu.  I wanted to be able to make the raid drives spin down, so I needed to boot off different drives.  I ordered two USB flash drives, set them up in a software raid 1, and installed the OS on it.  I considered running root off ZFS, but the ZFS boot in linux is more primitive.  I cannot boot off raidz1 nor raidz2, so booting off the existing raid was out, if I wanted to do so.  Additionally, the ZFS boot appears to not be able to boot off USB, so that pretty much killed it.  Later down the road, I&#8217;ll buy a pair of SSD drives for the boot drive.  It looks like there it shouldn&#8217;t have issue with booting off ZFS, in a mirror configuration.</p>
<p>In some ways I&#8217;m said to see FreeBSD go, but I really need more functionality with the machine.  FreeBSD is a nice stable server, but it&#8217;s so difficult to make it do anything beyond the standard fair.  It&#8217;s package management and port system is more difficult to use than apt-get.  Also, Ubuntu used by more people than FreeBSD, so it&#8217;s a more likely target for peoples&#8217; software development.  Lastly, SWT based java projects have no problems running on it, like the one I made to stream to my GoogleTV.  So, now my server is running Ubuntu going forward.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2012/04/switched-to-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Goodbye Roku, Hello GoogleTV</title>
		<link>http://www.cod3r.com/2011/12/goodbye-roku-hello-googletv/</link>
		<comments>http://www.cod3r.com/2011/12/goodbye-roku-hello-googletv/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 16:37:46 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=509</guid>
		<description><![CDATA[In my previous post, I said &#8220;I think I’ll elect to forgo a player for an external drive and rip every disk that I might buy.&#8221; That thought didn&#8217;t last very long. I decided to buy a Sony NSZ-GT1 which contains both a BluRay player and a GoogleTV together. I did this because I finally [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous post, I said &#8220;I think I’ll elect to forgo a player for an external drive and rip every disk that I might buy.&#8221;  That thought didn&#8217;t last very long.  I decided to buy a Sony NSZ-GT1 which contains both a BluRay player and a GoogleTV together.  I did this because I finally realized that the Roku that bought was never going to live up to my requirements, especially amid their numerous regressions in firmware updates.</p>
<p>So, I bought a Roku a few months ago after my dad bought one.  He got one of the first generation devices, as well as a second.  It was able to play his ripped media, with a little coaxing, but the feature that caught both of our attentions was the 1080p playback.  I decided to buy a second generation as well, since it had the ability to create third-party apps (they call them channels).</p>
<p>I started to program for the Roku, only to be first struck by the programming language.  While it has similarities to several other scripting languages, it is a new programming language.  Those out there familiar with the realities in computer science are screaming in the heads how this is a poor decision, but they made it anyway.  I was then struck by the complete lack of library availability.  Unfortunately, I had allowed myself to accept the premise that I had no choice in the matter and tried my best to plow on.  My father and I had designed a Java server, which facilitated transcoding of files to be served to the Roku.  I then started to add in the metadata features found in <a href="http://appletv.nanopi.net">Sapphire</a> to this server.  I had browsing working from the device as well as playback initiated from the device.  It was starting to look like a replacement for my AppleTV running Sapphire.</p>
<p>Then came the updates.  Roku issues a firmware update, which caused numerous problems.  The most notable was when one would play an MP3 on the first generation device (streaming a radio station for instance), then later played an MP4 with H.264, the device locked up requiring a reboot.  This bug took a month and a half to fix.  Additionally, the HLS streaming, which is what&#8217;s used to deliver the transcoded data to the device, was suffering from numerous audio dropouts.  Supposedly, this bug was fixed in the update that was released today, but I&#8217;ve found reports of this bug in the firmware betas dating as far back as May.  This means that roku was aware of the regression for 5 months before releasing the firmware.  Furthermore, try to report this bug on their forums, and the fanbois descend on you like a coming plague, insisting that nothing is broken, or that a fix is coming and you must be patient.  I&#8217;ve even seen some do both, even though they are diametrically apposed positions.  I then noticed a firmware update on my second generation roku including some of the same regressions.</p>
<p>I&#8217;ve had it.</p>
<p>I decided to get something else.  When I looked at the list of options, I narrowed my choice down to AndroidTV and GoogleTV.  AndroidTV is essentially hardware vendors taking the open sourced Android OS (the versions that are), and putting in on their devices.  GoogleTV is the Android OS, with some additional addons including a large host of codec/container support.  I went with the latter, so I now had to pick which device.  Sony makes a BluRay player and several TVs, and Logitech used to make their Revue.  I went with the BluRay player since it was not discontinued and I didn&#8217;t want to buy a TV right now.  Also, the GoogleTV&#8217;s new firmware is based on Android 3.1, and the AndroidTV devices are mostly on 2.2 or 2.3.</p>
<p>When the device arrived, I started doing some tests.  It played nearly everything I threw at it without issue.  I played everything over http, just giving the built-in VideoView class a URL to play, and it played it.  I tested MKV, AVI, MP4, and MKV files.  All had no issues.  It even played the killa sample, which is something that the roku failed to play.  The programming language is far better, since they used Java, and the programming environment actually works instead of the occasional lockup of the device in the debugger from which the roku suffers.  It&#8217;s also much faster, and stable.  My dad found that Amazon was still selling the Revue, so he bought one based on these results.  I don&#8217;t know what we are going to do with our roku devices.  I expect I may finish the Angry Birds levels, then call it failed experiment and box it up.</p>
<p>In short, don&#8217;t buy from roku.  Buy a GoogleTV instead.  Yes, they are more expensive, but you truly get what you pay for here.  The programming environment is far superior, which means the apps will be better.  The device works, and it appears that Google actually does regression testing.  Additionally, Google appears to be <a href="http://www.engadget.com/2011/12/07/googles-eric-schmidt-sees-google-tv-embedded-in-most-new-tvs-by/">ambitious in the devices future</a>.  It looks like GoogleTV truly is the route to go.  I just wish I had seen it earlier.</p>
<p>BTW, I plan on fully porting Sapphire over to work on the GoogleTV in a client-server relationship.  I&#8217;m doing this because I plan to allow sharing a single library across multiple devices.  I don&#8217;t know yet whether I intend to release it to the public.  Sometimes it is nice not having to deal with &#8220;customer&#8221; support.  Browsing and playback is done, as well as an importer to read the previous version&#8217;s metadata.  All that&#8217;s left is the metadata importing of new files.  Time will tell on where I go with this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2011/12/goodbye-roku-hello-googletv/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Case for Ripping Media</title>
		<link>http://www.cod3r.com/2011/11/the-case-for-ripping-media/</link>
		<comments>http://www.cod3r.com/2011/11/the-case-for-ripping-media/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 02:17:23 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=501</guid>
		<description><![CDATA[As some of you may know, I&#8217;ve ripped every DVD I own and store them on a file server. It&#8217;s a lot of space and it took a lot of time, but for my uses, it&#8217;s worth it. I started this because one movie, I don&#8217;t remember which one, forced me to wait on FBI [...]]]></description>
			<content:encoded><![CDATA[<p>As some of you may know, I&#8217;ve ripped every DVD I own and store them on a file server.  It&#8217;s a lot of space and it took a lot of time, but for my uses, it&#8217;s worth it.</p>
<p>I started this because one movie, I don&#8217;t remember which one, forced me to wait on FBI warning, another copyright violation warning, the same in French, and a disclaimer.  Then it displayed two previews and a lengthy menu before I could hit play.  This was followed by another lengthy menu animation, studio logos, and finally the movie.  In the whole process, the studio logos and the previews were the only portions I was able to skip, the other screens marked as not skippable on the DVD.  Now that I have my DVDs ripped, when I want to watch a movie, I browse my collection on the TV, and play the movie.  No warnings, no menus, just the movie.  I actually moved 8 months ago, and I have yet to unpack the DVD player.</p>
<p>This past weekend, I was at my parents&#8217; house and I played a few of their BluRay disks.  One movie, I think it was Flyboys, spent a considerable amount of time on the loading screen, had large sections of menus/screens that were not skippable, even included a section where it tried to download a trailer.  Once the movie started playing, I paused it and to help feed some kitties and give them attention for a few minutes only to return to a custom screen saver of some sort.  The movie would <strong>not resume</strong>.  Upon repeating the process, a total of 15 minutes was wasted excluding the time spent with the movie paused.</p>
<p>So now, I seriously question the value of keeping media in these physical formats.  I was considering BluRay in the near future, but now I think I&#8217;ll elect to forgo a player for an external drive and rip every disk that I might buy.  Now I just need to find a good external drive that allows easy ripping.  Thoughts?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2011/11/the-case-for-ripping-media/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>FreeBSD with ZFS root</title>
		<link>http://www.cod3r.com/2011/10/freebsd-with-zfs-root/</link>
		<comments>http://www.cod3r.com/2011/10/freebsd-with-zfs-root/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 02:00:55 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=489</guid>
		<description><![CDATA[It&#8217;s been a while since I posted here. I&#8217;ve been busy with a new job, new house, and a bunch of other things. One of these things was setting up my new file server. This is something that&#8217;s been in the works for a long time, as can be seen from the various posts on [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I posted here.  I&#8217;ve been busy with a new job, new house, and a bunch of other things.  One of these things was setting up my new file server.  This is something that&#8217;s been in the works for a long time, as can be seen from the various posts on <a href="http://www.cod3r.com/tag/zfs/">ZFS</a>.  I spent a long time researching this, and finally came up with my solution:</p>
<p>I did consider <a href="http://www.freenas.org/">FreeNAS</a> for a really long time.  It is essentially a <a href="http://freebsd.org">FreeBSD</a> install with most of the administrative work done for you through a web-based GUI.  It hit most of my checkboxes in that it supported ZFS, AFP, Bonjour, and a few others.  While this is nice, I found it also to be limiting when one wants to stray off the beaten path.  I didn&#8217;t want to lose ZFS, but I wanted something where I could tinker.  I decided to go with FreeBSD.</p>
<p>One of the first things I tried with FreeBSD, as the topic indicates, is to put the root filesystem on ZFS.  I followed an <a href="http://wiki.freebsd.org/RootOnZFS/GPTZFSBoot/RAIDZ2">excellent tutorial</a> to start, but decided to make a few modifications:</p>
<ul>
<li>I wanted to put the root filesystem some place other than the root of the pool.  Since my large media collection is going to be stored on the same pool, I wanted the ability to selectively snapshot the boot filesystem, and possibly revert it, without affecting the media partition.  So, I put the root filesystem on on a sub filesystem of the pool.</li>
<li>The trend in disk storage is looking like it will go to 4K sector sizes in the future.  ZFS cannot migrate a pool from 512 byte sector sizes to 4K sector sizes without a reformat/restore.  I wanted a 4K sector size pool from the start.</li>
<li>I wanted to use ZFS swap instead of swap partitions.</li>
<li>I was going to spent several iterations getting things right and didn&#8217;t want to type on that blasted 12 year old keyboard the same commands over and over.</li>
</ul>
<p>So, I accomplished this whole task through a series of scripts, that I would modify.  If the script did something wrong, I&#8217;d destroy the pool and start over.  The end result is a simple setup that I decided to share with the world:</p>
<ol>
<li>Download and burn/image one of the FreeBSD <a href="http://www.freebsd.org/where.html">iso images or USB images</a>.  I used 8.2, the most recent at the time of this writing, and did the USB image since I had flash drives to spare but no DVD ROM drives.</li>
<li>Boot the machine and enter the recovery mode (Fixit).</li>
<li>Start the networking:<br />
<code>mkdir /var/db<br />
dhclient em0<br />
ln -s /dist/usr/bin /usr/bin<br />
</code></li>
<li>Transfer over the script directory:<br />
<code>scp -r username@10.0.0.10:Desktop/FreeBSD/\* .</code><br />
In this case, 10.0.0.10 is my laptop with sshd running.</li>
<li>Start sshd: <code>./FreeBSDSSHSetup.sh</code></li>
<li>ssh into the machine from my laptop and execute: <code>./FreeBSDInstall.sh</code></li>
<li>Reboot the server and enjoy.</li>
</ol>
<p>The <a href="http://www.cod3r.com/FreeBSDRaidSetup.zip">FreeBSD directory is available</a> for those who would like to copy my efforts, though they will likely need some modification to suit your needs.  The <em>gptzfsboot</em>, <em>pmbr</em>, and <em>zfsloader</em> files came from <a href="http://people.freebsd.org/~pjd/zfsboot/">this site</a> which are modified versions that work with 4K drives.  The versions available in 8.2 do not work with 4K sector sizes, but future versions will.  My install script
<ul>
<li>Partitions ad8, 10, 12, 14, 16, 18 to contain the boot loader and zpool information (6 SATA drives),</li>
<li>Loads kernel modules and sets up a gnop drive with 4K sectors,</li>
<li>Creates a raidz2 pool using the gnop drive as one of the drives forcing 4K sectors, exports the pool,</li>
<li>Destroys the gnop drive, re-import the pool, which had been forced to 4K sectors,</li>
<li>Sets up root filesystem on zroot/root (zroot is the root of the pool, root is the root filesystem, as discussed above), and</li>
<li>Performs a standard zroot install, except no swap partition.</li>
</ul>
<p>I actually added the swap later, which is simply:<br />
<code>zfs create -V 2G zroot/swap<br />
zfs set org.freebsd:swap=on zroot/swap<br />
zfs set checksum=off zroot/swap<br />
</code></p>
<p>And that&#8217;s it.  I have my 8TB raid running, with 2 drive redundancy, booting off the raid.  Setting up AFP and the like requires more tinkering than with FreeNAS, but the instructions are easy to find and would be redundant to list here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2011/10/freebsd-with-zfs-root/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What Objective-C can learn from Java, Part 4 (Namespace)</title>
		<link>http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/</link>
		<comments>http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 21:18:40 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=464</guid>
		<description><![CDATA[This is the last is a series of blog posts I’m writing on things that Objective-C can learn from Java. The other parts can be found here: Part 1 (Generics) Part 2 (Abstract Classes) Part 3 (Single Source File) Part 4 (Namespace) Part 5 (Exceptions) For one who has programmed in other object oriented languages, [...]]]></description>
			<content:encoded><![CDATA[<p>This is the last is a series of blog posts I’m writing on things that Objective-C can learn from Java.  The other parts can be found here:<br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-1-generics/">Part 1 (Generics)</a><br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-2-abstract-classes/">Part 2 (Abstract Classes)</a><br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-3-single-source-file/">Part 3 (Single Source File)</a><br />
Part 4 (Namespace)<br />
<a href="http://www.cod3r.com/2012/04/what-objective-c-can-learn-from-java-part-5-exceptions/">Part 5 (Exceptions)</a></p>
<p>For one who has programmed in other object oriented languages, Objective-C stands out with its complete lack of namespace.  As a result, classes have a prefix, such as Apple&#8217;s common <em>NS</em> and <em>UI</em> prefixes.  On the mac side of things, every class under the sun seemed to start with <em>NS</em>, such as <code>NSString</code>, and confusion is added when on the iOS side, several classes start with <em>UI</em>, such as <code>UIView</code>.  This is due to the fact that without a concept of namespace, Objective-C cannot have two classes with the same name, regardless of whether the classes are public or not.</p>
<p>If I were designing an application which communicated on a network as well as talked to a database, I would split the two pieces into separate segments, or in Java, packages.  Inside each package, I would likely have a <code>Connection</code> class, which has completely different meanings within the network and database packages.  Inside those packages, especially if the <code>Connection</code> class was internal to the package only, I could name both classes <code>Connection</code> without any concern and the code inside the package would immediately understand what <code>Connection</code> actually meant.  This is possible in Java because the actual class names are <code>com.cod3r.app.network.Connection</code> and <code>com.cod3r.app.database.Connection</code>.  Since Objective-C does not have namespaces, I would have to name these <code>NetworkConnection</code> and <code>DatabaseConnection</code>.</p>
<p>Now, take the above scenario, and add another type of network connection.  Then take that new network connection and add new specific case to it, making a new class.  In Java, the package name gets longer where as in Objective-C the class name gets longer.  I have run into cases where this borders on ridiculous if one wants the class name to define what it actually does without ambiguity.  The class is within the <a href="http://appletv.nanopi.net">Sapphire</a> plugin.  In the project, all classes had the prefix <code>Sapphire</code> since it was a bundle included in another application and had to make sure there was never a class conflict.  The project has the concept of a <code>Directory</code> and a <code>VirtualDirectory</code> was a directory which wasn&#8217;t associated with a directory in the file system.  There is a type of <code>VirtualDirectory</code> that was <code>Custom</code> meaning it was defined by the user instead of already in the code.  Finally, this particular class is responsible for importing these <code>CustomVirtualDirectory</code> objects, making the final class titled <code>SapphireCustomVirtualDirectoryImporter</code>.  In Java, this class would have been <code>Importer</code> within the <code>net.nanopi.sapphire.directory.virtual.custom</code> package.  The difference is the fully qualified classname would only be used in the import statement, and the short class name would be used in the code, instead of the really long classname used in every location as seen in Objective-C.  This becomes particularly relevant when it comes to code completion that produces a terribly long list until nearly the entire class name is typed.</p>
<p>The lack of namespace becomes problematic when one uses third party libraries.  Take the above Sapphire example and another plugin developer finds a completely unrelated library titled Sapphire.  If that library happened to have a directory titled <code>SapphireDirectory</code>, then both plugins cannot be loaded at the same time.  Java goes even further with a two-level namespace such that two jars (bundles) with the same fully-qualified classname still don&#8217;t interfere since they are in separate jars.</p>
<p>Adding namespace is necessary for adding inner-classes, which Objective-C outright doesn&#8217;t use, but could in proper circumstances.  Inner classes are useful for implementing delegate methods.  When setting a delegate, one typically passed in the instance of an inner class rather than the current instance.  Not adopting this model has the issue when a single class is set to be the delegate to multiple objects, such as being the delegate to two table views.  Apple works around this design by making each delegate method have the first parameter be that of the object calling it&#8217;s delegate, such as the table view.  This means if the code is different between the two, every single delegate method needs have an if statement to determine which table view is being processed, and eliminates the ability of one to skip implementing an optional method for one table but not the other.  Both of these problems are eliminated with inner-classes.  Finally, the lack of inner-classes severely cripples the ability of a super-class to use the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/Concepts/KVOBasics.html">Key Value Observing</a> within Objective-C since the delegate and unregister methods were written in a way that really require an inner-class to work properly (I can see how to easily break some code in a sub-class or super-class since this was designed so badly).</p>
<p>Impact on Runtime:<br />
Small.  I don&#8217;t know the specifics of the runtime, so I can&#8217;t judge the exact impact, but this will result in longer effective class names, which may increase lookup times.  Inner-classes would need an instance variable for their outer-class to access it&#8217;s instance variables, resulting in additional pointer deference for accessing outer-class variables.</p>
<p>Impact on Code:<br />
No longer need to create necessarily long class names; programmer can use short class name without concern.  Frameworks need not have a class prefix.  More flexibility in object design.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>What Objective-C can learn from Java, Part 3 (Single Source File)</title>
		<link>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-3-single-source-file/</link>
		<comments>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-3-single-source-file/#comments</comments>
		<pubDate>Thu, 30 Dec 2010 16:16:28 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=422</guid>
		<description><![CDATA[This is the third is a series of blog posts I’m writing on things that Objective-C can learn from Java. The other parts can be found here: Part 1 (Generics) Part 2 (Abstract Classes) Part 3 (Single Source File) Part 4 (Namespace) Part 5 (Exceptions) Objective-C still retains a lot of its heritage from it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>This is the third is a series of blog posts I’m writing on things that Objective-C can learn from Java.  The other parts can be found here:<br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-1-generics/">Part 1 (Generics)</a><br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-2-abstract-classes/">Part 2 (Abstract Classes)</a><br />
Part 3 (Single Source File)<br />
<a href="http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/">Part 4 (Namespace)</a><br />
<a href="http://www.cod3r.com/2012/04/what-objective-c-can-learn-from-java-part-5-exceptions/">Part 5 (Exceptions)</a></p>
<p>Objective-C still retains a lot of its heritage from it&#8217;s C beginnings.  This includes using two files, a header and a source file, for each class.  In a strictly object oriented environment, the header file contains the class definition (super-class and instance variables), public property definitions, and any public function declarations.  The source file contains all of the function implementations, including synthesize statements.  In contrast, Java contains all the functions of both files in a single file.  To one who knows better, as in one who has used the single file environment, the two files for each class becomes a pain.</p>
<p>As to why this is a pain, one needs only to visit the following scenario:  Add a property called <code>name</code> to the <code>Person</code> object.  In Objective-C, one needs to add the instance variable to the class definition and the property declaration to the header file.  Then, add a <code>@synthesize</code> statement to the implementation and add <code>[name release];</code> in the dealloc (I&#8217;m neglecting Objective-C&#8217;s ability to create the instance variable in modern runtimes since it denies direct access to it in the code).  In contrast, Java needs the instance variable added to the class, and in the same file add the setters and getters (which if using Eclipse, can be auto-generated).  Java is able to accomplish this because it uses a two-pass compiler.  One pass parses the class definition and function declarations, and the second generates the actual code.  Any <code>import</code> statements only need the first pass of each file.</p>
<p>In Objective-C, some of this pain can be eliminated using my fork of <a href="https://bitbucket.org/gbooker/objectivecannotate/">ObjectiveCAnnotate</a>, but this is only part of the way to what should be done.  What Objective-C really needs is to use a single source file, and auto-generate the equivalent header file when the source file is saved (and save it only if it is different to reduce unnecessary re-compiles).  This serves as the equivalent of Java&#8217;s first complier pass.  Then, the actually compile step executes the second pass, using the generated header and the code within the source file.  Using the paradigm, several changes should be made to the source file.  The obvious is adding a public (or maybe @public) to functions that should be included in the header file.  Additionally, the property syntax can be combined with the instance variable declaration and possibly with synthesize to create something like <code>@property (nonatomic, retain, synthesize) NSString *name</code> to take the place of the instance variable declaration, the property declaration, and the synthesize statement.  Since this is by far the most common use case, why not simplify it to make things easier for the developer?  The instance variable still needs to be in dealloc, but now changes in instance variables has been reduced to two places.</p>
<p>This change doesn&#8217;t completely eliminate the need for header files.  The old C-style declarations, such as C-functions, structs, enums, externs, typedefs, and defines, would still need to be in a header file on their own.  Since most classes do not make these declarations, most classes wouldn&#8217;t need a distinct header file.  In the cases where such a definition is made, it is often better style to include all of the definitions in a single <em>types</em> header file for the framework/project.</p>
<p>This does necessitate a change to the import statements for a class.  In the two file environment, one can separate the import statements between the header and source files, but in a single file, this separation no longer exists.  However, the compiler could be made smart enough to track the locations of types it inserts in the generated header file, and include those location in the header file&#8217;s import statements.  This would mean the header file would contain the import statements for the super-class, and any C-style declarations only.  There is no need at all to include the import statements for other classes, as the existing <code>@class</code> declaration tells the compiler all it needs to know at this stage.  This would also eliminate the bad coding practice of including unnecessary import statements in the header file, a practice which I&#8217;ve seen too often by new programmers who were never taught of its dangers.</p>
<p>Impact on Runtime:<br />
None, this is pre-processor only</p>
<p>Impact on Code:<br />
Reduction in code complexity, ease in modification.  Reduction in need to reference two files to understand a single class.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-3-single-source-file/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>What Objective-C can learn from Java, Part 2 (Abstract Classes)</title>
		<link>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-2-abstract-classes/</link>
		<comments>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-2-abstract-classes/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 21:54:20 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=412</guid>
		<description><![CDATA[This is the second is a series of blog posts I’m writing on things that Objective-C can learn from Java. The other parts can be found here: Part 1 (Generics) Part 2 (Abstract Classes) Part 3 (Single Source File) Part 4 (Namespace) Part 5 (Exceptions) When one is using object oriented design, a common practice [...]]]></description>
			<content:encoded><![CDATA[<p>This is the second is a series of blog posts I’m writing on things that Objective-C can learn from Java.  The other parts can be found here:<br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-1-generics/">Part 1 (Generics)</a><br />
Part 2 (Abstract Classes)<br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-3-single-source-file/">Part 3 (Single Source File)</a><br />
<a href="http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/">Part 4 (Namespace)</a><br />
<a href="http://www.cod3r.com/2012/04/what-objective-c-can-learn-from-java-part-5-exceptions/">Part 5 (Exceptions)</a></p>
<p>When one is using object oriented design, a common practice is to lump similar classes together with a common super-class and include the common functionality in that super-class.  In doing such design, a common problem is for the super-class to require some information that can only be computed by the sub-class.  The solution is for the super-class to make a function call on itself which the sub-class implements.  For example, I recently designed a class which simplifies storage of an object in a SQL row, but it knows nothing about the actual field names or values stored in the database.  In this case, I made a function, which subclasses implement, to retrieve this data.  In Java, this is simply done through an abstract method in an abstract class.</p>
<p>Objective-C has no concept of an abstract method or class.  Instead, the closest one can get is to provide an empty implementation for a function and then override that implementation in the sub-classes.  Unlike Java, there is no error, or even a warning, if the programmer of the subclass forgets to implement the function that must be overridden.  The landscape becomes more confusing when one considers properties.  Since Objective-C&#8217;s gives errors when an implementation doesn&#8217;t provide the property accessor methods, it provides a annotation <code>@dynamic</code> which silences the error.  Apple mentions this can be used when an implementation is dynamically provided at runtime, but considering the complexity of this technique, it&#8217;s more common use is to silence the error in the case where a subclass implements the accessor methods.  However, in the inconsistency with which Apple has treated properties, there is no error or warning, or any way to make the compiler throw one, if the sub-class programmer forgets the implementation.  This makes <code>@dynamic</code> really dangerous (just as ignoring warnings can be dangerous).</p>
<p>So, what is really required to make abstract classes work in Objective-C?  Again, all of the work is in the compiler and doesn&#8217;t affect runtime.  First, one needs to be able to define a class as abstract, which tells the complier that allocation of that class, such as <code>[AbstractClass alloc]</code>, should throw an error.  Second, properties and methods need to be able to be defined as abstract.  This will silence any errors and warnings about missing implementation in the abstract class and throw the errors and warnings about missing implementation in a non-abstract sub-class.  A few changes to the complier, and a programmer can do more advanced designs and avoid simple common mistakes at compile time rather than runtime.</p>
<p>Impact on Runtime:<br />
None, abstract classes and methods are syntax sugar only.</p>
<p>Impact on Code:<br />
Allows more advanced design, and sub-classes become less prone to error.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-2-abstract-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What Objective-C can learn from Java, Part 1 (Generics)</title>
		<link>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-1-generics/</link>
		<comments>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-1-generics/#comments</comments>
		<pubDate>Sat, 04 Dec 2010 22:38:29 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=396</guid>
		<description><![CDATA[This is the first is a series of blog posts I&#8217;m going to write over the next several days on things that Objective-C can learn from Java. I&#8217;ve been programming in Java since 1997, and in Objective-C since 2001. The two languages have a lot of similarities, but there are a few design principles in [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first is a series of blog posts I&#8217;m going to write over the next several days on things that Objective-C can learn from Java.  I&#8217;ve been programming in Java since 1997, and in Objective-C since 2001.  The two languages have a lot of similarities, but there are a few design principles in which Java excels and Objective-C is left behind.  This is understandable considering that Objective-C is older than Java, and Java borrowed heavily from Objective-C when it was designed.  In this series I&#8217;m only going to discuss changes to the language; these items will have very little, if any, impact on the runtime.  For the purposes of this discussion, I&#8217;m going to use Java&#8217;s terminology since it is more familiar with the programming public.  This means I&#8217;ll talk about functions instead of selectors, and interfaces instead of protocols.</p>
<p>The other parts can be found here:<br />
Part 1 (Generics)<br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-2-abstract-classes/">Part 2 (Abstract Classes)</a><br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-3-single-source-file/">Part 3 (Single Source File)</a><br />
<a href="http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/">Part 4 (Namespace)</a><br />
<a href="http://www.cod3r.com/2012/04/what-objective-c-can-learn-from-java-part-5-exceptions/">Part 5 (Exceptions)</a></p>
<p>The first item which Objective-C can learn from Java is Generics.  Objective-C is a weakly typed language, too weak for my tastes, whereas Java is strongly typed.  There are distinct advantages to a strongly typed language, but I&#8217;m not going to get into that here.  This means that Objective-C&#8217;s can make a function call on an object without knowing its type where as Java must have the object typed to an interface or class which defines that function.  This requires typecasting in Java before making function calls, where as Objective-C does not.  In some cases this throws a warning in Objective-C, and in some cases does not.  Missing warnings can lead to programming mistakes, and programmer ignored warnings leads to bad style.  In either case, typecasting will change the mistakes to warnings, and the warnings which are not mistakes to no warnings.</p>
<p>Java had the issue in requiring typecasting to make function calls.  This lead to numerous typecasts in code, which added to clutter.  Java&#8217;s solution to much of this clutter came through the use of generics.  One of the largest sets of typecasts resulting in fetches from a collection.  For example, if one had a list which contains objects of class <code>Person</code>, then it would be convenient if the complier just remembered that for you.  This was done by simply declaring the list as <code>List&lt;Person&gt;</code>.  Then, when fetching objects from the List, no typecast is necessary since the compiler already knows that all objects in that list are a <code>Person</code> in the first place.  I should add, for the C++ programmers out there, this is <strong>not a template</strong>.  Templates define a whole new set of code for that type, ballooning the object binary, where as generics can be thought of as automatic typecasting.</p>
<p>I have found many arguments that state Objective-C doesn&#8217;t need generics because it is a weakly typed language (just Google <em>Objective-C generics</em> to see them).  These arguments tend to forget one major piece of the language.  Consider the following code:</p>
<p><code><br />
@interface Person : NSObject {<br />
&nbsp; &nbsp; NSString &nbsp; *name;<br />
&nbsp; &nbsp; NSArray &nbsp; &nbsp;*siblings;<br />
&nbsp; &nbsp; Person &nbsp; &nbsp; *father;<br />
&nbsp; &nbsp; Person &nbsp; &nbsp; *mother;<br />
&nbsp; &nbsp; NSArray &nbsp; &nbsp;*children;<br />
}</p>
<p>@property (nonatomic, retain) NSString *name;<br />
@property (nonatomic, retain) NSArray *siblings;<br />
@property (nonatomic, retain) Person *mother;<br />
@property (nonatomic, retain) Person *father;<br />
@property (nonatomic, retain) NSArray *siblings;</p>
<p>@end<br />
</code></p>
<p>In this example, I&#8217;ve defined an Objective-C class called <code>Person</code> with a name, an array of siblings, a father, mother, and an array of children.  Now, say I wanted to get the first-born child&#8217;s name.  I could do this with <code>[children objectAtIndex:0].name</code>.  Except, this produces an error because <code>[children objectAtIndex:0]</code> returns an <code>id</code>, not a <code>Person *</code>, and properties, unlike functions, are strongly typed in Objective-C.  So, the recourse is to either use a temporary variable of type <code>Person *</code>, or to typecast on the same line like: <code>((Person *)[children objectAtIndex:0]).name</code>.  If Objective-C had generics, this would eliminate any need for the typecast or temporary variable since the compiler would already know the type of the object returned by the array.</p>
<p>This is a simple example of where generics become useful in the language, but there are far more.  I have actually found Objective-C&#8217;s lack of generics limiting my ability to design class hierarchies, and requiring a large amount of unnecessary typecasts or in some cases, additional function calls, which produces slower code.</p>
<p>Should Objective-C adopt all of Java&#8217;s generics?  I would contend the answer is no.  Java&#8217;s generics can get very convoluted very quickly, and the biggest source of the mess is in defining a generic function call.  While they add convenience, generics in function calls becomes very messy.  However, generics on a class level (and used in it&#8217;s functions) add so much benefit and cleaner code design that Objective-C is really suffering without them.  Additionally, Java produces warnings if a class containing generics does not have it&#8217;s generic type defined.  For example, <code>List children</code> will produce a warning because I didn&#8217;t define the type of object contained within list.  In these cases, since Objective-C is so weakly typed, it&#8217;d be most appropriate if its generics just defaulted to the base class allowed in the generic, which in the case of NSArray would be <code>id</code>.</p>
<p>Impact on Runtime:<br />
None, generics are <em>syntax sugar</em> only.</p>
<p>Impact on Code:<br />
Generics added where needed, changing the tracking of object type to the compiler instead of the programmer.  Cleaner code, and less prone to error.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-1-generics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trac.fcgi Memory Usage</title>
		<link>http://www.cod3r.com/2010/10/trac-fcgi-memory-usage/</link>
		<comments>http://www.cod3r.com/2010/10/trac-fcgi-memory-usage/#comments</comments>
		<pubDate>Sat, 16 Oct 2010 18:06:28 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Servers]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=388</guid>
		<description><![CDATA[I&#8217;ve been slowly transitioning to using nginx as the web front-end in an effort to reduce Apache&#8217;s memory usage. In keeping with this task, I&#8217;m moving more and more off of Apache. One piece I recently moved was trac, transitioning to using it directly by nginx by running it in fast-cgi mode where as previously [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been slowly transitioning to using nginx as the web front-end in an effort to reduce Apache&#8217;s memory usage.  In keeping with this task, I&#8217;m moving more and more off of Apache.  One piece I recently moved was trac, transitioning to using it directly by nginx by running it in fast-cgi mode where as previously it was running as cgi though Apache.  </p>
<p>While fast-cgi is faster, it has inherent issues, such as any memory leak can result in ever growing memory usage, which is exactly why Apache has a setting for each child to serve a limited number of requests before exiting.  Trac.fcgi has no such directive, and has the equivalent of a large memory leak, a non-expiring cache.  While it&#8217;s not as bad as a memory leak, which will indefinitely grow instead of reaching a limit, if the cache size is larger than the available memory for trac to use, it&#8217;s just as serious.  The only solution, without fixing trac&#8217;s caching mechanisms, is to restart trac periodically, but during the time trac is restarting, all requests are lost, causing bad gateway errors to the user.  Additionally, the restart needs to be done manually.  Clearly not an ideal solution.</p>
<p>The ideal solution would be for the trac process to be periodically restarted, but all requests be successfully completed.  This is what Apache accomplishes with its children, but trac has no such mechanism or even the support for one.  So, I had to build it in myself.</p>
<p><strong>My Solution:</strong><br />
First piece is to create a parent process, which holds the fcgi socket, and restarts a child trac process when it dies.  This ensures that all waiting requests will be served by either the old or new process.  Such a parent process absolutely must have no memory leaks, and so I created one that has only 1 explicit allocation, and it is executed only once.</p>
<p>The second piece, and one that&#8217;s considerably harder, is to make the trac process exit gracefully when it&#8217;s memory usage gets too big.  The first step was to create a subclass of WSGIServer and override its _mainloopPeriodic to run a periodic check.  In this check, I do a memory usage check, and if it&#8217;s over 90MB, set itself to exit.  The problem is there&#8217;s no easy way to figure out the memory usage on linux.  There is a function, getrusage, which is supposed to give resource usage information, such as memory, but linux gives all zeros (unlike a proper kernel).  The only way to get this is to read the information out of /proc, and parse that data.  Since this becomes a more expensive operation, I only conduct the test every 100 times.<br />
After doing this, I was still getting periodic bad gateway errors.  It turns out that trac spawns a thread to process the request, and that request hadn&#8217;t completed when the process exited, dropping the connection and causing the error.  In examining the documentation, Python is supposed to wait for the thread to complete before exit.  Since it wasn&#8217;t, I put in a mechanism to see if any threads are running before exit.  Here lies a big problem with Python.  I found out that the thread, while created, hasn&#8217;t actually started.  Since it hasn&#8217;t started, it isn&#8217;t running, which is why Python exited.  Furthermore, Python&#8217;s threading is so brain-dead, there seems to be no way at all to differentiate between a thread which hasn&#8217;t started and one that is exited but not freed.  This means there is no reliable way to detect if all threads have exited.  So instead, in order to work around Python, I created a thread-safe counter to count the number of threads.  I increment it when the thread is created (not started), and decrement it when the thread completes.  I then only allow the main thread to exit when this counter reaches zero (since the main thread does the allocations, this never lets the process die without starting all threads).  Given this glaringly bad threading model, I put in another protection mechanism so that the main thread will exit after 30 seconds even if the count isn&#8217;t zero, just in case.</p>
<p>With the above two pieces, trac&#8217;s memory usage is limited, and no connections are dropped, in the time between one process deciding to go down and when it actually does, nothing is processing requests.  So, the last piece is to make trac signal to the parent process that it has decided to exit, and then have the parent process launch a new trac to take over while the previous is exiting.  I did this with USR1 signal, where the parent process sends a HUP to the child (in case someone else sent it the USR1 signal), and start a new child.  With these modifications in place, trac has been humming along for nearly a month, being restarted about 2-3 times a day with no issues.</p>
<p>Files:<br />
<a href='http://www.cod3r.com/images/2010/10/launcher.c'>launcher.c</a> &#8211; Requires the environment variable WORKER_PATH to be set to know what process to launch.  Best run with something like spawn-fcgi<br />
<a href='http://www.cod3r.com/images/2010/10/trac.fcgi_.txt'>trac.fcgi</a> &#8211; Modified trac.fcgi to incorporate the above mentioned changes, complete with commented code for testing/experimentation.<br />
Enjoy</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2010/10/trac-fcgi-memory-usage/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

