Shahzad Bhatti Welcome to my ramblings and rants!

August 6, 2009

How Twitters D.O.S brought my blog site to halt

Filed under: Computing — admin @ 12:17 pm

I noticed my blog was taking a long time to load and then realized that twitter’s denail of service attack effected my weblog. My blog shows latest tweets using javascript and as browsers generally block loading the contents when executing javascript, thus my blog was not showing the contents. I noticed that I was violating one of the commandments of Steve Souders, i.e., put your javascripts at the bottom. After moving the javascript calls to the bottom, my blog started loading happily though without the tweets for now. Also, Steve’s new book shows tons of ways to load javascript asynchronously but I haven’t added that to my blog yet.

July 28, 2009

Cut the scope and make your life easy

Filed under: Project Management — admin @ 10:45 am

I have been developing software for over twenty years and in every project you have to grapple with iron triangle of schedule/cost/functionality or sometime referred to as cost/quality/schedule or cost/resources/schedule. In my experience, curtailing the scope produces better results than adding more resources or extending deadline. In addition, slashing the scope also produces other side effects such as reducing the complexity of the software, easier learning curve for users, less training/support cost and better communication among team members.

You can reduce the scope by focusing on essential features using Pareto principle (80-20 rule) and companies like like Apple or 37Signals produce great products that are not only more useful but are much simpler to use. However, this is not easy as project manager or product owner have to say NO. Too often, I see project managers say YES to anything to please upper management and users. In the end, the team is overwhelmed and under stress. Also, a big pile of features where all features are of same importance (priority) is biggest reason for death-march projects.

Working with a small number of features reduces complexity such as essential complexity, cyclomatic complexity or accidental complexity because your codebase is smaller. Though, you still have to apply good software engineering principles such as domain driven design, unit testing, refactoring, etc, but maintenance becomes easier with smaller codebase. When you have a small codebase you have fewer bugs as they are no bugs for zero code. Fewer bugs means less support cost when some user complains of a bug or when system crashes in the middle of the night.

With a small set of features, the user interface becomes simpler, which in turn provides better usability to the users. Often, I have seen users get confuse when they have to work with a complex software that has a lot of features. This often is remedied by providing training or adding support that adds a lot more overhead to the projects. Again, better user interface does not come free automatically with a small set of features, but the usability problem becomes easier with fewer features.

Finally, small number of features and small code means your team size will remain small so communication among team members becomes easier. I like to work with team with size of 5 plus/minus 2, as number of communication links increase exponentially when you add more members. Also, with smaller teams that are colocated, you have better
Osmotic communication that Alistair Cockburn talks about. At Amazon, we have “2-Pizza” teams, i.e., teams are small enough to have team lunch with just two pizzas. Another factor when building teams is whether they are cross functional (vertical) or focus on single expertise such as systems, database, UI, etc. I prefer working with cross functional teams that focus on a single service or an application as communication and priorities within a single team is much easier to manage than between different teams.

In nutshell, reducing scope not only helps you deliver the software in time and delight your users but prepares you better to maintain and support the software. The complexity is number one killer for the software and results in buggy and bloated software. You should watch out when someone says “Wouldn’t it be cool if it did X?” kind of feature requests and often I see developers see this as a challenge or an opportunity to learn or apply new technology. However, each new feature takes a toll on your existing features, software maintenance and your team.

July 26, 2009

Day 5 at #oscon 2009

Filed under: Computing — admin @ 11:00 am

July 24, 2009 that was Day 5 of OSCON 2009 for me started with yet another talk by Gunnar Hellekson on using open source for building government projects. This was followed by very entertaining talk by Erik Meijer on “Fundamentalist Functional Programming”. He talked about side-effect free programming and how most functional languages are not pure. He briefly described Monads features of Haskell and how LINQ is influenced by them. Finally, there were keynotes by Karl Schroeder and Mark Surman, which were not very inspiring.

There were not a lot of sessions on last day of the OSCON, I decided to attend The HTML 5 Experiments to learn a bit on new HTML5 tags. Bruce Lawson showed how he implemented his blog using some of HTML5 tags such as header, footer, section, article, time, etc. He also mentioned canvas feature that was interesting but was difficult for people that require assistance technology. Finally, video tags won’t be available anytime soon due to a lot of proprietary decoders.

