Duties of a Software Architect – build for customer needs, not ours.

In my previous article (UNDERSTANDING THE ROLE OF A SOFTWARE ARCHITECT), I explained the role of a software architect as well how we can categorize software architects. Whilst writing that article what came to my mind is, do we really know what our duties or responsibilities are as an architect. So I decided write from my experience what are some key duties or responsibilities from us as architects.

One of the key challenges, which I have seen many times in projects and dealing with other architects  or even myself for a major part of my career (which is over 21 years  now), where most times we as architects try to come up with technological and architectural solutions but we miss the actual problem we are trying to solve. Sure, we know all the tools, the technologies, the diagrams, and the notations but for what we are using these tools of our trade is a sometime a question.  I believe as an architect the most important thing required by us is not a technical write up or an end state diagram or even a large solutions document, but simply to understand what’s the problem or the challenges our customers have. Given below are some projects from my experience where the teams almost missed the clients need by trying to build sophisticated solutions but by re-evaluating the actual customers need were able to come up with “Just good enough architecture” to help the clients to get what they need.

In a project one of our customers had an issue where their system which had grown organically over the years was at a state where it was not able to scale to handle the traffic volumes any more. The architecture teams were tasked at re-implementing the key areas of the systems that needed to scale. The team came up with a pretty cool target state, but that would be almost a complete rewrite of some major areas of the system and potentially would take a considerable time and effort. However rather than jumping in to building this cool new target state, the team decided to re evaluate what the actual need was, was it to build this super cool system that can scale at large in couple of years or was it to handle the traffic loads incrementally so that business see’s the system improve and scale with the demands. Once we identified the actual need of the customer was to have the system to have the ability to grow with the traffic growth gradually as well as have a buffer and resiliency to a sudden spike, we came up with a road map on how to get to our target state incrementally. Then by  developing some simple optimizations to the data base structure, queries, introducing parallel processing to some key areas that were impacted with traffic growth, and a bit of additional hardware to support the parallel processing,  we were able to handle almost 3x the traffic load. Whilst the business was enjoying the scale, the team worked in introducing caching to reduce the loads on the database, decentralizing the data base so that loads could be handled by slave data stores, and working on breaking the system’s key areas to service orientation with cloud native features and ability to add hardware on the fly (elasticity). This bought the system to be scaled at large and it also gave the business an immediate return on investment as their business grew exponentially.

In another system, which was logistic based, the team had architected a sophisticated solution where it was micro service based, and with rich front end UI’s using the latest front end scripting frameworks and web applications. A major part of the development effort was going for the web and mobile front to make sure that they were very attractive and user friendly. However when we again re-evaluated to look at the actual need of the client, and how the client would use the system operationally, we identified that the operational staff at the client end rarely needed to use a UI, what they really needed was a simple list with data to do their job and to get the list printed when needed. Once this was identified the need for sophisticated UI’s was no longer a need. This reduced a huge complexity from the system and cut down a major portion of development efforts. Another area identified was the system mainly needed trigger based jobs that needed to execute periodically and rather than developing the components as web applications or web services as originally planned, just doing simple CLI’s- the system complexity, cost of infrastructure and development efforts could be reduced drastically.

We had a request from one of the clients that they were having a challenge where they were getting data from various sources and the time taken to load that data to their main system, which needed to happen regularly, was extremely high. Their recommendation was to see if a data science approach can be taken to use machine learning to reduce the overall time taken. So the teams were engaged and architectures were planned. However a closer look at trying to understand what the actual challenge the customer had, we identified that the overall process from end to end had multiple manual workloads  that the areas that were looked at to be automated through machine learning, would not help the client that much. However after visualizing the current work flow, identifying what are the manual bottlenecks and how they can be automated through simple automation processes, were identified that we can ensure the overall time taken can be cut down drastically and all this can be done whilst the data science aspect (which obviously takes time for training and implementation) is getting implemented. Hence the customer starts seeing benefit almost immediately.

In another project for an online transaction processing product where for the team to deliver a simple product feature to production after development completion, it was taking at least two months. They were looking at implementing sophisticated tools and revamping / rewriting the system to be cloud native etc… This was a massive project which potentially could have taken years. However when we really drill down to the actual root cause of the problem, we were able to identify that the challenge mainly was in two main areas of the system where any change done in any area of the system impacts these two key areas. So rather than trying to revamp, rewrite the complete system from scratch and bringing in new sophisticated tools up front, we were able to come up with an end state architecture, where the system would become a micro serviced, cloud native, with proper devops pipelines, and that could release features to production within couple of minutes. However more important than that, we built a simple road map where within a short period of time the product teams had the ability to safely release features within two weeks after development by bringing in QA automation to key areas and devops tooling with team collaborations to the overall project. This gave a huge boost to the product teams to release features rapidly. Later we started working towards the end state where the releases can be done within couple of minutes.

These are some example out of many which I has to get involved in, which shows that rather than trying to find technical solutions, we need to be able to understand what is the problem that our customers have, why are they looking at us to come up with a solution, and then only look at how best we can help the customer with solving their problem. Let’s face it, if the customers do not have a problem, they certainly do not need to spend on an architect. I believe “Just good enough architecture” is an approach we would need to take rather than “grand scale architecture” when coming up with solutions.

Concurrency vs. Parallelism

In a project that I was working on, we were discussing using “map-reduce” to process our application data faster and when we were discussing about leveraging current multi processors to process faster , I found there was some confusion about concurrency vs parallelism within the team. So I thought maybe I can explain the difference in a layman’s term so that all can grasp the idea.

