In the groove.

Yesterday was one of the most productive days I’ve had in ages. I did some huge revisions to CONGO‘s appserver (the core application that holds all the business logic).

After being sick for a day, and having a tooth extracted earlier in the week, I was feeling edgy about the amount of stuff getting done, but yesterday’s 4-6 hour burst of code updates really helped.

For those into the geekier details, read on!

There’s a set of interfaces that I provide with CONGO that allow PHP applications to talk to the appserver. This file (called ‘congoxml_libraries.php’) had a single function for every method call in the XMLRPC server.

The problem is, like a dolt, I had written up an call wrapper for one of the methods when I first developed it, and… well, never really thought about it again. To add a new method interface, I duplicated the code block, and changed the method names and added other handlers as needed.

The old code block looked like this:

215   #-------------------------------------------------------------------
216   function getLocationByID($locrid,$loctype,$locname) {
217     Global $spath, $shost, $sport ;
218     logit("Calling registrants.getLocationByID for '$locrid', location '$loctype','$locname'");
219     $rid_val = new xmlrpcval($locrid,'int');
220     $type_val = new xmlrpcval($loctype,'string');
221     $type_name= new xmlrpcval($locname,'string');
222     $f = new xmlrpcmsg('registrants.getLocationByID',array($rid_val,$type_val,$type_name));
223     $c = new xmlrpc_client($spath,$shost,$sport);
224     $c->setDebug(FALSE);
225     $r=$c->send($f) or dieError("xmlrpc","getLocationByID","Send failed to RPC server");
226     $intresults = phpxmlrpc_decode($r->value());
227     if (isset($intresults['faultString'])) {
228       dieError("xmlrpc","getLocationByID",$intresults['faultCode'],$intresults['faultString']);
229     }
230     logit("status.getLocationByID call succeeded");
231     return phpxmlrpc_decode($r->value());
232   }

Now, consider that replicated 60 or so times, and you see a coding maintenance problem. The file had grown to 1600+ lines, and I was dreading adding new interfaces into CONGO, because each time I had to replicate that block.

After pondering it for a while, I realized the interface could be simplified down to one generic function, and all the method interfaces could call it. I wrote up a generic sendQuery() function, like this:

19   function sendQuery($methodName,$parameterList=array()) {
20     Global $spath, $shost, $sport ;
21     logit("Invoking $methodName");
22     $f = new xmlrpcmsg($methodName,$parameterList);
23     $c = new xmlrpc_client($spath,$shost,$sport);
24     $c->setDebug(FALSE);
25     $r=$c->send($f);
26     if (0 != $r->errno) {
27       // New dieError.  Doesn't actually -die-.
28       logit("Dying in $methodName");
29       dieError("xmlrpc",$methodName, $r->errstr,"");
30     } else {
31       logit("Successful call to $methodName");
32       $intresults = phpxmlrpc_decode($r->value());
33       if (is_array($intresults)) {
34         if (isset($intresults['faultString'])) {
35           dieError("xmlrpc",$methodName,$intresults['faultCode'],$intresults['faultString']);
36         }
37       }
38     }
39     logit("Exiting $methodName");
40     return phpxmlrpc_decode($r->value());
41   }

Using this generic wrapper, I was able to rewrite all the interfaces in congoxml_libraries.php to call sendQuery. The above method call was now shortened down to:

115   function getLocationByID($locrid,$loctype,$locname) {
116     $rid_val = new xmlrpcval($locrid,'int');
117     $type_val = new xmlrpcval($loctype,'string');
118     $type_name= new xmlrpcval($locname,'string');
119     return sendQuery('registrants.getLocationByID',array($rid_val,$type_val,$type_name));
120   }

Wow what a difference. congoxml_libraries shortened from 1600+ lines to about 925, and is now far easier to manage, and will parse faster on each hit. A major step forward in code maintenance.

With that in place, i was able to fix a slew of other bugs that had been cropping up (noteably in the ‘browse registrants’ functions, etc). The next step will be to complete the ‘maintain registration pages’ functions inside Coconut and get them live for a customer who is asking for them.


A wandering geek. Toys, shiny things, pursuits and distractions.

View all posts by

One thought on “In the groove.

Comments are closed.