I then skipped next session and headed to Tech Museum, which is must see if you are visiting San Jose. I then headed to the airport and flew back to Seattle in the evening. Overall, I enjoyed OSCON 2009, I wished there were more talks on functional programming and was disappointed when haskell talk was cancelled. Also, I wish more talks were a bit more hands on like talks on CoucheDB that showed examples of how to use the system instead of just listing out features.

Day 4 at #oscon 2009

Filed under: Computing — admin @ 9:29 am

Thursday, July 23 2009, which was Day 4 for me at OSCON 2009, started with keynote by Kirrily Robert, where she she deplored acceptance of women in open source projects. This was followed by lame keynote by Tony Hey from Microsoft, where the presenter showed bits of open source contributions by Microsoft. Finally, Simon Wardley talked about cloud computing that was pretty entertaining. I then proceeded to attend talk on JRuby on Google App Engine, which didn’t quite kept up to its name and a lot of talk focused on persistence. I attended talk on Eucalyptus, which is an open source project for building private EC2 based cloud. This was sort of marketing talk, but I got a couple of things out such as how Amazon throttles network traffic within a datacenter to 500mb/sec and between zones to 200mb/sec.

I then attended A Survey of Concurrency Constructs, which presented common constructs for concurrency such as locks, transactional shared memory, message passing, dataflow, futures, i-structures, etc. I liked dataflow due to its deterministic nature, but is difficult to implement. I-structures is also interesting, but is non-deterministic and requires ports that make it similar to actors. I also like Linda as it can simulate dataflow, actors and CSP. Finally, message-passing and actors model are poplar these days due to their implementation in Erlang and Scala languages. Ted mentioned how most of the solutions are 20-30 years old, you can read history of most of these solutions from his slides. This was bleak talk as none of the options presented satisfactory option, though his bias was towards JVM based technology and he was impressed with Jonas Boner’s work on AKKA.

Next, I attended talk on Clojure: Functional Concurrency for the JVM, which described functional nature of Clojure and brief overview of its features and syntax. I found calling Java code from Clojure a little verbose especially when you are using method chaining, e.g.

                 factory.newSaxParser().parse(src, handler)
 becomes
                 (.. factory new SaxParser (parse src handler))
 

Another interesting features of Clojure are its implementation of persistent datastorage and lazy evaluation. Finally, Clojure supports transactional memory for building concurrent applications but there is a little emperical data on its performance and usability. In fact, Ted Sueng mentioned porting some of open source applications to use transactional memory resulted in deadlocks so I am waiting for a little more evidence.

Next, I attended talk on Cassandra: Open Source Bigtable + Dynamo, which is another DHT similar to
Dynomite, Redis, Tokyo Tyrant, Voldemort, HBase, etc. Cassendra is an implementation of DHT based on Amazon Dynamo paper and supports consistent hashing, gossip, failure detection, cluster state, partitioning and replication. I liked the fact that there is no single master as in BigTable so it is easier to scale and uses bloomfilter to keep index of keys. You can read more on its features from the slides.

Last session I attended was “Design Patterns” in Dynamic Languages, where Neal Ford showed how GOF design patterns were created to overcome deficiencies of C++ and he described how dynamic languages like Ruby and Groovy make it trivial to use these patterns without all the ceremony. Neal showed how method_missing can be used to implement builder pattern (though, I prefer not to use method_missing). He showed how each method on array is easier than iterator, how closures can be used to implement command and strategy patterns. Neal then showed, how internel DSLs can be used to implement interpreter pattern. Other examples included decorator and adapter patterns that used invokeMethod feature of Groovy to delegate invocation. Finally, he showed using null object pattern for consistent interface and aridifier to keep your code DRY. You can read more from his slides.

July 25, 2009

Day 3 at #oscon 2009

Filed under: Computing — admin @ 9:44 pm