Let us first look at what is concurrency

According to Wikipedia

In computer scienceconcurrency is the ability of different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome. This allows for parallel execution of the concurrent units, which can significantly improve overall speed of the execution in multi-processor and multi-core systems. In more technical terms, concurrency refers to the decomposability property of a program, algorithm, or problem into order-independent or partially-ordered components or units.[1]

Quite a mouthful right?

So what about parallelism or parallel computing

Parallel computing is a type of computation in which many calculations or the execution of processes are carried out simultaneously.[1] Large problems can often be divided into smaller ones, which can then be solved at the same time. There are several different forms of parallel computing: bit-levelinstruction-leveldata, and task parallelism. Parallelism has long been employed in high-performance computing, but has gained broader interest due to the physical constraints preventing frequency scaling.[2] As power consumption (and consequently heat generation) by computers has become a concern in recent years,[3] parallel computing has become the dominant paradigm in computer architecture, mainly in the form of multi-core processors.[4]

Again quite a mouthful … So what does this really mean in apples and oranges term?

Single Task – let’s say you go to the grocery store to buy an apple, and an apple only. This means you have a single task to do. 

Concurrency – let’s say you go to the same store, but now you want to buy apples, sugar, cream, milk , and flour to make an apple pie. So now you going to do multiple tasks, but you will select each item one by one at a given time.

Parallelism – Let’s say now, in order to make the same apple pie, you go to the store with couple of your friends and you give each one a set of items to buy. Now the items are being bought at the same time so your completion of the buying becomes much faster.

The following picture show how modern CPU would execute a concurrent or a parallel execution

Modern languages support to write applications using concurrency and support them being executed in parallel with multi core systems.

I have created a simple go application which creates go routines with and without channels that shows how concurrent tasks will run in multi core systems using parallelism. You can get the code @

https://github.com/IndikaMaligaspe/go-concurrnecy

Before we dive into code , we need to get an understanding of the difference between threads and Goroutine

ThreadsGoroutine
Have own execution stackHave own execution stac
Fixed stack space (around 1 MB)Variable stack space (starts @2 KB)
Managed by OSManaged by Go runtime
  
Threads vs Goroutines

Let’s look at some code snippets

package main

import (
	"fmt"

	"github.com/indikamaligaspe/go-concurrnecy/src/movies/channels"
	"github.com/indikamaligaspe/go-concurrnecy/src/movies/waitgroups"
)

func main() {
	fmt.Println("Starting With WAITGROUPS")
	waitgroups.StartWaitGroup()
	fmt.Println("Starting With CHANNELS")
	channels.StartChannels()
}

Using Channels

func StartChannels() {
	wg := &
sync.WaitGroup{}
	m := &sync.RWMutex{}
	cacheCh := make(chan movies.Movie)
	dbCh := make(chan movies.Movie)

	for i := 1; i < 10; i++ {
		id := rnd.Intn(10) + 1
		wg.Add(2)
		go func(id int, wg *sync.WaitGroup, m *sync.RWMutex, ch chan<- movies.Movie) {
			if movie, ok := queryCahce(id, m); ok {
				ch <- movie
			}
			wg.Done()
		}(id, wg, m, cacheCh)
		go func(id int, wg *sync.WaitGroup, m *sync.RWMutex, ch chan<- movies.Movie) {
			if movie, ok := queryDatabase(id, m); ok {
				m.Lock()
				chcache[id] = movie
				m.Unlock()
				ch <- movie
			}
			wg.Done()
		}(id, wg, m, dbCh)

		go func(cacheCh, dbCh <-chan movies.Movie) {
			select {
			case movie := <-cacheCh:
				fmt.Println("From Cache ->")
				fmt.Println(movie)
				<-dbCh
			case movie := <-dbCh:
				fmt.Println("From Database ->")
				fmt.Println(movie)
			}
		}(cacheCh, dbCh)
		time.Sleep(150 * time.Millisecond)
	}
	wg.Wait()
}

Without channels

func StartWaitGroup() {
	wg := &sync.WaitGroup{}
	m := &sync.RWMutex{}
	for i := 0; i < 10; i++ {
		fmt.Printf("Run %v : ", (i + 1))
		id := rnd.Intn(10) + 1
		wg.Add(2)
		go func(id int, wg *sync.WaitGroup, m *sync.RWMutex) {
			movie, ok := queryCahce(id, m)
			if ok {
				fmt.Println("From Cache")
				fmt.Println(movie)
			}
			wg.Done()
		}(id, wg, m)
		go func(id int, wg *sync.WaitGroup, m *sync.RWMutex) {
			movie, ok := queryDatabase(id, m)
			if ok {
				fmt.Println("From Database")
				fmt.Println(movie)
			}
			wg.Done()
		}(id, wg, m)
		time.Sleep(150 * time.Millisecond)
	}
	wg.Wait()
}

When executed we can see that the application runs utilizing all the cores in my notebook

Well , I hope this gave an idea about the difference and how Go handled parallelism with goroutines

Understanding the role of a Software Architect

According to Wikipedia the role of a Software Architect is defined as

Architects make high-level design choices based on their programming experience. An architect has thought through all the aspects of a software, just like an architect that builds a house. A construction architect knows where the ducts will be, where the electric connections will be and where the wall outlets will be. A design that a common person sees is just the walls and windows but a detailed design that is abstracted from the outsider are also present with the architect. In addition, the architect may sometimes propose technical standards, including coding standards, tools, or platforms.”

However according to my experience and according to actual software architects out there who have shared their experience; this is just a small portion of what goes into being a Software Architect.  A better analogy for me would be

An architect is a person who works with a diverse set of people both technical and non technical to guide a project / product or an organization to it’s business success using technology , engineering, collaboration, leadership, project management, standards,  and governance.”

According to above an architect plays a role of technical visionary, leader as well as people and process champion to ensure a project is successfully completed.

Well, what does these actually mean?

However when we look at the content that is out there, we mostly see the technical aspects as designing, modeling, deep technology knowledge , engineering principles etc… but if we look at above list, we are looking at more non technical then technical aspects.

So what is an architect expected to do?

To understand this, let’s understand the typical types of software architects that we can find in the industry. Though there are many, I can see three clear distinct types or architects,

  • Enterprise Architect – A strategic architect who looks at the overall organization’s business processes, people, information flow, and business & technical strategies. The main goal is to align an organization’s IT with business goals. An enterprise architect looks at the long term initiatives.
  • Solutions Architect – A tactical architect who looks at cross domain and cross functional system interactions such as frameworks, infrastructure, road maps, guidance, cross cutting process & governance, reuse and strategic solutions. The main goal is to look at an organizations product or services suite and help to implement strategic solutions across the board.
  • Application Architect – An operational architect who is a subject matter expert and will focus on single application stack. Integration Architect, Cloud Architect, Data Architect, Mobile Architect etc… An Application Architect would focus on components, maintainability, modules, classes, libraries, languages etc…

Most of the content available mainly details application architects, which is about the operational implementation and remaining highly technical. But the different between a senior engineer and an architect are those non technical skills, which I would coin as the essential skills needed for an architect to be successful.  

So to be an effective software architect, we need to understand the role of an architect and the key role non technical essential skills play in the role.

So to answer the question “What is the role of a software architect” ? the best answer that I can put out is , a person who guides a project or product from inception to closure with a diverse set of teams by using leadership, management and broad set of technical skills.

In my next article I will dive deeper into understanding what are the technical and non-technical duties of a software architect.

Building an IT Strategy

Developing an IT strategy may look as a daunting task for many IT leaders and even a defined IT strategy may not yield the right outcome. Many reason could contribute to a failed IT strategy but some of the main reasons being

  • IT leaders being pushed for IT strategies where the business itself may not be having a right strategy with clear vision, mission, goals, and objectives
  • A strategy being based on several tactics that keeps changing frequently
  • A strategy based on some external consultant with a 200 page document that nobody really follows.

 IT strategy should be based on answering one key question,

how will IT helps business success

So it is imperative that what defines as business success is identified up front. There are many tools in identifying business success, but one simple but yet powerful tool could be using Value Discipline model by Michael Treacy and Fred Wiesemara. The Value Disciple allows an organization to understand what is the one thing that will create a competitive advantage over others and what is it that an organization wants to be famous for. Another great feature about the Value Discipline is that in can be applied at any stage of organizations growth

Strategy

Strategy should define a vision of how the company will succeed, what are the goals to succeed. Basically how will the company win, by focusing on what?

Strategy is long term, will not, and should not change frequently

Strategic plan

Are the short term tactics that will allow us to get to the long term strategy? These are short lived, 3 months – 1 year. Regularly evaluated and changed to meet the current need and environment change.

IT strategy can be broken into three key areas DEMAND , CONTROL , SUPPLY.

Demand encapsulate the business demand to ensure business success and the IT contribution to that success

Control defines how will the organization ensure the strategic design is enforced correctly

Supply is how will IT evolve it’s capabilities to meet the demand

Demand (How will we win)Control (How will we ensure strategic design)Supply (How will IT evolve it’s capabilities)
Business Context (Value Discipline)IT PrinciplesIT Service
Business SuccessIT GovernanceArchitecture
Business CapabilitiesFinance ManagementPeople
IT contributionMetricsSourcing

The IT strategy document should be an 10 – 15 page document that encapsulate what is needed for the organization from the above table. Not all is needed , but we should pick what we need for our business.

Some highlights from above are

Demand

Business Context (Value Discipline) – What discipline should be our core discipline that we will never compromise for any reason. This is what will make us win the game of business

What will be the measurement of business success?

Business Capabilities – What are our core capabilities we need to have in order ensure that we meet business success (Cycle Time,  M&A, Efficiency , Process Improvement, Agility and Change, Transparency, Innovation , etc….)

IT contribution – How will IT contribute for business to win?

Control

Principles – 8 or 10 core principles that will govern all IT decisions which should be catered towards how IT will help business win. Two key questions to ask each time we make a decision (strategy moment)

  1. How do we succeed as a business
  2. How will IT help

Governance – What will govern every IT decision in every area?

Metrics – what are the KPI’ s that IT leaders need to monitor in order to ensure that the IT strategy is being followed and IT is delivering it’s promise to support business sucess

Supply

IT Services – what are the IT services that needs to be improved, altered or added to ensure that IT supports the business.

Architecture – How should the application , infrastructure , product architecture improve or will enhance the capabilities of the business.

People – What and where are the skill gaps that needs to fulfilled in order for IT to supply business success

A well laid out IT strategy and strategic plan will ensure that IT delivers on it’s promise to ensure business success.

I hope that above gave some insight to IT leaders on building an IT strategy that will work and has worked for me.

Software Engineering – Merge Sort

I recently had to a do an application that required me to sort a data set fast and efficiently. I opted to do a merge sort. Merge sort is a fast sorting algorithm which is always true with an average or worst case performance of O(n log n). What I really love about a merge sort is that it is a stable sorting algorithm.

After doing the sorting I realized that most people are unaware of how actually merge sort worked. Hence I decided to do this post so anyone can actually understand how merge sort worked behind the scene and give example codes using java and C of a merge sort on an integer array.

Merge Sort is a divide an concur sorting algorithm. The Array is divided repeatedly until we have only 2 arrays of only one element each. Then the elements in the two arrays are sorted and we work our way back up the hierarchy merging the arrays till we get a sorted array. You can get a very good description on the wiki site about merge sort.

If we take an array of 6 integers, say 5,12,3,3,9,18, we follow the process below

  1. Break the array in to two arrays -> 5,12,3 and 3,9,18
  2. Take each array and break it again -> 5 and 12,3
  3. Break the array till you have only 1 element each -> 12 and 3
  4. Now start sorting and merging – >3 and 12
    1. one layer up 3,12 and 1 -> 1,3,12
    2. one layer up 1,3,12 and 3,9,18 – > 1,3,3,9,12,18
  5. Now you have a sorted array

Let me explain this now with a Java code.
Note that I did not use any specific java syntax such as array.length to keep the code as generic as possible. The code methods are self explanatory.

class merge_sort
{

    public int[] split_merge(int [] mainArr , int start, int end)
    {
	if ((end - start) < 2) {
	    return mainArr;
	}

	int middle = (start + end) / 2;

	int[] A = new int[middle - start];
	int[] B = new int[end - middle];

	A = copy_array(mainArr, start, middle,A);
	B = copy_array(mainArr, middle, end ,B);

        //Recursively Call split_merge till we have an 
        //array with 1 element
	A = split_merge(A,0,middle);
	B = split_merge(B,0 ,(end-middle));
        
        //merge our way back one layer up always.
	mainArr = merge(mainArr, A, B, start, middle, end);
	return mainArr;
    }

    public int[] merge(int[] array, int[] A, int[] B, int start, int middle, int end)
    {
	int i = 0 , j = 0, k = 0;
        //Loop till end of main array and copy the sorted elements.
	for (k=0;k<(end-start);k++){
	    if ( (i < middle)  && (A[i] < B[j]) ){
		    array[k] = A[i];
		    i=i+1;
	    }else{
		    array[k] = B[j];
		    j=j+1;
	   }
	}

	return array;
	
    }

