in

 

Sean Chambers

I am a Lead Developer from Palm Coast Florida. If I could describe my skillset I would include TDD, DDD, Alt.net, NHibernate, Castle Project and so on

December 2007 - Posts

  • Dealing with RSI properly

    Over the last two weeks I have been having bad symptoms of RSI and Carpal Tunnel Syndrome. Specifically in the right hand more so than the left. This is almost surely from the mouse.

    I am going to share what I have found out after doing some research on the topics as all programmers should treat the symptoms of RSI as serious. This is probably the one thing that could end your career as a programmer and the symptoms should not be ignored for any reason. I have an appointment next week to visit my doctor and start physical therapy.

    Over the last year or so I have noticed waking up at night with numbness in my right hand and figured I was just sleeping on it wrong. This was the only warning sign I had up until two weeks ago. One night two weeks ago I awoke from an amazing amount of pain in my right hand. I ran some cold water over it for a couple of minutes to get it to stop hurting so much and went back to sleep. The next day I noticed that my index, thumb and middle finger on my right hand were tingling on and off. After some brief research I found that these were common symptoms of Carpal Tunnel. In addition to that I now have burning sensations in my knuckles/joints and stiffness in my forearm and wrist.

    Now, Carpal Tunnel is only one affliction in a family of problems that is RSI (Repetitive Strain Injury). Some of these include tendonitis, arthritis, carpal tunnel etc.. So before you jump the gun and assume that you have Carpal Tunnel, visit your doctor to get a sure answer. 

    First and foremost, take a break. At my peak over the last 2 or 3 months I have been spending about 14-15 hours a day at the computer typing away and coding. The very first thing I did was take a 2 day break over the vacation and iced my hand all the time. This helped me a lot and brought down a lot of the swelling.

    It seems the steps you take from here is where there are a lot of different options and opinions. For some links on information that I have gathered thus far take a gander at my RSI tag at Delicious. That's just some of the information I've gathered with a little bit of research. The two oldest links are by Phil Haack and Jeff Atwood with great information on what options you have with dealing with it. Phil Haack deals with RSI while Jeff Atwood fortunately does not.

    Some of the things I have done to help with my symptoms are simple things at the time being. The first thing I did was switch my mouse to my left hand. It felt very awkward at first but I am getting much better at finer control with the left hand. This helped a lot as I only had to use my right hand for typing. Next, I purchased a decent wrist brace from walmart to help stabilize my wrist which I haven't used that much as I switched mousing hands.  I purchased some Ibuprofen to help the swelling in my right hand and to help with the inflammation. I also got a stress ball from work that I have been using constantly to help strengthen both hands. Icing the wrist/hand at the end of the day works wonders for me and definately helps for sleeping and such.

    The most major change I made in the attempt to stop any further problems in both hands was switch to the dvorak layout. This has been tricky as it is very hard picking up a new keyboard layout. This is a very logical way to go however. Simply put, your hands do less traveling with the dvorak keyboard than the qwerty keyboard. I have been practicing an hour a day for the last 5 days and am getting pretty good. For any long periods of typing such as this blog post I switched back to qwerty as it would have taken me an hour to type out this entire blog post. For everything else though I have been using dvorak. I got a new flat apple keyboard from work and swapped all the keys as well as swapped all the keys on my macbook pro for the new layout. I think this is the first time I have gone back to qwerty in about 3 days. I've heard it takes about a month to pick up the new layout. So far so good.

    In closing, if you have any symptoms at all in shoulders/back/hands etc..., take them very seriously. Do some research and then see a doctor. There is no penalty for being careful. If symptoms go unchecked, the damage can be permanent and irreversible. Don't take anything I have said here as gospel or anyone else for that matter. Do your own research and seek a specialist. The industry we are in doesn't have many show stoppers, but this is certainly one of them. 

  • What I do

    Here is my response to Jason Meridth tagging me.

    I'm a Senior Programmer/Analyst for Flagler County School District in Flagler County Florida. Flagler county is situated in North East Florida, about 30 miles north of the famous Daytona Beach.

    Even though my title says "Programmer", I am definitely a multi-roled employee of the school district. My main duties include programming, DBA, graphic designer, Network Technician and a couple of other things here and there. Mainly I do all the database work and all the development. I am the sole developer for the school district and the sole DBA as well. My language of choice is C#, although I am starting to do more RoR development for smaller applications that have shorter life cycles.

    The biggest project I maintain is our public website which can be found at http://www.flaglerschools.com. This website is built with Castle MonoRail, Windsor and NHibernte on the back end. It allows every teacher/department and school in the district to maintain their individual website through an easy to use CMS interface. For the content editor I am using TinyMCE. We have about 600 teachers on the portal at this time and about 10 schools. We just launched it this past August. It took myself about a full 5 months of development to create it.

    Along with the public website there are a number of internal applications I developed and maintain. Some of these include a Timesheet logger for pay roll, a number of tools for the technology department uses to help manage active directory and our large user base. I frequently build reports and applications for various other departments in the district.

    For source control I use Subversion. I was using VSS about a year ago but since going to svn, I couldn't imagine going back. I have an ubuntu linux server that I am using for my apache/subversion server. Another linux server is my production RoR server that is running nginx/mongrel.

    Working for a school district definitely has it's perks though. Due to the fact that the district is not driven by profit opens a whole myriad of opportunities for me in the development world. First off, I can use any open source technology I wish without question. Management actually encourages me to use open source before purchasing tools as it matches well with education and as long as we have knowledgeable staff to support it, it just makes more sense. In addition to that, I can pretty much ask for anything I need (books, software, training) and get it as long as I supply a good reason for it.

    I work with about 20 fellow geeks in my department whom are mainly techs at each of our remote sites. I work at the main district office along with our network routing guy and our GP/AD administrator and a couple other office staff.

     

    Here are some of the tools I use on a day to day basis:

    • NAnt
    • CruiseControl.Net
    • Subversion
    • NUnit/MbUnit (newer projects)
    • RhinoMocks
    • Castle Project (MonoRail, Windsor/MicroKernel)
    • ReSharper (who doesn't?)
    • jQuery/Prototype/Scriptaculous (moving everything towards jQuery)
    • Notepad2
    • Pentaho Data Integration (really neat tool!, instead of stupid SSIS)
    • MediaWiki (online school board policy)
    • VisualSVN (awesome tool!)
    • VS 2005/SharpDevelop for IDE's
    • VMware Fusion on my Macbook Pro
    • Firefox w/ Firebug (couldn't live without it for CSS/AJAX debugging)

    Probably forgetting a couple but can't think right now.

     

    In turn, I tag the following:

    Bill McCafferty

    Colin Ramsay

    Chris Patterson

     

    What would you say you do here?

  • Choosing a JavaScript Framework

    Before I dive into details of details I found in each framework I think it would be best to highlight features of each framework. In case you've been living under a rock, a javascript framework makes it easier for you to write complex javascript code. Almost all of them provide an effects framework for snazzy visual effects along with AJAX support for making remote updates/calls to your server. When writing any javascript in this day and age it is almost a requirement to have one of these handy frameworks in your toolkit. Like any new technology, many different variables are taken into account when making a decision. I will try to highlight as many of these variables in this posting.

    - jQuery : http://jquery.com/

      • supports method chaining
      • basic methods for dom traversal, find(), gt(), lt(), next(), parent(), siblings() etc..
      • excellent documentation
      • limited examples
      • has effects built in
      • very easy to use and get started 
      • size at ~20kb

    - Prototype/Scriptaculous : http://www.prototypejs.org/

      • supports method chaining
      • poor documentation besides API docs
      • hardly any examples
      • effects are accomplished via scriptaculous
      • scriptaculous about 30kb
      • size about 15kb

    - Yahoo! User Interface : http://developer.yahoo.com/yui/

      • uses namespaces to accomplish tasks. i.e. YAHOO.util.DOM, YAHOO.util.Effects
      • utils seperated out into files to load only what you need
      • backed by a large corporation
      • excellent documentation (almost too much)
      • good support for modern browsers
      • extremely small footprint when compressed (3kb per feature) (about 20kb for everything)

    MooTools/MooEffects : http://mootools.net/

      • API Documentation
      • Limited examples
      • size at 20kb

     

    The frameworks that I specifically looked at were Prototype/Scriptaculous, jQuery and YUI. I have used MooTools in the past but not recently. I played briefly with some other frameworks such as dojo toolkit. I just didn't have enough time to download and play with all the frameworks as each has it's own learning curve that is usually pretty steep. I would have liked to review them all but this was not possible.

    The first thing in the whole scenario is to decide what is most important to you from the framework. Is it file size of the framework? Support for different types of browsers? Documentation and Samples? For instance, if I were building an application that will only be used internally in my organization by a specific browser (IE7) then I would probably want to use the framework with the best support for IE7. If it is a widely used application across all browsers then perhaps speed and file size would be more important.

    As far as support for modern browsers go when testing Firefox/Safari 3 and IE 7, the differences are negligible. Almost all the major javascript frameworks have good support for the 3 major browsers. If you need to support other more exotic browsers then you would have to choose the framework more wisely.

    When I chose a framework for a recent set of projects the most important thing to me was the amount of documentation. Everything else was taken into account but documentation would allow me to learn the framework quickly and easily. YUI was clearly the framework that had to most massive amount of documentation. With step by step instructions on how to setup each effect/feature from the javascript include all the way up to the actual js code. YUI almost has TOO much documentation as when you start reading through the docs they throw so many documentation sources at you that your head spins. All in all, YUI had the best documentation with jQuery next and prototype last.

    The next thing I took into account was how efficient each framework was as far as code goes. I made a sample of a javascript that captures a link click, traverses the dom to find the parent element with a specific class name, slides down that div and makes an AJAX call which updates another div. jQuery was clearly the winner here. Although jQuery code is more cryptic and harder to read, it is extremely efficient. It took about 50 lines of code to accomplish this in prototype versus only 25 lines in jQuery. I was amazed at this and it definitely warmed be up more to jQuery. Particularly in the AJAX calls. Prototype and other frameworks require a pretty verbose function to make an ajax call. You can shorten it but it is much more verbose then it needs to be. jQuery accomplishes an ajax update by simply calling mydiv.load(). This was very neat as this is the most common ajax call that I use. One thing I did have a problem with was using $.ajax calls with Castle MonoRail. NVelocity interpets $. as a variable and thus removes it from the output. To work around this you just need to set a literal in nvelocity like so: #set($ajax = "$."), then you can use $ajax in your js code and it will be replaced with the proper jquery string at runtime.

    Another thing to take into account is groups/irc channels that support these frameworks. All the major ones have irc channels on irc.freenode.net and every framework has a Yahoo/Google group for the corresponding framework. These are good avenues to ask for help once you can't get something to work correctly and are stumped.

    All in all, I will be moving forward with jQuery as it just felt natural once I picked it up and started running with it. I ran into less problems and accomplished more tasks faster then I could with the other frameworks. YMMV depending on your requirements. Hopefully this will help a couple of people out that head down the same path that I have traveled down in the last couple of weeks!

  • What really are the ALT.NET Shared Values?

    Phil Haack just wrote a post about Composition over Inheritance and how adopting practices just because they are talked about is silly. I agree 100% with him on this note. Making a design decision without context is like removing your engine from your car to make it go faster. It's just completely backwards. I have been busy this week and didn't have a chance to read the thread on the alt.net mailing list but this is just silly to propose.

    I think it is very important that the alt.net community doesn't identify a particular practice as non-alt.net or not. Maybe we can recommend what is considered "good pratice" like the patterns & practices team but no one should be shunned for doing something the way they like it. As Phil states, the alt.net community is in an identity forming stage. A stage of critical mass if you will, and what happens over the next couple of months/years will determine if it is here to stay. Even if for some reason it doesn't make it, there will always be a community of developers that always strive and look for more.

    The reason I gained interest in alt.net is because it is a community where people strive for better. I align myself with this because when I write a piece of code the first thing I do is look at the code I just wrote and try to see if there is a better way to do it. Either with tools, refactoring, design patterns or whatever the case may be. In my eyes, the alt.net community is about exactly that. Other ways that are outside the scope of Microsoft, may I stress a point here: NOT against what Microsoft says, simply another way of doing things that may or may not align with Microsoft. Just because the alt.net community doesn't always agree with Microsoft doesn't make them completely against them. It is a free world after all.

    What is your opinion of what the alt.net shared values are?

  • Phil Haack posts about ASP.NET MVC

    Phil Haack has a tutorial type post of usage of the new MS MVC with TDD, DI and the Repository Pattern. In the tutorial he sets up a new project, creates a repository and gets a sample app up and running with StructureMap.

    As I stated in the comments of his posting there are only two things that concern me off the bat. The first thing is the fact that every action on controllers require a [ControllerAction] attribute. This is very descriptive of the controllers but really unnecessary. It adds a lot of extra typing for no real benefit. I realize they are trying to make sure that developers aren't running around naked with scissors but descriptive documentation stating every public method will be an action would work better here. My hope is there will be some way to override this behavior.

    The other thing that concerns me in the post is the way he is passing a parameter back to the view when calling RenderView like so: RenderView("myview", mycollection). I would imagine that they have a way to set parameters to an array like PropertyBag[] in MonoRail. Perhaps there is a way to accomplish this already. I haven't really dove into the documentation for the new framework. I am trying to hold back until the CTP.

    All this is great and excellent that a MS employee is now explaining how to use TDD with a new framework from MS. This is a great move on their part and I'm glad we've gotten this far. The new framework looks great and I'm sure it will do fine with the community.

    Regardless of how awesome it looks, I do have to go back to an older posting that I wrote that describes at the end of the day, this is still a Microsoft technology. Therefore, there is no way you can take this framework and add features to it yourself, or fix bugs, or contribute to it. This fact alone makes me very nervous about using it. I don't mean to get on an open source soap box here but these are the types of things I look at when choosing a new framework. Sure, it is made by MS, but how many times have you been burned by a MS tool? It just makes me nervous that this is not Open Source. The main reason that MonoRail has been so successful is because it is open source. They have an extremely large number of contributors that help make MonoRail successful.

    Anyway's, before I piss of too many people I will say farewell and I am very much looking forward to the MS MVC CTP which is coming very soon!

  • Configuring MacBook Pro for multi-platform development

    I received a MacBook Pro yesterday from my boss. He purchased a new one and I got his old one. I was ecstatic. The memory and small screen/keyboard was really holding me back on my MacBook. With the larger display (15") and large keyboard I have already found that the MBP is much easier to use then a MB. Couple that with the fact that it is actually lighter than a MB, I'm sold.

    This is just a little log of the steps I went through to setup my MBP with a RoR development environment and a VMWare Fusion Bootcamp Partition for Visual Studio and any other supporting apps I need that is still in Windows.

    Here's a list of things that I installed for both OS's

    Apple

    • Ruby on Rails Environment already installed on Leopard!
    • TextMate
    • FireFox with FireBug (definately a must)
    • Freemind (Mind mapping software for notes and brainstorming)
    • Cord (Remote Desktop software)
    • Colloquy (IRC channel so I can hang out in #alt.net on freenode)
    • svnX (svn is installed on leopard by default, but I like having a GUI sometimes)
    • Mac OSX Software Updates (to get Boot Camp)

    Windows

    • Windows Updates (like 36 of em)
    • Visual Studio 2005
    • VisualSVN
    • ReSharper for Visual Studio
    • TortoiseSVN
    • SQL Server Management Studio
    • Windows Live Writer

    When setting up the development environment on the Apple I was going to install MySQL to use for RoR development but after some searching I found out that MySQL has not yet released an install for MySQL on Leopard yet. This didn't matter though because RoR uses Sqlite by default.

    So the first step was to transfer files from my old macbook to my new MBP. If you are migrating from an old mac and have the benefit of coming from leopard then the easiest path would be to perform a backup to an external hdd and then use migration assistant to restore to your new macbook with time machine. In my instance I didn't have enough data to justify this so I simply just backed everything up to dvd and popped it in my new macbook pro.

    Next task was to get Bootcamp installed. A couple of coworkers and myself experimented with VMWare Fusion in a couple of different configurations in the past and the best performance is to install windows on a bootcamp partition and then run the bootcamp partition within vmware. I created a 15gb partition and I was off.

    After installed Bootcamp and Windows XP, I then rebooted into Leopard and installed VMWare Fusion. When fusion was finished installing the Bootcamp Partition will automatically show up under the list of available virtual machines too boot from.

    The rest is pretty much self explanatory. Enjoy!

  • Setting up a Ruby on Rails Production Server while keeping your sanity

    So last week a co-worker came to me and said he needed a "quick and dirty" application for keeping track of assets internally. I told him that I didn't have enough time to do a full scale .Net web app but that perhaps RoR could give us what we were looking for. Within 30 minutes we had a pretty good looking model setup and was entering dummy data into it with the help of scaffolding. My co-worker assured me that this would be fine for now pending a handful of changes and validations to perform when entering data. That being said I set off to get a production server up and running. That's where I left my sanity.

    This post will just go over the steps I took to setup a RoR production server and getting deployment to work. The article that helped get everything setup was this blog posting here by Urbanpuddle. That post gets you pretty much 99% of the way there and walks you through setting up almost everything in Ubuntu. There were a couple of quirks near the end that I will go over.

    Now, I am a RoR newbie so I really can't complain about the language at all. I find it to be very easy to use with a huge support community. My pain point is getting a darn production server up and running. The amount of steps that you must take is just absolutely ridiculous. As far as a *nix production server goes, it needs ALOT of work. Just to give you a small taste of what you need to setup on your production server:


    Step 1. Supporting Libraries

    • ruby, ri, rdoc
    • mysql-server
    • libmysql-ruby
    • ruby1.8-dev
    • irb1.8
    • libdbd-mysql-perl
    • libdbi-perl
    • libmysql-ruby1.8
    • libnet-daemon-perl
    • libplrpc-perl
    • libreadline-ruby1.8
    • libruby1.8
    • mysql-client-5.0
    • mysql-common
    • mysql-server-5.0
    • ruby1.8

    Now this is just absolutely crazy. The ruby guys really need to include all of this in one single package like they recently did for the BitNami RubyStack. I think this is where they are heading with it. There is a spot for Linux and Mac x86 but only for available for windows at the moment. When they do complete this it will allow a lot of people to keep all of their hair.


    Step 2. Install RubyGems & Ruby on Rails

    So now we can get down to the meat and potatoes. Once you install the exhaustive list of apps above you can install Ruby Gems and then install rails. No problems there. This is pretty well documented on how to install so I won't dive into this.

    Step 3. Web Server (Nginx and Mongrel)

    Before I describe the steps here, I will give credit to Greg Benedict for his blog post on Nginx/Mongrel as this is what I used to get it working. I had to modify how the configuration is setup to suit my needs but his post got me almost all the way there. You can find his detailed post here.

    railsscalelighttpd15First let me describe how all of this fits together. I was a little confused at first and would have liked a description as to how everything works. I found this picture on the net to give a basic overview of how Nginx and Mongrel fit together.

    User requests a page and nginx is dispatched. The configuration file is checked and then the request is forwarded to an available mongrel in the cluster.

    In the picture to the left we have 3 mongrels in the cluster. Pretty straight forward.

    Now, I chose nginx as a web server this time around. About 6 months ago I attempted to get apache to work with Mongrel clusters and I could never get it to work so I gave up. This time around I figured I would give something else a try. After looking around I found that Nginx was really easy to configure and a VERY small memory footprint, like 10mb or something around there. That's what sold me on it.

    So first you need to install Nginx (pronounced engine x) and once thats done, you install fastcgi. Fastcgi is used for parsing php pages like phpMyAdmin for managing the mysql databases. If you are comfortable managing mysql from the command line, then don't bother with phpMyAdmin.

    Next is the nginx configuration file. The way I was setting up my server is to have multiple named virtual hosts so that I could host multiple ruby apps from the same machine name. The first thing I had to do was add a CNAME wildcard into DNS so that anything.myservername.com would get forwarded to the same IP address. Next you setup a generic nginx.conf file to handle the general configuration. This will apply whether you are doing multiple named virtual hosts or not.

    Here is the configuration that I am using. It is located at /etc/nginx/nginx.conf

     

    user www-data www-data; worker_processes 1; pid /var/run/nginx.pid; # Valid error reporting levels are debug, notice and info error_log /var/log/nginx/error.log debug; events { worker_connections 1024; } http { # pull in mime-types. You can break out your config # into as many include.s as you want to make it cleaner include /etc/nginx/mime.types; # set a default type for the rare situation that # nothing matches from the mimie-type include default_type application/octet-stream; # configure log format log_format main .$remote_addr - $remote_user [$time_local] . ..$request. $status $body_bytes_sent .$http_referer. . ..$http_user_agent. .$http_x_forwarded_for..; # main access log access_log /var/log/nginx_access.log main; # main error log error_log /var/log/nginx_error.log debug; # no sendfile on OSX sendfile on; # These are good default values. tcp_nopush on; keepalive_timeout 65; tcp_nodelay on; # output compression saves bandwidth gzip on; gzip_min_length 1100; gzip_buffers 4 8k; gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascr$ gzip_http_version 1.0; gzip_comp_level 2; gzip_proxied any; server_names_hash_bucket_size 64; # The following includes are specified for virtual hosts include /var/www/app1/current/config/nginx.conf; include /var/www/app2/current/config/nginx.conf;
    include /var/www/app3/current/config/nginx.conf }

     

    Pay attention to the last 3 lines in the nginx.conf. These lines include an external configuration that is located under the apps config directories. What this does for us is it allows you to just add one line in your /etc/nginx/nginx.conf, and thats all that needs to be done in nginx when adding another application to your server. Pretty nifty.


    And here is the configuration for my app1 which is located in  /var/www/app1/current/config/nginx.conf

    # The name of the upstream server is used by the mongrel
    # section below under the server declaration
    upstream app1 {
      server 127.0.0.1:8000;
      server 127.0.0.1:8001;
      server 127.0.0.1:8002;
    }
    
    server {
      # port to listen on. Can also be set to an IP:PORT
      listen 80;
    
      # Set the max size for file uploads to 50Mb
      client_max_body_size 50M;
    
      # sets the domainSleep that this vhost server requests for.
      server_name app1.myservername.com;
    
      # doc root
      root /var/www/app1/current/public;
    
      # vhost specific access log
      access_log /var/www/app1/current/log/nginx.access.log main;
    
      # this rewrites all the requests to the maintenance.html
      # page if it exists in the doc root. This is for capistrano.s
      # disable web task
      if (-f $document_root/system/maintenance.html) {
        rewrite ^(.*)$ /system/maintenance.html last;
        break;
      }
    
      location / {
        # Uncomment to allow server side includes so nginx can
        # post-process Rails content
        ## ssi on;
    
        # needed to forward user.s IP address to rails
        proxy_set_header X-Real-IP $remote_addr;
        # needed for HTTPS
        #proxy_set_header X_FORWARDED_PROTO https;
    
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect false;
        proxy_max_temp_file_size 0;
    
        # If the file exists as a static file serve it directly without
        # running all the other rewite tests on it
        if (-f $request_filename) {
          break;
        }
    
        # check for index.html for directory index
        # if its there on the filesystem then rewite
        # the url to add /index.html to the end of it
        # and then break to send it to the next config rules.
        if (-f $request_filename/index.html) {
          rewrite (.*) $1/index.html break;
        }
    
        # Look for existence of PHP index file.
        # Don.t break here.just rewrite it.
        if (-f $request_filename/index.php) {
          rewrite (.*) $1/index.php;
        }
    
        # this is the meat of the rails page caching config
        # it adds .html to the end of the url and then checks
        # the filesystem for that file. If it exists, then we
        # rewite the url to have explicit .html on the end
        # and then send it on its way to the next config rule.
        # if there is no file on the fs then it sets all the
        # necessary headers and proxies to our upstream mongrels
        if (-f $request_filename.html) {
          rewrite (.*) $1.html break;
        }
    
        # You.ll need to change this proxy_pass to match what
        # what you specified above. It must be unique to each vhost.
        if (!-f $request_filename) {
          proxy_pass http://app1;
          break;
        }
      }
    
      error_page 500 502 503 504 /500.html;
      location = /500.html {
        root /var/www/app1/current/public;
      }
    }
    

     

    First pay attention at the top where you have the upstream section. Note the name as it is used further in the config file to state what mongrel cluster nginx should forward to for this servername.

    The thing to nice is that most of this configuration is encapsulated in a server {} tag. This is the section that holds a virtual host. You can have as many of these as you want per nginx. I have just seperated them out into seperate files to facilitate easier configuration.

    Second, make note of "server_name" and change that to the server name that will be handling requests for this app. This can be myserver.com, or you can have it setup as a subdomain as I do.

    Last, change all other references to app1 to whatever your app is named, then at the bottom you will notice the proxy_pass. This portion is what forwards requests to your mongrel cluster. Change http://app1 to whatever you had for the upstream at the top. They need to the same otherwise you will receive 502 errors.

    Ok, now that we have the nginx configuration out of the way we can go on to your Mongrel cluster.

    The mongrel cluster is pretty easy to configure. Here is the mongrel_cluster.yml file that you can drop into yourapp/config/mongrel_cluster.yml

    cwd: /var/www/app1/current
    port: 8000
    environment: production
    user: produser
    group: produser
    address: 127.0.0.1
    pid_file: /var/www/app1/shared/pids/mongrel.pid
    servers: 3

     

    Pretty straightforward. Grab the Restart script found here. And place that in /etc/init.d/. This will allow you to do "sudo /etc/init.d/mongrel_cluster start|stop|restart" 

    Your mongrel_cluster.yml file needs to be linked to /etc/mongrel/app1_cluster.yml. This way, when you use the restart script. It will look in /etc/mongrel to restart all clusters that are running on the machine. You can create the link like so:

    sudo ln -s /var/www/app1/current/config/mongrel_cluster.yml app1.yml

    Now that you have that out of the way you can get to deployment with capistrano.

    Step 4. Deployment with Capistrano

    First I would note that if you install the latest version of Capistrano it will be version 2.1. For some reason the RoR documentation is outdated and references the old version of capistrano. Before you would do "rake deploy" but now you run capistrano commands like so: "cap deploy". This was a bit of a pain but there are people out there using it so the documentation should be updated soon.

    Capistrano is a standalone utility much like nant. You can run different tasks, deploy in different configurations etc.. The difference is that capistrano can do a lot more stuff than nant can. I only scratched the surface so I employ you to dive further into capistrano.

    The really cool part of capistrano deployment is the ability to rollback a deployment. Basically what happens is upon deploying via capistrano, it first exports from subversion to a folder that is named the UTC datetime of the deployment. Then it creates a link from that folder to the current folder that is referenced above. Previous deployments still live in their datetime folder but are no longer symlinked to the current directory. When you want to rollback a deployment type "cap rollback" and everything is undone including your database migrations. Pretty neat eh?

    Ok, so you have your app built, you have created a subversion repository for it and have checked in your changes to your repository. Now you want to deploy it to your brand new shiny deployment server.

    This is the part where I slipped into the seventh level of hell.

    There is A LOT of different blog posts on how to accomplish this. After trying  multitude of different ways I settled on this deployment script that lives in app1/config/deploy.rb

    set :application, "My App"
    set :repository,  "http://yoursvnserver/svn/app1/trunk"
    set :user, "username"
    set :password, "password"
    
    set :deploy_to, "/var/www/app1"
    set :deploy_via, :export
    
    set :mongrel_conf, "#{deploy_to}/current/config/mongrel_cluster.yml"
    
    role :app, "username@mydeploymentserver.com"
    role :web, "username@mydeploymentserver.com"
    role :db,  "username@mydeploymentserver.com", :primary => true
    
    namespace :deploy do
      desc "Restart mongrel servers"
      task :restart, :roles => [:web] do
        run "cd #{release_path} && sudo /etc/init.d/mongrel_cluster restart" do |ch, steam, out|
          ch.send_data "#{password}\n" if out =~/password/
        end
    
        run "sudo chown -R www-data:www-data #{release_path}/tmp" do |ch, steam, out|
          ch.send_data "#{password}\n" if out =~/password/
        end
      end
    end
    

     

    Ok so most of the deployment file is self explanatory. :repository should be set to your repository address, Set :user and :password to the sudo user and password on your deployment server. Now, if you are deploying over the web, I would strongly suggest looking for another way to transmit this data, perhaps an SSL deployment or something. I am running this server on my internal network with limited usage so I didn't care if all this information was sitting in my repsoitory but this is bad! bad! bad! =)

    The :deploy_via is how you want to perform the deployment from subversion. This states that subversion will perform an export to the deployment server. You can also do a :co which will perform a checkout. Export seemed like the more logical way.

    :app, :web and :db are your deployment servers. I am using all the same server so they are all the same. If you wanted to you could break out your application to seperate servers for performance. Pretty neat that it has that option ready to go in there.

    The next portion is a little different. This is where you can define commands to run, tasks to perform on the remote server. First I tell it to cd to the apps root directory and then restart the mongrel_cluster. The ONLY thing you need to restart after a deployment is your mongrel_cluster. There is no need to restart nginx.

    Let me clarify here. In your /etc/init.d/mongrel_cluster script it states who the mongrel clusters should run as. BE SURE that the user you defined there has access to the shared/pids folder otherwise mongrel cannot write the pid files and will fail to start. I bounced around with this problem for a couple of hours banging my head on the wall between attempts.

    Next I added in a chown command as I noticed that after everything completed successfully, the nginx user could not write the ruby sessions to the tmp directory. That command fixed the problem, everything was working and there was much rejoicing.

    Now, there were quite a few bumps in the road throughout the process that I failed to document but after searching on google for awhile and poking I was able to get around all of them. As a result if I setup another server I know what to expect now and hopefully so will you!

    I hope this helps at least one person avoid the insanity that I endured for a couple of days. Good luck!

  • Hiring a Developer Part 1

    In the next couple of weeks we will be posting positions for two new developers to work with myself. As a service to the community I am going to post the process I am going through on my blog so everyone can see what I did when hiring a new developer that would perhaps give them a better idea what works and what does not. Down to business!

    My Initial concerns. The area I live in is pretty scarce on tech jobs. The school district I work at is the largest employer in the county and the largest provider of tech oriented jobs so pickings are very slim. My boss and I already typed up a brief description of what type of developer we are looking for that will be posted on Dice and Monster. These will be posted on those websites before we formally place a job posting on our website. I didn't expect to find anyone that is familiar with OSS tooling or many of the other technologies I work with but I figured if I could get someone that at least knows C#, SQL and a couple of other things, that I could teach them the rest without too much effort.

    Everytime we post for an open position we get ALOT of people apply for positions that are not even qualified. It seems like many people just throw everything up there to see what sticks so I am not looking forward to the interview process. I am not going to interview people that have no OOP experience because everyone and their mother has created a website for their family that I do not care about =) Bottom line is, there will be alot of applicants to weed out.

    The next part that I have thought about is code tests. I have read in alot of places that people have the interviewee do a simple fizz buzz problem or something along those lines. I'm not sure if this is a good indicator of their work but it would at least tell me if they have problem solving skills which IMO every programmer already has, if they don't then this test will clearly display this.

    These are my initial thoughts on the process. When we get closer I am sure I will have some interesting posts on what works and what doesn't. If anyone has anything to add please comment!

    Posted Dec 04 2007, 04:58 AM by schambers with 9 comment(s)
    Filed under:
Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems