Mission-Style Bookshelf

February 12th, 2011

Filed under: Life and Everything Else

Tags: ,

My current woodworking project is a Mission-style bookshelf that I designed to match the sofa table that I built last year. The bookshelf will sit below a window to the kitchen, so it is low and extra wide to fit that space. To support the weight of the books without sagging, sets of stiles transfers weight from the middle shelf to the frame above and below.

I am building the bookshelf out of cherry. Like the sofa table, all joinery is mortise and tenon. This time I am squaring out the mortises with a new set of mortising chisels rather than rounding off the tenons with a knife as I did on the sofa table — which is making the process go much faster.

If you like the design and wish to build one for yourself, you can download my SketchUp model as a starting point.

Git Tip: Grouping feature-branch commits when merging.

December 12th, 2010

Filed under: Computers and Technology , Work/Professional

Tags: , ,

Let’s say you are working on a large feature or update that requires a bunch of commits to complete. You finish up with your work and are then ready to merge it onto your master branch.

For example, here is the history of my drupal repository after some work updating the cas module to the latest version (and to support the new version of phpCAS):

As you can see, I have a number of commits, followed by a merge in with the new module code, followed by some more commits.

Now, if I merge my feature branch (master-cas3-simple) into the master via

git merge  master-cas3-simple

then the history will look like this:

While the history is all there, it isn’t obvious that all of the commits beyond “Convert MS Word quote…” are a single unit of work. They all kind of blend together because git performed a “fast-forward” commit. Usually fast-forward commits are helpful since they keep the history from being cluttered with hundreds of unnecessary merge commits, but in this case we are loosing the context of these commits being a unit of work.

To preserve the grouping of these commits together I can instead force the merge operation to create a merge commit (and even append a message) by using the --no-ff option to git merge:

git merge --no-ff -m "Upgraded CAS support to to cas-6.x-3.x-dev and phpCAS 1.2.0 RC2.5" master-cas3-simple

This results in the history below:

As you can see, merging with the --no-ff option creates a merge commit which very obviously delineates work on this feature. If we decided that we wanted to roll back this feature it would be much easier to sort out where the starting point before the feature was.

Thanks to Vincent Driessen for turning me onto the utility of the the --no-ff merge option via his post “A successful Git branching model“.

Mirroring a Subversion repository on Github

December 5th, 2010

Filed under: Computers and Technology , Work/Professional

Tags: , , , ,

For the past few months I have been doing a lot of work on the phpCAS library, mostly to improve the community trunk of phpCAS so that I wouldn’t have to maintain our own custom fork with support for the CAS attribute format we use at Middlebury College. The phpCAS project lead, Joachim Fritschi, has been great to work with and I’ve had a blast helping out with the project.

The tooling has involved a few challenges however, since Jasig (the organization that hosts the CAS and phpCAS projects) uses Subversion for its source-code repositories and we use Git for all of our projects. Now, I could just suck it up and use Subversion when doing phpCAS development, but there are a few reasons I don’t:

  1. We make use of Git submodules to include phpCAS along with the source-code of our applications, necessitating the use of a public Git repository that includes phpCAS.
  2. The git-svn tools allow me to use git on my end to work with a Subversion repository, which is great because…
  3. I find that Git’s fast history browsing and searching make troubleshooting and bug fixing much easier than any other tools I’ve used.

For the past two years I have been using git-svn to work with the phpCAS repository and every so often pushing changes up to a public Git repository on GitHub. Our applications reference this repository as a submodule when they need to make use of phpCAS. Now that I’ve been doing more work on phpCAS (and am more interested in keeping our applications using up-to-date versions), I’ve decided to automate the process of mirroring the Subversion repository on GitHub. Read on for details of how I’ve set this up and the scripts for keeping the mirror in sync.

Continue Reading »

Bittersweet Falls

November 7th, 2010

Filed under: Life and Everything Else

Tags: , , , ,

