Friday, October 29, 2010

Tracing call flows in Python

Python decorators comes handy when you want to intercept a piece of call flow and profiling technique seems just too verbose.
I use this quite often to analyze a python program to understand it better.

Consider the following piece of contrived python code to illustrate this approach of tracing python call flows.

def f():
    f1('some value')


def f1(result): 
    print result
    f2("f1 result")
    

def f2(result): 
    print result
    f3("f2 result")
    fe("f2 result")
    return "f2 result"

def f3(result): 
    print result
    return "f3 result"

def fe(result): 
    print result

f()

Output:
some value
f1 result
f2 result
f2 result

Thursday, October 21, 2010

Before taking a dip into haskell

I have been itching to start learning another language. I have been perusing through rather a voluminous opinions on what language to learn, on the net.
Too many opinions and it could freeze you from doing something. In any case, I have taken the plunge and would start learning haskell, keeping a commentary on the same here.

Before I do that, I really wanted to have Haskell syntax highlighting support in blogger.

I am yet to test it though. so here is a snippet attached that should have been highlighted. Of course, this code is not mine and just serves to confirm that highlighting works.

module Main where

main = putStrLn "Hello, World!"
         

Wednesday, October 20, 2010

Buildbot - Issue with svn poller

SVN poller may miss a check-in based on poll interval.

The current behavior of the poller is

The poller polls the version control system and stores last change (version number).  Subsequent changes are notified as log entries. These log entries are marked with the Time Stamp when the changes are noticed. These log entries are used to create change objects that is then passed to scheduler to trigger builds.Scheduler sees these change objects with the same timestamp and picks the latest change object to trigger the build.

The issue with this model is that if there are multiple changes within a single polling interval, this poller will result in triggering build only for the last one.

Wednesday, October 13, 2010

Python wisdom from stackoverflow #1

I had started participating in "stack overflow" in anticipation to improve my knowledge on topics of interest. What would be better than answering, working on problems posted by users and also look at the answers provided by various folks from the community.

In many posts, I could find some very elegant way of attacking the problem that I had never thought of. It was clear that there are nuggets of wisdom buried in "stack overflow" and mostly it would be difficult to go back and look at them. So I started by collecting weekly wisdoms on topic of my interest which usually is "Python programing". The good thing is that they are going to be unrelated snippets and bad thing is that their isn't any central theme to these posts.

Starting with this post, I will try to pull some neat solutions provided there for reference and later perusal.

#1 : round-up numbers to two decimal points

anFloat = 1234.55555
 print round(anFloat, 2)
# Output : 1234.5599999999999
rounded = "%.2f" % round(anFloat, 2)
print rounded
# Output: '1234.56'

Setting up buildbot - customizing configuration file

The crux of BuildBot involves a master and multiple build slaves that can be distributed across many computers.

Each Builder is configured with a list of BuildSlaves that it will use for its builds. Within a single BuildSlave, each Builder creates its own SlaveBuilder instance.
Once a SlaveBuilder is available, the Builder pulls one or more BuildRequests off its incoming queue.These requests are merged into a single Build instance, which includes the SourceStamp that describes what exact version of the source code should be used for the build. The Build is then randomly assigned to a free SlaveBuilder and the build begins.

All this is configured via a single file called master.cfg which is a dictionary of various keys that is used to configure the buildbot when it starts up.
Open up the sample "master.cfg" that comes with the buildbot distribution, drop it in the master directory that you have created and start hacking it.

I have listed few important configuration that should get you started.
Below is instance of dictionary that is populated in the configuration file
c = BuildmasterConfig = {}

Wednesday, October 6, 2010

Learning Twisted (part 7) : Understanding protocol class implementation

In my last post, I had focused on protocol factory class, various methods it needs to provide and also the code flow within which these methods gets called or invoked.
Here we will look into the structure of protocol class , various methods it needs to provide and context in which they are called.

There are two ways to lookup and learn this:

  • Look at the interface definition: IProtocol(Interface) in interfaces.py
  • Like I did in my previous posting , supply a protocol class with no methods and look at the traceback to understand the code flow

So usual imports for writing a custom protocol:

from twisted.web import proxy
from twisted.internet import reactor
from twisted.internet import protocol
from twisted.python import log
import sys
log.startLogging(sys.stdout)

It is much better to derive from protocol.Protocol to build custom protocol. It does a few things for you.
Any intricate logic should be built using the connect, disconnect, data received event handlers and methods to write data onto connection
makeConnection method sets the transport attribute and also calls connectionMade method . You can use this to start communicating once the connection setup has been established.
dataReceived method is called when there is data to be read off the connection. connectionLost is called when the transport connection is lost for some reason. To write data on the connection, you use the transport method self.transport.write. This results in adding the data to buffer which will be sent across the connection. To make twisted send the data or buffer immediately, you can call self.transport.doWrite