On the third day (Wednesday, July 22, 2009, the real conference started. The day began with the a couple of keynotes. First, Tim O’reilly talked about Government 2.0, data.gov and other open source organizations that are building applications for the newly opened data. This turned out to be theme of a number of keynote speakers and there was a lot of interest in sunlight labs, http://opensourceforamerica.org/, http://www.gov2summit.com/. Then Dirk Hohndel talked about netbooks and some of innovations from Intel to improve boot time. He deplored state of graphics on Linux that have changed a little in last twenty years. Finally, Mike Lopp, author of Rands in Repose blog talked about how well intentional evil people can ruin companies using Borland as an example.

I started the sessions with Testing iPhone apps with Ruby and Cucumber, which should have been called Testing iPhone GUI apps with Ruby and Cucumber. It was half decent, but the framework had a lot of dependencies that we didn’t go into. I would like to give it a try as testing on Objective-C sucks. I then attended Introduction to Animation and OpenGL on the Android SDK, which seemed too fast and the presenter rambled on miscleneous APIs of OpenGL that I could not follow.

On the second half, I started talk on Automating System Builds and Maintenance with Cobbler and Puppet. This was somewhat useful and I learned a bit to use Cobbler for creating system images and using Puppet for configuration. This was followed by Best practices for ‘scripting’ with Python 3. This was a good talk that described some good principles for writing scripts (as opposed to Python applications). These principles included using optparse for parsing arguments, layers of I/O to help testing (StringIO), using generators for performance and finally using templates for packaging as setup is hard to configure from scratch. I then attended Using Hadoop for Big Data Analysis, which was sort of marketing talk from Cloudera CEO and prsented a few projects that are using Hadoop such as log processing at rackspace, monitoring electircal grid and large hadron collider. Finally, I attended Distributed Applications with CouchDB, which was really good talk on CouchDB by J Chris Anderson from couch.io. It described architecture of CouchDB and features of CouchDB. Chris also gave password for private beta to http://hosting.couch.io, which was “booom-couch”. You can read detailed examples from his slides.

July 23, 2009

Day 2 at #oscon 2009

Filed under: Computing — admin @ 2:34 pm

On the second day of OSCon 2009, I started with PhoneGap tutorial. The PhoneGap is an ambitious project that provides Javascript based unified APIs to develop mobile applications for a variety of mobile platforms such as iPhone, Blackberry, Android, Windows Mobile, Nokia, Palm, etc (most of those are not yet support, but 1.0 is expected in a few months that will have support most of them). It competes with a number of other open source projects such as Joyent Smart platform, Big five, Corona, Nimblekit, Appcellerator, Rhodes, etc. The PhoneGap uses HTML, CSS and Javascript for development and relies on Webkit and HTML5 technologies and standards. Many of mobile platforms such as iphone, android, palmpre support Webkit, though Blackberry and Windows Mobile are exceptions. The PhoneGap uses a number of features of HTML5 such as caching, CSS transformation, fonts, local storage, etc. The PhoneGap uses XUI, which is a subset of jQuery as some of the platforms such as iPhone provide limited caching (25K) for Javascript. It uses selectors and CSS for animations. The session introduced Dashcode tool that comes with XCode to build web applications and then converting those web applications into native applications using PhoneGap. The presenation for this session is available from http://presentations.sintaxi.com/oscon/

For the second half I decided to attend “Scalable Internet Architectures” — more than 10 million consumers/day. It was interesting talk that discussed building scalable architectures from hardware and networking perspective. It empahsized awareness on end-to-end architecture including javascript, application, database, network and machines and stressed importance of including people from operations in the architecture of the system. The presenter suggested use of CDN for static contents and using peer-based HA instead of load balancers as it eliminates load balancers as point of contention or failures. The speaker also suggested use of reverse proxy cache such as Varnish or Squid. He also suggested setting up multiple DNS servers for each data center and registering local servers with local DNS so that they take advantage of shortest path routes and talk to local servers. Other suggestions included use of caching, avoiding 302 redirects, separtion of OLTP and OLAP databases, use of DHT. The speaker also pointed to a number of networking techniques such isolating network for different services to prevent starvation of bandwidth when one of the service is surging the network with high dataload by using mac based filtering.
The speaker mentioned a number of usability techniques to offload expensive operation or hinting users when something is going on in the background. He mentioned use of queuing technology for offload processing. Finally, the speaker talked about a number of lesson learned from scaling and some of big WTF moments from his consulting work. Overall, this talk summarized a lot of existing knowledge for building scalable applications (such as from Steve Souders work) with a couple of new networking techniques to tackle slashdot or denial of service attack. The slides from this talk are available at http://www.slideshare.net/postwait/scalable-internet-architecture.

July 22, 2009

Day 1 at #oscon 2009

Filed under: Computing — admin @ 5:25 pm

The first day of OSCon 2009 covered a number of tutorials and I decided to attend Google App Engine tutorial for the first half of the day. Google App Engine API follows CGI model of web development, i.e., it uses stdin and stdout files and assumes stateless applications. There is limit of 10MB response size and 30 requests per second, but it does not allow streaming. The tutorial started pretty slow and we spent first hour just installing the SDK and tutorial. The Google App Engine SDK is available from http://code.google.com/appengine/downloads.html. I downloaded Mac image and then dragged the image to my hard drive. I then double clicked the app icon for Google Appe Engine SDK, which installed the SDK under /usr/local/google_appengine. Once the SDK is installed, you have to install Google App Engine tutorials from http://code.google.com/p/app-engine-tutorial/.

After installing SDK and tutorial, I copied all files named tutorial? under the SDK. The rest of session covered those tutorials one by one, though we ran out of time in the end and completed only upto tutorial7. In order to install first tutorial, I went into tutorial1 directory, e.g.

 cd /usr/local/google_appengine/tutorial1
 

Then started local app server as follows:

 python ../dev_appserver.py .
 

When I pointed my browser to the http://localhost:8080, I was able to see “Hello World!”.

Next, I registered myself to http://appspot.com. After registering, I received an SMS message for confirmation and was able to fully register after entering the confirmation number. Next, I created an application-id on Google App Engine. You can only create 10 app-ids and you cannot delete app-ids, so be careful with ids. Also, you can also use your own domain instead appspot.com. For my testing purpose, I chose the id “shahbhat”.

Next, I changed app.yaml inside my local tutorial1 directory that describes how your application is configured. You may also notice index.yaml, which describes list of indices in the database, though Google App Engine can figure out what queries are being used and creates indices automatically. I changed application name in app.yaml to “shahbhat”, e.g.

 application: shahbhat
 

I then pushed my application to the Google App Engine by typing

 python ../appcfg.py update .
 

I was then able to go to http://shahbhat.appspot.com/ and see my application, Voila. You can also see your application usage from http://appengine.google.com/dashboard?app_id=shahbhat (you will have to change app_id parameter in your application).

Unfortunately, a lot of people had problems getting to that state so we wasted another half hour in break where other folks sort out configuration and deployment issues.
Next, I went through another tutorial to turn on authentication by setting:

 login: required
 

in app.yaml file. Next I added caching by adding expires options in the app.yaml. I was also able to use curl to test my applications and see headers to verify caching, e.g.

 curl --include http://localhost:8080
 

Which showed following when caching was not configured:

 Cache-Control: no-cache
 

When I configured the caching to 2d, I was able to see:

 Cache-Control: public, max-age=172800
 

The Google App Engine SDK also includes development that you can view by going to:

 http://localhost:8080/_ah/admin
 

The Google App Engine supports Django based templates, e.g.

 #!/usr/bin/env python
   
   import os
   from google.appengine.ext.webapp import template
   
   def main():
       template_values = {"foo" : [1,2,3]}
       template_file = os.path.join(
                    os.path.dirname(__file__), "index.html")
       body = template.render(
         template_file, template_values)
       print "Status: 200 OK"
       print "Content-type: text/html"
       print
       print body
   
   if __name__ == '__main__':
     main()
 

In addition, Google App Engine supports WSGI standard (PEP 333), e.g.

   import os
   import wsgiref.handlers
   
   from google.appengine.ext import webapp
   from google.appengine.ext.webapp import template
   
   class IndexHandler(webapp.RequestHandler):
   
     def get(self):
       template_values = {"foo" : 1}
   
       template_file = os.path.join(os.path.dirname(__file__), "index.html")
       self.response.out.write(template.render(template_file, template_values))
   
   
   def main():
     application = webapp.WSGIApplication([('/', IndexHandler)], debug=True)
     wsgiref.handlers.CGIHandler().run(application)
   
   
   if __name__ == '__main__':
     main()
 

Other tutorials included authentication APIs such as

 create_login_url(dest_url)
 create_logout_url(dest_url)
 get_current_user()
 is_current_user_admin()
 

The SDK also includes decorator to add authentication automitcally using

 from gogole.appengine.ext.webapp.util import login_required
 ...
     @login_required
     def get(self):
 

Finally, we went over datastore APIs for persistence support, e.g.

   import os
   import wsgiref.handlers
   
   from google.appengine.ext import webapp
   from google.appengine.ext.webapp import template
   from google.appengine.ext import db
   
   class ToDoModel(db.Model):
     description = db.StringProperty()
     created = db.DateTimeProperty(auto_now_add=True)
     foo = db.FloatProperty(default=3.14)
     bar = db.IntegerProperty()
     baz = db.BooleanProperty(default=False)
     N = db.IntegerProperty()
     l = db.ListProperty(str, default=["foo", "bar"])
   
   
   class IndexHandler(webapp.RequestHandler):
   
     def get(self):
       todo = ToDoModel(description = "Hello World", bar=1, baz=True)
       todo.put()
   
   def main():
     application = webapp.WSGIApplication([('/', IndexHandler)], debug=True)
     wsgiref.handlers.CGIHandler().run(application)
   
   if __name__ == '__main__':
     main()
 

You can view the model by going to http://localhost:8080/_ah/admin/datastore. The data store supports a number of types such as string, boolean, blob, list, time, text. However, there are some limitations,
e.g. TextProperty can only store upto 500 bytes and Google App Engine will create index if needed, however it won’t create index on TextProperty. For each row, the datastore assigns a numeric id and UUID based key,
though you can provide your own key. Also, a row cannot exceed 1MB.
Unfortunately, we ran out of time At this time, so I had to go to http://code.googlecom/appengne/docs for further documentation. Overall, I thought it was good introduction to Google App Engine, but I was disappointed that instructor wasted a lot of time with setup that could have been used to cover rest of the tutorials.

For the second half of the day, I attended session on “Building applications with XMPP”. This was interesting session that showed usage of XMPP for a number of usecases such as IM, gaming, real-time social networking, , monitoring, etc. The session started with history of XMPP (Extensible Messaging and Presnce Protocol), its Jabber roots and its use of streaming XML. A number of factors contributed to the popularity of XMPP such as open source, XML, federeated network, low latency, etc. The XMPP is also very extensible and supports audio/video via jingle, geo location, TLS, SASL, etc. XMPP architecture is based on client server, where servers are decentralized and federated. XMPP identifies a user with jabber id that looks like email address and consists of local part, domain and resource, e.g. alise@wonderland.lit/TeaParty, where domain is mandatory, but local-part and resource are optional. There are three types of XMPP message stanzas, i.e., presence, IQ, message. The presence-stanza is asynchronous, but IQ stanza requires response. As opposed to web architecture that is based on short lived connections and stateless architecture, XMPP uses one long lived session and events are received asynchronously.

Next, the tutorial showed how to build a javascript client for jabber using sleekxmpp and Strophe library (alternatively you can use twistedword). The example used Bosh protocol to wrap XMPP protocol with HTTP protocol. Unfortunately, there was a lot of fast typing and I could not follow all that. I am waiting for the presenters to post the slides online so that I can use those examples in my own applications.

June 15, 2009

My plan B for being a programmer

Filed under: Computing — admin @ 11:29 am

I came across an interesting blog on Programmers: Before you turn 40, get a plan B, where the author sites age discrimination in programming career. The author shows how in IT industry, technology shift every 10 years levels the plainfield so there is a little difference between junior and senior programmer. The author also asserts that more experienced programmer will have a lot of irrelevent experience that employer may not be willing to consider when hiring or may not pay higher salary for those skills. I have been programming for over twenty two years and working professionally for over seventeen years and I certainly have seen effects of technology shift. In early 90s, I worked for a physics lab that had plenty of VAX computers using FORTRAN, and they were migrating most of the system to UNIX so people with VMS skills had to adopt to UNIX. I then had to work on mainframe system for another company and used COBOL and CICS. I saw plenty of people who worked on mainframe system for over 10-15 years and knew a little outside mainframe technology. When that company also migrated to NT and UNIX platform, it was quite stressful to many people. Though, there are still companies who are willing to pay top dollars for mainframe experience but opportunities are very few. I myself had to adopt and learn C++ and object-oriented design and found other opportunties that used those skills. I was young and unmarried so switching to another technology was not hard. In mid 90s I switched to Java, CORBA and Web development and there was some learning and adopting involved. In late 90s and early 2000s, I started using Java Enterprise Beans (EJBs) and SOAP based Web services. From 2003-onward, I started using more open source technologies like Spring, Hibernate, Tomcat, REST, etc and I had to abandoned my past CORBA or EJB expertise. This was followed by rise of dynamic languages and I started using Ruby on Rails and built a couple of sites using it. After that I became interested functional programming such as Erlang. These days, I have been spending my spare time in iPhone development.

I completely agree that in programming career, the past experience becomes irrelevant and most companies won’t pay me for the irrelevant experience such as VMS, mainframe, CORBA or EJBs. Also, as I became older and started family, switching jobs just for technology became a lot harder. I believe experienced programmers who have worked with varied technologies bring useful perspective and a bit of pessimism that is often needed. I also believe most experienced programmers have better design skills and pay more attention to writing maintainable or scalable code, but it probably doesn’t matter in may places that just want to get shit done.

Another aspect that differentiates programming career from other professions is lack of predictability. I have found that in our industry, project scope, requirements and estimates are poorly defined and most companies expect programmers to be heros or martyrs who will abandoned their life and dedicate completely to the work. IT people also have to pay for the global culture of 24×7 service and have to be oncall when things break. This becomes a lot harder with the family so many companies prefer young and unmarried folks who are more willing to be heros and those young programmers like the extra attention.

So what is my plan B? It is to continually learn new skills and be a little better than the competition. Many of my past colleagues have moved to the dark site and now are directors or senior managers at other companies. And truth is that in most companies managers carry more respect and authority so no wonder most programmers aspire to become one. I on the other hand, just can’t give up programming and usually spend my spare time on a number of small projects. So I will continue to be a lowly code monkey for the rest of my life.

June 13, 2009

ActiveObject based O/R Mapping library for iPhone development

Filed under: iPhone development — admin @ 6:38 pm

I have been learning iPhone development lately and needed to add some persistence capability to my application. There are varied options available for persistence such as using “User Defaults” for small user specific settings, serialization similar to serialization or pickle features of other languages and builtin support of embeded Sqlite. I found Sqlite more performant, memory efficient and flexible than other options so I chose it. Using Sqlite with iPhone is fairly straight forward and there are tons of examples such Creating Todo list using Sqlite. However, when I looked for some O/R mapping framework for iPhone, I found that iPhone SDK unlike Mac development didn’t have any support and neither I could find any other solution elsewhere. So, I started writing a simple O/R mapping library based on Active Object pattern. This is similar to how Rails and Django implement O/R mapping. Based on convention over configuration, it simply maps object properties to the database table fields. At this time, this is very basic O/R mapping library and does not support relations, validation, database integrity support, etc. Nevertheless, it met my simple needs and I have released it as open source project under OCActiveObjects on GitHub.

The OCActiveObjects library is fairly small and consists of following classes:

ActiveObject

This is the base class that you extend in order to add automatic O/R support. You have to override following Class methods to specify name of the database and table:

     + (NSString *) getTableName;
   

Above method defines name of table where instances of the object will be stored.

     + (NSString *) getDatabaseName;
   

Above method defines name of the database to be used. You will then be able to call following methods to interact with the Sqlite database:

   + (void) openDatabase;
   

Above method must be called once before any other methods, usually at the start of your application.

   + (void) closeDatabase;
   

Above method must be called once before you shutodnw your application.

  
   - (void) save;
 

Above method saves a new object or updates an existing object. Each subclass of ActiveObject is automatically assigned a unique database id with a property
named “objectId”. This is another example of convention where all tables will use a numeric surrogate key to identify each row.
If that property is nil then it assumes this is new object and inserts a new row in the database, otherwise it updates an existing row in the
database. It assumes that name of database fields are same as property names, though you can override that behavior by overriding _getPropertyNamesAndTypes Class method.

   + (ActiveObject *) findByPrimaryKey:(NSNumber *)objId;
 

Above method queries an object in the database matching objectId property, which identifies each object in the database.

   + (NSArray *) findWithCriteria:(NSDictionary *)criteria;
 

Above method returns an array of objects that match criteria. The criteria at this time is simple dictionary, i.e., pair of name and values that are joined by
“AND” clause. There is a immediate need to extend this to support more flexible queries.

   + (NSArray *) findAll;
 

Above method returns all objects, which may not be good for iPhone application due to limited amount of memory. This is another area that needs immediate attention.

   + (int) removeAll;
 

Above method removes all rows in the table so be careful with this.

   + (int) removeWithCriteria:(NSDictionary *)criteria;
 

Above method removes only methods matching criteria. Again criteria consists of name/value pairs.

   + (int) countWithCriteria:(NSDictionary *)criteria;
 

Above method counts the number of rows in the database matching criteria.

   + (int) countAll;
 

Above method returns count of all rows in the table.

Exension Methods in ActiveObject

There are number of extension methods to customize SQLs or behavior of the object such as

 - (void) _insert;
 

Above method inserts an object into the database.

 - (void) _update;
 

Above method updates an existing object into the database.

 + (NSDictionary *) _getPropertyNamesAndTypes;
 

You can override above method to change properties that needs to be persisted.

 + (NSString *) _getCreateSQL;
 

Above method generates an SQL for creating table.

 + (NSMutableString *) _getInsertSQL;
 

Above method generates an SQL for inserting a row in the table.

 + (NSMutableString *) _getUpdateSQL;
 

Above method generates an SQL for updating a row in the table.

 + (NSMutableString *) _getSelectSQL;
 

Above method generates an SQL for selecting fields from the database.

 + (void) _createTable;
 

Above method creates database table.

IntrospectHelper

The OCActiveObjects library uses some Objective C magical runtime support to query for properties and this class encapsulates those methods.

SqliteHelper

This class some helper methods for Sqlite3.

How to use

In order to test it, let’s define a simple Person class that extends ActiveObject, e.g.

 #import <Foundation/Foundation.h>
 #import "ActiveObject.h"
 
 @interface Person : ActiveObject {
         NSString *name;
         short age;
         int rank;
         long votes;
         char sex;
         double income;
         BOOL active;
         NSInteger flags;
         NSNumber *rating;
         NSDate *birthdate;      
 }
 
 
 @property (nonatomic, retain) NSString *name;
 @property (nonatomic, assign) short age;
 @property (nonatomic, assign) int rank;
 @property (nonatomic, assign) long votes;
 @property (nonatomic, assign) char sex;
 @property (nonatomic, assign) double income;
 @property (nonatomic, assign) BOOL active;
 @property (nonatomic, assign) NSInteger flags;
 @property (nonatomic, retain) NSNumber *rating;
 @property (nonatomic, retain) NSDate *birthdate;
 
 - (BOOL)isEqualToPerson:(Person *)aPerson;
 
 @end
 

Implemention of Person.m looks like:

 #import "Person.h"
 
 @implementation Person
 @synthesize name;
 @synthesize age;
 @synthesize rank;
 @synthesize votes;
 @synthesize sex;
 @synthesize income;
 @synthesize active;
 @synthesize flags;
 @synthesize rating;
 @synthesize birthdate;
 
 - (BOOL)isEqual:(id)other {
     if (other == self)
         return YES;
     if (!other || ![other isKindOfClass:[self class]])
         return NO;
     return [self isEqualToPerson:other];
 }
 
 - (BOOL)isEqualToPerson:(Person *)aPerson {
         if (self == aPerson)
         return YES;
     if (![(id)[self name] isEqual:[aPerson name]])
         return NO;
     return YES;
 }
 
 - (NSUInteger)hash {
         NSUInteger hash = 0;
         hash += [[self name] hash];
         return hash;
 }
 
 
 
 - (NSString *)description {
         return [NSString stringWithFormat:@"id %@, name %@", self.objectId, self.name);
 }
 
 
 - (void) dealloc {
         [name release];
         [birthdate release];
         [super dealloc];
 }
 
 + (NSString *) getTableName {
         return @"persons";
 }
 
 + (NSString *) getDatabaseName {
         return @"personsdb";
 }
 
 @end
 

Then you can first open the database, e.g.

 
         [Person openDatabase];
 

Then create a new person object, e.g.

         Person *person = [[[Person alloc] init] autorelease];
         person.birthdate = [[NSDate alloc]init];
         int random = [person.birthdate timeIntervalSince1970];
         person.age =  random % 30;
         person.rank = random % 20;
         person.votes = random % 10;
         person.sex = 'M';
         person.name = [NSString stringWithFormat:@"Joe #%d", random % 1000];
         person.income = random % 3000;
         person.active = YES;
         person.flags = random % 30 + 0.5;
         person.rating = [NSNumber numberWithInt:20.5];  
         return person;
 

You will then be able to save the person object as

         [person save];
 

You can see how many rows are in the database by

         int count = [Person countAll];
 

And then retrieve the object that we saved as

         Person *person2 = (Person *) [Person findByPrimaryKey:person.objectId];
 

When you are done, you can then close the database:

         [Person closeDatabase];
 

One of the frustrating aspect of iPhone development has been lack of good unit testing support. Though, XCode comes with OCUnit, but it is hard to install and use with iPhone. I kept getting weird errors like:

 exited abnormally with code 139
 
 failed tests for architecture 'i386'
 

Though, there are some basic tutorials like Test Driving Your Code with OCUnit or OCUnit: Integrated Unit Testing In Xcode, but they didn’t help. I also tried adding google-toolbox-for-mac but macro errors are extremely frustrating. Besides better testing, OCActiveObjects needs a lot of help to add better support of criteria, paging, relational mapping and validation. I also had hard time figuring out how to create a static library until I found Building static libraries with the iPhone SDK though I still need help in adding framework level support. Hopefuly, other people can contribute to the open source project. You can send me your suggestions and comments as well via email “bhatti AT plexobject DOT com” or tweet me at bhatti_shahzad.

May 26, 2009

Tracing memory leaks with command line Java tools

Filed under: Java — admin @ 3:42 pm

I was recently tracking memory leak in one of our applicatios, however the problem was only occuring in our production environment and the network latency between production subnet and my local subnet was too high to run profiler (I tried). So, I had to use some other tools to look at the snapshot of memory that was in use. I found jmap and jhat that are shipped with JDK (1.6 in our case) pretty handy. When memory usage was high, I dumped the memory using jmap, e.g.

 jmap -F -dump:file=/tmp/dump.out 
 

I then copied the file to my local machine and ran jhat using

 jhat dump.out
 

Though, jhat is fairly slow, but it finally starts the web server on port 7000 and you can then point your browser to

 http://mymachine:7000
 

The jhat can also read data from hprof that you can dump by adding following vm option:

 -agentlib:hprof=heap=sites
 

and then read the file using jhat. In addition to above tool, you can run garbage collection in verbose mode using following vm option:

 -verbose:gc -verbose:class -Xloggc:gc.out -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
 

Finally, you can use jconsole to look at memory graph by adding support of jmx to your application server, .e.g.

 -Dcom.sun.management.jmxremote.port=9003 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote
 

Despite all these options, I find profiler is much better for finding memory leaks, but these tools helped a bit.

« Newer PostsOlder Posts »

Powered by WordPress