    public int[] copy_array(int[] A, int start, int end, int[] B)
    {
	int i =start, j =0;
        while (i < end) {
	    B[j] = A[i];
	    j+=1;
	    i+=1;
	}
	return B;
    }
    public  static void  main(String args[])
    {
	int mainArr[] = {2,3,5,1,6,4,10};
	int length = 7;

	for(int i =0 ; i <mainarr.length; i++){
="" system.out.format("unsorted="" array[%d]="%d" \n="" ",="" i="" ,="" mainarr[i]);="" }="" mainarr="new" merge_sort().split_merge(mainarr,0,length);="" for(int="" ;="" <mainarr.length;="" system.out.format("sorted="" <="" pre="">

Now let’s look at the same as implemented using C language. Again I have tried to make it language agnostic as possible.

#include <stdio.h>
#include <string.h>

int *merge_sort(int A[],int length);
int *copy_array(int *A,int start , int end , int *B);
int *split_merge(int *A, int start, int end);
int *merge(int *arr, int *A, int *B, int start,int middle, int end);


int* copy_array(int *A, int start, int end,int *B)
{
 int i , j;
  j = 0;
  for ( i = start; i< end; i++){
    B[j] = A[i];
    j = j +1;
  }
  return B;
}

int *merge(int *arr , int *A, int *B, int start, int middle, int end)
{
  int i = 0;
  int j = 0;
  int k = 0;

  for(k = 0; k < end ; k++){
    if((i < middle) && (A[i] < B[j])){
      arr[k] = A[i];
      i = i +1 ;
    }else {
      arr[k] = B[j];
      j = j +1;
    }  
  }
  return arr;
}

int *split_merge(int *arr, int start, int end)
{
  if((end-start) < 2)
    return arr;
  int k;
  
  int middle = (end -start) /2;
  int size_a = middle - start;
  int size_b = end - middle;
  
  int A[size_a];
  int B[size_b];
  int *_aptr = copy_array(arr , 0 , middle , A);
  int *_bptr = copy_array(arr, middle , end, B);

  _aptr = split_merge(_aptr,0,middle);
  _bptr = split_merge(_bptr,0, (end - middle));

  arr = merge(arr , _aptr , _bptr , start , middle, end);
  return arr;
  
}

int *merge_sort(int A[], int length)
{
  int start  = 0;
  int end = length; //I put this to match the Java Code
  A = split_merge(A,start,end);
  return A;
}


int main(int argc, char argv[])
{
  int A[] = {100,50,200,1000,18,5300};
  int length = 6;
  int *B;

  for ( i = 0;i < length ; i++){
    printf("Unsorted Array[%d] : %d \n",i , A[i]);
  }

  int *aptr = merge_sort(A , length );
  int i;
 
  for ( i = 0;i < length ; i++){
    printf("Sorted Array[%d] : %d \n",i , aptr[i]);
  }
  
  return 0;
}

So I hope that this will help you next time when you have to sort a data set and you will choose merge as an option to your application.

Connecting RabbitMQ with PIKA for 10000 EPS

Hey all , I know it has been a long time since I posted any articles on my site due to and extremely busy schedule. But I wanted to start again giving out my experience so that someone can benefit from that.

In the last week or so I have been tasked to create an event driven architecture to handle 10000+ EPS (events per second). The platform I chose  was to use message queue that will act as the main bus for all messages to be streams. For this purpose I have used RabbitMQ and pika (as the system is written in Python). One of the key challenges was to create an asynchronous publisher which had to be thread safe for 10000+ EPS. Searching over the net I could not find any good resource for this but found several supporting articles that helped me to build this out.

Following is a simple python pika publisher to publish messages asynchronously and in a thread safe environment.

import logging
import pika
import json
import time
from logging.handlers import RotatingFileHandler
from threading import Thread



class Publisher(Thread):

    def __init__(self, RABBITMQ_SETTINGS,LOG4PY_SETTINGS):
        Thread.__init__(self)       
        self.logger = logging.getLogger("Publisher.py")
        self.connection = None
        self.channel = None
        self._deliveries = []
        self._acked = 0
        self._nacked = 0
        self._message_number = 0
        self._stopping = False
        self.queue = 'alienvault_replicate'
        self.routing_key = 'alienvault_replicate'
        self.exchange = 'alienvault_replicate'
        self.message = None
        self.ready = False
        self._closing = False
        log4py_file  = LOG4PY_SETTINGS['log4py_file']
        log4py_log_level = LOG4PY_SETTINGS['log4py_log_level']
        self.PUBLISH_INTERVAL=0.1
        self.RABBITMQ_SETTINGS =RABBITMQ_SETTINGS

        if log4py_log_level == 'DEBUG':
           self.log_level = logging.DEBUG
        elif log4py_log_level == 'INFO': 
           self.log_level = logging.INFO
        elif log4py_log_level == 'WARN':
           self.log_level = logging.WARN
        elif log4py_log_level == 'ERROR': 
           self.log_level = logging.ERROR

        self.logger.setLevel(self.log_level)
        # create console handler and set level to debug
        rfh = RotatingFileHandler(filename=log4py_file, mode='a', maxBytes=100*1024*1024,backupCount=2)
        rfh.setLevel(self.log_level)
        # create formatter
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
        # add formatter to ch
        rfh.setFormatter(formatter)
    
        # add ch to logger
        self.logger.addHandler(rfh)
        
        amqp_url = 'amqp://'+self.RABBITMQ_SETTINGS['user']+':'+self.RABBITMQ_SETTINGS['passwd']+'@'+self.RABBITMQ_SETTINGS['host']+':'+str('5672')+'/%2F'
        self._url = amqp_url
        
    def is_ready(self):
        return self.ready
        
    def set_message(self,message):
        self.message = message
        self.logger.info('Message set to publish to {0}'.format(self.message))
    
    
    def connect(self):
        self.logger.info('Connecting to %s', self._url)
        return pika.SelectConnection(pika.URLParameters(self._url),
                                     self.onconnection_open)
        
    def close_connection(self):
        self.logger.info('Closing connection')
        self._closing = True
        self.connection.close()

    def add_onconnection_close_callback(self):
        self.logger.info('Adding connection close callback')
        self.connection.add_on_close_callback(self.onconnection_closed)

    def onconnection_closed(self, connection, reply_code, reply_text):

        self.channel = None
        if self._closing:
            self.connection.ioloop.stop()
        else:
            self.logger.warning('Connection closed, reopening in 5 seconds: (%s) %s',
                           reply_code, reply_text)
            self.ready = False                   
            self.reconnect()


    def onconnection_open(self, unusedconnection):
        self.logger.info('Connection opened')
        self.add_onconnection_close_callback()
        self.openchannel()

    def reconnect(self):
        self.connection.ioloop.stop()
        self.connection = self.connect()
        self.connection.ioloop.start()

    def add_onchannel_close_callback(self):
        self.logger.info('Adding channel close callback')
        self.channel.add_on_close_callback(self.onchannel_closed)

    def onchannel_closed(self, channel, reply_code, reply_text):
        self.logger.warning('Channel was closed: (%s) %s', reply_code, reply_text)
        if not self._closing:
            self.connection.close()

    def onchannel_open(self, channel):
        self.logger.info('Channel opened')
        self.channel = channel
        self.add_onchannel_close_callback()
        self.setup_exchange(self.exchange)

    def setup_exchange(self, exchange_name):
        self.logger.info('Declaring exchange %s', exchange_name)
        self.channel.exchange_declare(self.on_exchange_declareok,
                                       exchange_name)

    def on_exchange_declareok(self, unused_frame):
        self.logger.info('Exchange declared')
        self.setup_queue(self.queue)

    def setup_queue(self, queue_name):
        self.logger.info('Declaring queue %s', queue_name)
        self.channel.queue_declare(self.on_queue_declareok, queue_name,durable=True)

    def on_queue_declareok(self, method_frame):
        self.logger.info('Binding %s to %s with %s',
                    self.exchange, self.queue, self.routing_key)
        self.channel.queue_bind(self.on_bindok, self.queue,
                                 self.exchange, self.routing_key)


    def publish_message(self):
        if self._stopping:
            return
        if self.message == None:
            return

        try:
            properties = pika.BasicProperties(delivery_mode = 1)
    
            self.channel.basic_publish(self.exchange, self.routing_key,
                                        self.message,
                                        properties)
            self.logger.info('Published message # %i', self._message_number)
        except Exception as err:
            import trace
            self.logger.info("Error in sending message ... {0}".format(err.message))
            self.ready = False

    def start_publishing(self):
        self.logger.info('Issuing consumer related RPC commands')
        self.ready = True
        self.publish_message()

    def on_bindok(self, unused_frame):
        self.logger.info('Queue bound')
        self.start_publishing()

    def closechannel(self):
        self.logger.info('Closing the channel')
        if self.channel:
            self.channel.close()

    def openchannel(self):
        self.logger.info('Creating a new channel')
        self.connection.channel(on_open_callback=self.onchannel_open)

    def run(self):
        self.connection = self.connect()
        self.connection.ioloop.start()


    def stop(self):
        self.logger.info('Stopping')
        self._stopping = True
        self.closechannel()
        self.close_connection()
        self.connection.ioloop.start()
        self.logger.info('Stopped')

if __name__ == '__main__':
    try:
        RABBITMQ_SETTINGS = {"user":"user","passwd":"pw","host":"xxx.xxx.xxx.xxx"}
        LOG4PY_SETTINGS = {"log4py_file":"./log4py.log","log4py_log_level":"INFO"}
        
        publisher = Publisher(RABBITMQ_SETTINGS,LOG4PY_SETTINGS)
        publisher.start()
        for i in range(1 , 100000):
            message = '{"message":"Hello Fellasss...."'+str(i)+'}'
            publisher.set_message(message)
            while not publisher.is_ready():
                time.sleep(.001)
            publisher.publish_message()
        publisher.stop()    
    except KeyboardInterrupt:
        publisher.stop()

Clean Code or Code Clean – Why I love refactoring

I am pretty sure that most of the times, us developers have heard the following line from some senior personal “Why don’t you code it clean the first time”. Well in fact I have heard this many times as a developer and have told this to my juniors many times as well.

But when you dig deep, you begin to ask your self, Is there anything called coding clean these days. With the business demands, systems evolving, pressure to fix or develop faster etc… we as developers are tide down to quickly hash code and release! in fact all these new Agile methodologies and time boxed sprints are not making it any more easier.

So how do we make sure that we keep our code maintainable, clean and effective… We use a simple term called “Code Refactor”.

So what really is refactoring…

“Code refactoring is a “disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior”,[1] undertaken in order to improve some of the nonfunctional attributes of the software. Advantages include improved code readability and reduced complexity to improve the maintainability of the source code, as well as a more expressive internal architecture or object model to improve extensibility.”  – Wikipedia

By continuously improving the design of code, we make it easier and easier to work with. This is in sharp contrast to what typically happens: little refactoring and a great deal of attention paid to expediently adding new features. If you get into the hygienic habit of refactoring continuously, you’ll find that it is easier to extend and maintain code.” —Joshua Kerievsky, Refactoring to Patterns
 
According to studies done the highest cost in a software project is in maintaining the code rather then writing the initial code. So refactoring is a critical art that needs to be practice. But most people do not treat code refactor as a software development routine to ardently follow. Many developers I know believe that refactoing is this BIG project that needs to be done as a separate project and needs a separate time / sprint cycle etc… I always believe in the idea that if you want to be agile or be in the agile space you need to refactor. 


With this in mind following are some key points that convinced me why code refactoring is a must in software development

  • I cannot be Agile if my code is not clean. Because I can not respond to change fast if my code sucks.
  • No one can write good code in one sitting, there should be several iterations. Each iteration cleans the code.
  • Code is there to be read and understood. We read code more then we write.When pushed with tight deadlines it is not possible to write clean code. So it’s better to write crappy code that works, then refactor to make it a great code. 
  • Managable and clean code has to have four characteristics and refactoring paves a way for that. The characteristics are
    • Simple
    • Clear
    • Bravity (Keep your code small)
    • Human readable then machine readable.
  • Software change over time. Hence designs and architectures change. The code also needs to support these changes. Hence the code will always get changed.
  • Your team depends on your code now and years in the future as well. So make it easy for the team by cleaning your code overtime.
  • The easiest code to QA or manage is code that is not there. Cleaning code, reduced unwanted code. This leads to less QA and less maintenance.
  • Finally, The code we write reflects us, leaving a cleaned code reflects our quality and who we are.

I hope the above shows why code needs to be cleaned continuously. The following are some tips when doing code refactoring that I normally try to follow.

  • Refactor your code as soon as you write your code. Don’t wait till end of a sprint, six months down the line to refactor.
  • Before doing any refactoring, first find a way to test what you refactor. Either find automated tests or build your own test for the area that you are refactoring. This could be unit, integration or functional tests. Never get into refactoring if you cannot test.
  • Don’t try to refactor the code by making it clever, but by making it simple
  • Refactor the code to be cohesive. This means that your code blocks should be doing independent work. Remove all dependencies as much as possible.
  • Make your methods to one level of abstraction. This means code your methods to have one functionality, and drill down to inner methods for sub functionality.
  • A method should always be fully visible within your screen. This means without scrolling up / down you should be able to read the full method. If a method cannot be read in one glance, then refactor the method again.
  • When refactoring, always try to reduce code and not add code. Code that is not there create lesser bugs. For example remove duplicates, remove redundant code, take out unnecessary comments or logging etc…
  • Checkin your code very frequently. 
  • Get help from a peer, to review your refactor.


I hope the above tips help you to improve your code by refactoring and continuous cleaning. Always remember that you are the creator of your code, hence make sure that you groom your code contentiously. Your customers or management may not see your code and will not care about code quality, but you will need to care about your code.

What is the cost of going Agile

Recently I was interested in a user group question about what is the actual cost of implementing Agile within an organization. I believe that using the term “cost” when it comes to Agile implementations may not be the right term and I would rather prefer “ROI”. However following is my take on what is the cost in implementing Agile within an organization.

From what I seen in Agile implementations I have been involved in and coached, the cost is mainly going to be in the buy in from all to adopt to Agile. What I have seen is moving an organization to be Agile is a cultural change rather then just doing Agile (which is some teams doing something like scrum or XP or kanban etc…).

The idea is as a whole, the organization becomes agile by having constant improving itself from the way they interact with clients to the development and everything in between. On paper everyone will say ‘YES’ let’s go agile, but when things get tough, people will always try to find some way of breaking the process. So their has to be commitment from all areas. This can not be commanded, it has to be accepted and adopted.

So simply we need to ask our self and our management, are we willing to really get in to being agile, then the cost comes down to ROI. That is the whole investment including

  • Learning curve (investment of teaching employees about Agile and agile framework of choice)
  • Slowdown in progress initially (impacts business and clients)
  • Getting customer buy in
  • Investment on tools (getting the right tools for the right tasks)
  • Investment on coaching (getting a coach if needed)
  • Monitoring and Improving every step of the way (there is an investment for making sure Agile sticks when the going get’s tough as well)

Note that Agile does not bring ROI immediately. It will be a slow progressing journey, which at the end will bring very high returns.

5 Attributes of a Great Software Engineer

Software Engineering is the process of applying engineering to design, development and maintenance of software. Most engineers who come from engineering schools are taught about engineering practices, programming languages , coding standards etc… but once you enter the world of professional software engineering and the dust settles down , you find the rules of the game are not exactly what you expected.

In the last 15 year I have dealt with software engineers who are rock solid , enjoying every minute of their work and others who are dreading to come to work everyday. After discussing and researching on both sides of the fence, what I have seen is that it is not the difference in skill set , the talents or IQ that makes the difference between the two , but the attitudes and the personality attributes that count the most. Listed below are five of the key attributes I’ve found that makes the biggest differences between the two groups

Passion

All great software engineers have a passion for giving solutions to variety of complex problems. It is in their nature to give solutions and they do not back down from challenges. Let’s face it, software engineers have either just finished solving a problem or are in a problem or heading towards a problem. So you need to have passion to find solutions to these problems. The solutions could be a software design, an analytical / logic design or a code change. But whatever way you look at is you need to have a passion for going into problems and giving solutions. If your cup of tea is not giving solutions to complex problems, then software engineering may not be the right hat for you to wear.

Desire to learn

Any software engineer I have come across who is worth his salt desires to learn. They desire to grow and expand their skill set as well as understand what their giving their software solution for. In order to do this a software engineer needs to have burning desire to learn.

If as engineers we are not sure of what solution we are developing we need to learn what we are developing our solution for. We need to learn what the requirements are. Gone are the days when an analyst would list down the specifications step-by-step with the intent of getting it developed in that order. Agile Development is an excellent example for this. It is expected for a software engineer to learn from clients and develop a solution that caters to clients needs.

The technologies in the industry are changing ever so rapidly that it is extremely hard to keep up, but as engineers it is expected. So desiring to learn and spending at least 1 hour per day on building themselves is key to any software engineer. They need to make sure they are in par with the industry needs and the latest technology , engineering trends.

How do you learn, well the best ways are

    • Ask Questions
    • Join a User group
    • Read
    • Try things out

Discipline

They say there are two pains in life, the pain of discipline which weighs ounces whilst the pain of regret which weighs tons. A true software engineer is totally focused and disciplined. Disciple is the difference between a cowboy and a seasoned engineer. I believe there are two areas that a software engineer really needs to be disciplined in

    • To end what you start – You need to make sure that you complete things that you start, otherwise you will have foundations laid down allover but no building to show for that. With the technology changes and new challenges that are thrown to engineers by the industry, it is easy to get lost in trying out new things always. But it is extremely important to finish what you start. As a software engineer you need to have a reputation as a person who the industry can depend on to deliver and that does not come if you are not disciplined.
    • To look before you leap – You need to think and see what are the consequence of doing something before doing. My metaphor for this is “Read the README before running the Software”. Most software engineers jump into something without doing the due diligence and this is asking for trouble down the line in any project. You need to spend that upfront time in planning (maybe not 100%) at least to a level where you know what needs to be done, where the potential road blocks can be and what can be done to overcome them. Sometimes you may not foresee all the challenges, but that is not in your control. But you need to be disciplined to spend that time upfront in planning before implementing.
    • Learn from your mistakes – You need to be discipline enough to document what went wrong with each project and see how you can improve on this. Most of the time I have seen engineers make the same mistakes over and over again. This leads to loss of credibility and potentially damaging projects. So as a rule make notes of what went wrong and improve with every step you take. This requires a discipline to document , analyze and above all commit to improving yourself.

Flexibility

I have herd the term “I am a Java engineer” , “I am C# engineer” , “I am Python engineer” or “I am Database engineer” , “I am a Business component engineer” etc… so many times by Software Engineers. For me this is not what a software engineer should stand for. A software engineer should be flexible enough to adopt change. They should be able to learn and see what the current situation requires and becomes the very agent that provides the solution. Now you may choose to master an area of expertise, but you should not get locked to any. The more flexible you are in changing yourself to the current needs of the industry the better solutions you can give and more you will be valuable to the industry.

Apart from this a software engineer should always try things out and see how they will fit into to the solutions that he needs to give in the future. Do not be afraid to change or try new things due to future failure. Always be flexible and adaptable.

A good software engineer is not bound by a technology, a framework or any area of development. They provide solutions to the industry by looking at what is best suited and how best to get that solution implemented.

Enjoy

The last but the most important attribute I have seen by solid and successful engineers is that they enjoy being a software engineer. They love and thrive on the solutions that they give and what they are called upon to do.

They enjoy what they produce and how they go about producing great software solutions. I believe they actually view the work they do as an art rather then just a profession and this leads them to enjoy the process of creating their masterpiece.

So enjoy every moment how challenging it may seems at the time. Remember somewhere in the not to distant future you will look back in time at a challenge or some problem you went through and laugh at what you faced and how you overcame , so why wait… why not just enjoy the challenges and what you do now it self.

So there you have it, five attributes that I have seen over and over again from rock solid engineers. I know if you add these attributes to you , maybe you can also become one rock solid engineer.

Modernizing Legacy Systems to Cloud

Most companies who have been in for business for more than 5 years do have legacy applications. Once the company realizes the potential benefits of modernizing legacy applications for cloud, then it is up to the technology head (CTO / CIO / VP – Technology / Chief Architect etc…) to come up with a strategy to do the migration. Though this might look daunting luckily there are several proven strategies that can be leveraged on.

First and foremost understand why you need to migrate and what the benefit is. This is the first key step that needs to be done before anything. This would help in understanding whether you want to go for Hybrid cloud or Private cloud, Public cloud only. By critically looking at your current business model, existing system and future plans the shape of migration can be planned.

For example if your application has high sensitive data or is very chatty by nature then private cloud will be the best option, if you system is going to incorporate web fronts, social media integration etc… You may look at a hybrid solution or if your system is anyway light weight and your plans in the future do not include dealing with highly sensitive data you can look at just going with public cloud.

Next understand the architecture difference between monolithic all in one, Hybrid cloud and cloud architectures and see what fits best for your system. Is your system a large monolithic system which is difficult to decompose? Or are there parts in your system that can work independently and are light weight enough to be moved around? Or are you even planning on some new features that can be done as separate sub systems that can be used to glue into your existing system with glue code. In this phase you can identify what are potential candidates. Another area to analyze is the workload each area of the system does. Depending on the load you can decide which areas would need high scalability and plan accordingly your cloud migration.

Now that you have identified whether you want to move ahead with modernizing the existing system to cloud, let’s look at some options you have in doing this safely.

Lift and Shift

This is the first step in moving to cloud, where simply the monolithic application can be taken and move in to a cloud environment as is. At this stage the early analysis that was done will become priceless. You would be able to understand whether you would need to have a private cloud or hybrid cloud solution where certain parts of the system with sensitive data or chatty behavior can be shifted and any area that is light weight and can reside in a public cloud. My recommendation is always go for a hybrid where your master database and core components in your monolithic system to be in a private cloud or dedicated servers and any customer facing web tier apps or disjointed parts of your system which can run on their own to be in public cloud. The key thing to understand is that, there is minimum or no change done to the systems architecture. This is the least expensive and fastest in terms moving to cloud however then you will not get the full benefit of cloud.

Partition or Incremental Replacement

Next option or the natural progression from “lift and shift” is to start migrating parts of the system incrementally to cloud or partition the system and migrate. Here again the analysis done initially will be priceless as you can identify which areas will be easiest to migrate / replace or which areas of the system would benefit from a cloud migration. You would create a list of your systems functional / business domain units and put down a priority for cloud migration. You can look at what is the business value, how easy is it, what is the cost for each unit of your system for creating a priority list.

For example if your system has a web front where customers come into place orders, then that is an ideal candidate as that can be easily migrated to cloud with some effort, however by doing this you could leverage the elasticity of cloud. Also if your analysis revealed that this area of the system is what get’s most of the hits seasonally then again this is an ideal candidate. You can even look at having the web front in public cloud whilst the database and even business tier apps still residing in private or dedicated environment initially.

Once you have the list prioritized you would go on either moving each part of the system to cloud by modernizing or replacing with another application / system. The cost in this phase / option is higher then lifts and shifts but you will be able to leverage befits of cloud more and you are now getting in to a true cloud system. Also this will be very less risky than doing a full blown cloud migration in one go and following an application migration list will mitigate risk.

Refactor and Cloudify

This is the most costly and up front time consuming option. Here you would look at your system with your analysis done and completely re-engineer your system with newer architecture and / or technology to move into cloud. There are methods of bringing your system architecture to cloud and those needs to be studied. You will need to invest upfront time and resourcing to start refactoring your system to be cloud ready and use cloud. For example you may go from a monolithic system to a SOA based or Microservice based architecture, you will go from one single database to multi-master database architecture, you may even have to change your technology stack to support cloud, you will need to change your delivery, deployment processes by leveraging orchestration tools etc.. However once done your system will be fully cloud compliant and will be able to reap the benefits of cloud including cost reductions, elasticity, high availability , safe deployments, continues deliveries etc…

So there you have it, three ways to modernize your current system to cloud. My personal opinion and what I have used for most is to go from “lift and shift” to “partitioning and incremental replacement” or refactoring. This will be less risky and will allow you to reap the benefits of cloud early as well as give you time to learn and absorb all that comes with a cloud based system.