Sunday, March 18, 2012

Codeigniter load->model and load->library ideosyncracies

Codeigniter's load model and load library commands both create Singletons, which are global in scope.  This can produce difficult to diagnose bugs if you don't realize it.

When you execute a $this->load->model('model_name', 'instance_name') , it invokes the "model" method in the CI_Loader class.  This method first checks that no other instance of the model exists with the same name.  If you do not give a name, then it uses "model_name" as the "instance_name".  This method stores the name of every model it has created in an array named "_ci_models".  If it does not find the name there, it then looks for it in $CI which is the super object you access via "$CI=& get_instance();". 

Because the model method executes an "if (isset($CI->name))" prior to instantiating the class, there cannot be any any object of any type anywhere within codeigniter that has the same name.  Hence it is global in scope.

And you cannot overwrite the assignment directly.  So let's say for example we are trying to make a "$Vendor_details" object.  And we want to assign one of two different address storage models to it based on the "$vendor_type".  So we create code something like the following.

switch ($vendor_type) {

case "domestic" :
$this->load->model('models/vendor_domestic', 'vendorModel');
break;
case "international" :
$this->load->model('models/vendor_international', 'vendorModel');
break;
...

And we try to access this model via "$this->vendorModel->someFunction".  Let's say the first time through, "vendorModel" is set to reference an instance of "Vendor_domestic", but the next time through, $vendor_type = "international".  We try to create an instance of  the "Vendor_international" model and assign it to $this->vendorModel.  We will get no warning, but we will in fact end up accessing the "Vendor_domestic" instance we created in the first pass, because "$this->vendorModel" cannot be reassigned, and it is pointing to the instance we first created. 

Once the name checks pass, the model method executes a "require_once" on the model name and then creates an instance of it references to either "instance_name" or the model name if no "instance_name" argument was passed in.   It also opens the database connection. 

The library load operates in a very similar way, but of course it does not open the database (which is probably already open anyway in most cases). 

If you need multiple copies of a model or library, you will need to instantiate them by including the referenced class in the top of the file with a:
require_once('path/modelName.php') in the top of the file

and instantiate the class with the standard:
$instance_name = new modelClassName();

Saturday, March 17, 2012

Repairing Model 77 Skill Saw

Recently, my Mag 77 Skill saw suddenly stopped working.  I made a cut.  I put the saw down (gently), and when I picked it up, it sputtered for a second and stopped.  I hit the switch again.  It sputtered slightly again, and that was the last sign of life from it.  Luckily, I have another older saw, so I finished the project with that.

I was just going to buy another saw, but when I saw that the price tag on this saw model, which Skill still sells was $189, I figured it was worth the trouble of trying to fix it.

I framed houses for about three years when I was (much) younger.  We used these worm drive Skill saws exclusively.  They are beasts.  They can take ridiculous amounts of punishment.  I have seen them fail, but it usually comes on gradually and involves the triggers or brushes.  However, I use this saw so rarely, it seemed highly improbable that it would be either the trigger or the brushes.  Nevertheless, I inspected the brushes and tested the trigger, and you should too.  

Neither of these was the culprit here.  So I had to dig in and crack the case.  It’s actually quite easy to get into the motor on this saw.  The only caveat is it uses T20 torx screws.  I had a driver laying around, but if not, you are going to have to buy it.  There are some larger Torx screws on the case, but you don’t actually need to pull them in order to get to the motor.

Before you begin pulling the screws, you should remove the brushes if you have not already done so.  They are removed by unscrewing two black plastic plugs from each side of the case.  You can see a picture here of one of the brushes that has been removed.  Notice that I damaged the cap slightly in the process.  Use a screwdriver that fits well.  They are a bit delicate.


Notice that the brush is quite long.  This brush is barely worn.  If you use a saw heavily, you can wear out your brushes.  So if need be, you might have to replace yours.  You risk damaging the brushes if you pull the saw apart before you remove them, and you absolutely cannot put it back together without taking them out anyway as they are spring loaded and  will pop in and block the motor armature from going back in.

You need to pull these five screws (green arrows) to get the saw apart. 


You can see three of them here, and the other two are on the back side.  The four that go into the back of the case are very long.   Notice that small part marked with the blue arrow.  That fell out of somewhere at some point.  After studying the saw a bit, I decided it must be a tensioner for the motor armature.  I’ll show you where I put it when I was reassembling here in a second.

Once I got the saw apart, I saw the problem immediately.  There were two wires not connected to anything.  It was obvious they had been connected together, but had broken.  Unfortunately, it occurred to me to write this up after the fact, and I didn't take a picture of it.  They had been arcing to the case for some time before the saw failed.

If you look at the picture of the cooling fins, you can see the electrical arc damage on them.  


 This explains why this saw had been popping the GFI for about a year before it failed.  I had gotten in the habit of just plugging it inside because the outdoor GFI plug would just trip every time I tried to use it.

What happened was the manufacturer ran one of the supply wires to the forward end of the motor and connected it to the enamel coated wire from the windings.  They taped the two wires down with strapping tape.  The strapping tape failed after a few years, and the wires were long enough that they eventually pulled away from the windings far enough (or maybe got sucked into) the cooling fins.  When they started shorting to the fins, it caused the GFI to pop. And eventually the mechanical strain of hitting the cooling fins eventually broke the connection causing the saw to die.

The fix was very easy.  I cleaned up the enamel coated wire with some sandpaper, and I soldered it back onto the supply wire.  I then taped the connection with electrical tape, and then I taped that to the windings by threading through the electrical tape through the loops using a paperclip.  I put the saw back together, but I still wasn’t feeling too good about it.  Then it occurred to me that what it really needed was a more positive non-conductive fastener like a zip-tie (Panduit).  So I tore the saw back apart, this time not removing any unnecessary screws, and that’s when I also decided to photograph it.

The final work looks like this.  Notice that I didn't clamp the zip-ties directly on the wiring.  They are sitting on electrical tape.  I was a bit concerned about vibration causing them to damage the enamel on the windings.  I think it's probably better to not to tighten them down directly on the windings.  And I snugged them, but I didn't really zip them down as tight as I possibly could.  Maybe it would be better to just tape it.  I really wrestled with that decision before deciding to use the ties.  But I don't trust that electrical tape not to fail after a couple years.  And it's very hard to thread it through the windings.  So two turns was about all I could get per piece of tape.


I think that tensioner marked with the blue arrow above goes where the blue arrow is on this photo.  It's the only place that it fits.  Pay close attention when you pull your saw apart, and you might not have to guess at it.  Mine just fell out in the process.

The saw now works perfectly, and it no longer pops the GFI.

Saturday, March 3, 2012

SVN: Merging Trunk into Branch

In my case, the repository in question is on Jira.  So instead of using svn+ssh://, I use https:// to access the repository.  I am assuming you already have a branch in your local directory, and you want to merge trunk into it.  This is a good practice.  Otherwise, if you have CSS files with revisions for instance, it's quite possible that both you and another developer might mod those files and advance the revision.  This creates a "local add, incoming add upon merge" tree conflict that subversion doesn't know how to resolve forcing you to resolve it manually.  This sort of problem cannot be completely avoided, but at least you can pick up any changes that have already been put back before you alter the files.  Over the course of a long project, you can end up very far behind trunk with a big job to merge if you don't do this occasionally.

Before you start this process, remember to do a commit of your branch picking up any changes that have made.  This keeps the log files clean when you commit the trunk merge, and it allows you to completely roll back the changes in case something goes horribly wrong.  Assuming you have already committed your branch, proceed as follows:

Check out a copy of trunk if you don't already have one.  Otherwise, just cd to the root of it and proceed to step 2.

          1.  svn co https://server/path/to/project/trunk

cd to the root directory of trunk

          2.  svn up

this will already be up to date if you just checked it out in step one, but note down the revision number (YYYY) it spits out.

cd to your branch root directory

          3.  svn log --stop-on-copy

This will display all the revision that have occurred since this branch was cut from the main one.  Find the lowest numbered revision (the oldest one), and make a note of it (XXXX).

Now execute the merge with the following:

           4.  svn merge --dry-run -r XXXX:YYYY https://server/path/to/project/trunk

Note the "--dry-run".  That's completely optional of course, but if you think there may be conflicts, it's not a bad idea to get an idea of what they may be before you start.  

once you are happy with that, run it for real:

           4.  svn merge -r XXXX:YYYY https://server/path/to/project/trunk

resolve all the conflicts.

           5. svn commit -m "Merged trunk into branch"