A hundred yards from the aptly-named Bittersweet Falls Road, the Beaver Brook cascades over a formation of marble and dolomite to create a beautiful 18 foot cascade.

Bittersweet Falls

Above Bittersweet Falls, the Beaver Brook cuts a deep ravine through layers of black slate. The gorge can be difficult to traverse without getting one’s feet wet, but is filled with cascades and mossy bottoms ringed by ferns and overshadowed by hemlocks.

In the glen

I headed out the door today planing to swing by Bittersweet Falls for a few quick shots before driving out to the Dead Creek Wildlife Management Area where stargazer05756 has been following the migration of snow geese. I never made it to Dead Creek. After taking a few shots below the falls I climbed up above and noticed an impressive gorge winding upstream. Ever since I was a child I have always loved exploring up cascading streams. There is just something magical above clambering around a rock to find another waterfall or quiet pool surrounded by moss, ferns, hemlocks — and in the south, rhododendrons.

311/365: In the glen

The Beaver Brook didn’t disappoint and while its steep slate side posed a challenge, I hiked about a third of a mile upstream along the stream bed before scaling the hillside and quickly walking back to the car from above.


View Larger Map

The Northeast Waterfalls site has directions and more info.

BASH tip: Top web pages

October 14th, 2010

Filed under: Computers and Technology , Work/Professional

Tags: , , ,

Here is a quick command to generate a list of the top pages in the Apache web-server’s access log:

gawk '{ print $7}' /var/log/httpd/access_log | sort | uniq -c | sort -nr | head -n 20

Parts of the command explained:

  1. gawk '{ print $7}' — return only the 7th [white-space delimited] column of text from the access log, which happens to be the path requested.
  2. sort — sort the lines of the output.
  3. uniq -c — condense the output to unique lines, prepending each line with the number of times that line occurs.
  4. sort -nr — sort the resulting lines numerically in reverse order.
  5. head -n 20 — chop off all but the first 20 lines.

The result should look something like this:

  83361 /
  49582 /feed
  39616 /robots.txt
  36265 /favicon.ico
  17048 /?feed=rss2
  10798 /archives/3
  10036 /wp-content/uploads/2007/05/img_7870_header.jpg
   9913 /wp-includes/images/smilies/icon_smile.gif
   9425 /wp-comments-post.php
   8274 /feed/
   7508 /archives/category/work/feed
   7367 /archives/88
   7312 /photos/10_small/IMG_3023.JPG.jpg
   7175 /photos/10_small/IMG_3028.JPG.jpg
   7151 /photos/10_small/IMG_3024.JPG.jpg
   7096 /photos/10_small/IMG_3026.JPG.jpg
   6381 /photosetToKML.php?set=72157594417350372&size=small
   6253 /qtvr/2007-04-05_back_deck_snow%20-%2010000x5000%20-%20SLIN%20-%20Blended%20Layer0002.jpg
   5798 /photosetToKML.php
   4344 /archives/category/photography

Adding reverse-proxy caching to PHP applications

June 14th, 2010

Filed under: Computers and Technology , Work/Professional

Tags: , , , ,

Note: This is a cross-post of documentation I am writing about Lazy Sessions.

Why use reverse-proxy caching?

For most public-facing web applications, the significant majority of their traffic is anonymous, non-authenticated users. Even with a variety of internal data-cache mechanisms and other good optimizations, a large amount of code execution goes into executing a PHP application to generate a page even if the content of this page will be the same for many users. Code and query optimization are very important to improving the experience for all users of a web application, but even the most basic “Hello World” script will top out at about 3k requests/second due to the overhead of Apache and PHP — many real applications top out at less than 200 requests/second. Varnish, a light-weight proxy-server that can run on the same host as the webserver, can cache pages in memory and can serve them at rates of more than 10k requests/second with thousands of concurrent connections.

While the point of web-applications is to have content be dynamic and easily changeable, for most applications and most of the anonymous users, receiving content that is slightly stale (cached for 5 minutes or something similar) isn’t a big deal. Sure, visitors to your blog might not see the latest post for a few minutes, but they will get their response in 4 milliseconds rather than 2 seconds.

Should your site get posted on Slashdot, a caching reverse-proxy server will give anonymous visitor #2 and up the same page from cache (until expiration), while authenticated users continue to have their requests passed through to the Apache/PHP back-end. Everyone wins.

Continue Reading »

Sofa Table Complete

April 11th, 2010

Filed under: Life and Everything Else

Tags: , ,

Over the course of the past year I built this cherry sofa table based on a design by Scott Gibson in Fine Woodworking’s "Furniture" book.

All frame joinery is mortise and tenon, while the drawers use doweled rabbit joints. The finish is boiled linseed oil topped with 3 coats of Minwax wiping varnish.

Building this table was quite a learning experience as just about every part required techniques that I hadn’t used before. Mortise and tenon joinery, biscuits to align the table top during glue-up, doweled joints fort the drawers, quartersawn veneers for the legs, breadboard-ends, and varnish; all of these were new to me and required a bit of trial and error to get right.

This project certainly had its share of "oops" moments, but nothing that couldn’t be repaired or worked-around. I cut the bottom shelf stretcher one inch too short, but was able to cut it in half and splice in a section with a small mortise and tenon in the middle. Later, I made the hipped-tenons on which the breadboard-ends of the top sit too thin. This was repaired with the addition of some 5-minute epoxy to thicken the tenon.

All that remains now is to choose and install drawer-pull hardware.

Importing users into Bugzilla

March 8th, 2010

Filed under: Computers and Technology , Software , Work/Professional

Tags: , , ,

For the past 6 months our Web Application Development work-group has been Bugzilla as our issue tracker with quite a bit of success. While it has its warts, Bugzilla seems like a pretty decent issue-tracking system and is flexible enough to fit into a variety of different work-flows. One very important feature of Bugzilla is support for LDAP authentication. This enables any Middlebury College user to log in and report a bug using their standard campus credentials.

While LDAP authentication works great, there is one problem: If a person has never logged into our Bugzilla, we can’t add them to the CC list of an issue. This is important for us because issues usually don’t get submitted directly to the bug tracker, but rather come in via calls, emails, tweets, and face-to-face meetings. We are then left to submit issues to Bugzilla ourselves to keep track of our to-do items. Ideally we’d add the original reporter to the bug’s CC list so that they will automatically be notified as we make progress on the issue, but their Bugzilla account must exist before we can add them to the bug.

Searching about the internet I wasn’t able to find anything about how to import LDAP users (or any kind of users) into Bugzilla, though I was able to find some basic instructions on how to create a single user via Bugzilla’s Perl API. To improve on the lack of user-import support I’ve created an Perl script that creates users from lines in a tab-delimited text file (create_users.pl) as well as a companion PHP script that will export an appropriately-formatted list of users from an Active Directory (LDAP) server (export_users.php).

Continue Reading »

Project 365

January 1st, 2010

Filed under: Life and Everything Else

Tags: ,

Sarah announced today that she was going to do a “365 project” this year: taking a photo every day of the year, both as a journal and to force one’s self to get out and take some pictures. This sounded like a fun idea and one that would be easier to stick to if we were both doing it, so I’m going to give it a whirl as well. You can follow along with this feed or check the photo-set for updates.

Subscribe to a feed of 365 - 2010 Feed – Subscribe to the set “Project 365 – 2010”

See Sarah’s “Project 365” on Flickr.

Slow Cooking

January 1st, 2010

Filed under: Life and Everything Else

Tags: ,

Sarah’s big Christmas present this year was a Cuisinart slow-cooker. We tried it out a few days ago to make “Curried Cream of Chicken Soup” from a recipe in The Silver Palate Cookbook

The cooker worked great and the chicken melted off of the bone.

« Prev - Next »