$ thought | blog

Place to serialize my thoughts…

Archive for the ‘Developer’ Category

Rewards of “Frequent Check In”

with 4 comments

I have worked with many developers and many times, I ran into following conversation. Whenever we are in the middle of development and I ask for checking in the code, one of following reply is heard -

  • Umm, lets do check-in towards end-of-the day. We are not yet done with the code.
  • Let me clean up these things and make them perfect.
  • I don't want to check-in as I have some ongoing changes and I can't checkin partial files.
  • Lets checkin tomorrow when we complete major functionality.

I am sure you must have heard similar conversation (or had it). Can you give a moment and think about why do are we afraid of checking-in? I have been constantly thinking about this issue and there are many reasons which makes sense on this issue. Few of them are -

Fear of bad code - Developers are afraid of peers criticizing their code. Its GOOD! Believe me, you're never going to write perfect code without receiving feedback about it. Sooner you receive the feedback, better you perform in short time. This is the reason, people don't make their changes public until they are convinced that they can't do any better. It is clearly a false fear.
One of the way to improve and influence your team is to make your work public as it is in progress. This way, you make team aware of your approach. If there is any conflict in approach or disconnect in understanding, it becomes visible sooner and you can resolve it better.

Not sure about impact on other parts of the system - Yes! This is very valid reason. You're in middle of a feature and you're not sure how it will impact rest of the system if you check-in early. Half baked features can take the whole system down. To get over this fear, unit testing your code, running a full build before check-in and having continuous integration makes sure your changes are fail-safe. Make sure that you are providing a working build to the team by writing solid unit tests and more comprehensive integration tests.

Working on multiple parallel streams - It is often a bad practice to work on multiple parallel streams of work. Even worse when you don't commit any of those changes in VCS.
If you're working with DVCS like Git, it is very easy to branch and commit code. If you're working on central VCS like subversion, then it is little tricky to keep your parallel working streams with minimal effort. There are few simple things you can do to make your life little easy -

Use DVCS. This will prove immense value in long run, if you use it properly. There is a learning curve associated with it, but it is definitely worth it.
If you are using SVN, create a branch if it is a big change. If it is small change, evaluate if you can checkin without breaking application. Taking patch is another option too. Use unit testing safety net on your side and make sure you progress smoothly.

In any situation, its not helpful when you're working on parallel streams of work and those changes co-exist. I have often observed people checking in partial or missing content. This happens when they are confused and trying to understand what all files are required to make one of streams live.

Why frequent check in is important?

  • Getting feedback from your application and team.
  • Never lose any of your changes and hard work. Machines do crash and when they do, its bad!
  • Avoid stepping on each others toes, particularly when team is distributed and code churn is faster.
  • Making whole team aware of your approach and remove silo operations. This helps bringing everybody on the same page and triggers conversations whenever required.
  • You can't explain in 30 minutes of speech what code explains in 10 minutes. It eliminates confusion.
  • Discipline of frequent checkin allows you to make sure, changes are not causing any conflicts.
  • Smaller changes, encourages you to refactor and improve code quality.

If you want to read more -

Golden principle of development: Check-in-early, check-in-often.
DVCS introduction from the master: Google Video on Git.
Continuous integration: Wikipedia entry.

Written by Sachin

June 19th, 2010 at 7:53 am

Things to Ponder with Alfresco (Part III: WCM – Improvements)

without comments

Now days using web content management systems (WCM) is trivial. You should continuously update the website content to maintain a fresh look. It increases returning customers and popularity. Almost every major website uses a CMS to achieve this. It might be an in-house developed or an off-the-shelf product. In any case, it helps organizations to separate the content authoring team from the application development cycles.  This helps in quicker content updates without being dependent on release schedules. I am going to point out certain things about WCM feature of alfresco. You can also apply the same principles to your WCM if you are using existing one, or planning to develop a new one!

Content storage format - Alfresco provides a nice feature called "web-forms". There are two types of forms currently available i.e. WCM forms and ECM forms. Both of them capture the input data and store it as XML. You can also choose to apply content transformation using XSL. It helps to save final output as either HTML, Text or PDF etc. Not to forget, the content is actually captured and saved as XML. In my perception one of the strengths of Alfresco is its content repository. If XML is target format, it is saved in CR as a cm:content property and it defeats the whole purpose. If CR is not aware of the structure of the content, it defeats the purpose of content model definition? It is not very different from storing the content xml as plain string in database. Frankly I don't see any benefit of using CR over database in this method.

To avoid such inefficient use of alfresco, you can take some effort and write a custom form component. Use custom forms (develop forms in your application and then communicate with alfresco using API) to capture user data and store them in content repository in defined content model and schema.

This will help you in -

  • Content repository now understands the structure of your content. This is really important and if you have any doubts, please post that in comments. I might write about it later in my blog.
  • You can apply your custom content transformation logic so that content can be exported in XML / HTML / custom output format. Just generate this once every time you update the content. It improves the efficiency of content management system to deliver target content.
  • You will have a flexibility of own input format, use JSP or rails forms, its your choice!

Deployment benefits - Alfresco has another great strength, Deployment Infrastructure. I think its also one of its weaknesses. Use it wisely to improve your release management. On the release date of web application usually you come across content sanity issues, or format differences. To avoid that, setup proper environments where alfresco can sync content and test it before you push it to live. This might save you a lot of frustration.

Although its a great feature, there is a caveat to that. Generally all the code for web application is stored in CVS systems. Alfresco code (web scripts, web form definitions etc.) is stored in alfresco. Keeping the versions of alfresco code and web application code is nightmare. Develop some automated web script deployment tool and every time you release, wipe out all the previous webscripts and deploy new ones from the CVS. This always makes you keep updated code in the CVS and versioning becomes much robust.

Written by Sachin

January 4th, 2010 at 8:48 pm

Posted in Articles,Developer

Tagged with ,

Things to ponder with Alfresco (Part-II: Workflow Design)

with 2 comments

Complex Workflow Designs  

Complex Workflow Designs

As I mentioned in my earlier post that I will be writing few more posts about the Alfresco. This is second installment in the series. If you are thinking to use Alfresco at the center of your application then it is hard that it will not have a workflow. If your business process is just more than simple workflows mentioned in Alfresco, then for sure you have to write your own business model definition.

If you are planning to do so, here are few lessons I have learned –

  • Simplicity – We got lot of benefits just by keeping our process definition simple and neat. Don’t add unnecessary steps which will cause confusing steps for the end users.
  • Right things at right place – Alfresco is very flexible in terms of business logic implementation. You will always have multiple options to accomplish same operation. Web Scripts, Java classes or Web Service and you will be tempted to use different things at times. Decide one approach and stick to it. Put as much as logic in the workflow and don’t spread across the workflow business logic outside the workflow.
  • Loops can be evil – Loops in the workflow actions can be daunting at times. Rethink on the circular steps in the workflow and make sure you are not violating the “simplicity” rule. It might be difficult sometimes to achieve these steps.
  • Blocking is good sometimes – Next bigger decision should be synchronous operations or asynchronous. All the operations which might result in inconsistent states should be synchronous i.e. transactional. Asynchronous operations are better in terms of responsiveness. Sending e-mails could be asynchronous tasks as you people can receive emails after couple of seconds, but if it is related to pushing records to a queue, let it be synchronous. You got the idea!

You are advised to check Alfresco wiki for more details. There is plenty of documentation available for the administration and authoring custom workflows.

Written by Sachin

September 21st, 2008 at 5:17 pm

Things to ponder with Alfresco (Part-I: Content Model)

without comments

For any content repository, content model definition is similar to the DDL (schema definition) for databases. It is expected in a big application to have evolutionary content model like databases. Updating the table structures or introducing new tables is common in any business application. In content repository, you should also keep in mind that your content model should be open to evolve. Define the content model which will be extensible. Most of the good practices of database design should be applicable here.

Few tips for better content models -

  • Use aspects for specializing types instead of defining content types. There are few advantages of that, aspects can be applied or removed at run-time which gives you much more control over the dynamic nature of types.
  • Aspects also helps in keeping the default set of properties over a content type to be small. Alfresco recommends you to prefer aspects over custom content types.
  • Aspects helps you to logically group properties. This helps your data to be part of multiple groups at the same time. If you have aspects Publishable and Indexable; you can apply or revoke a nature at your will without much hassle.
  • Indexing is very helpful for searchable content. It is useful but use it wisely. The cost of indexing in Alfresco is much higher than cost of index in Databases as this will be full-text search indexes. It will take up more disk space as well as time to index the data. Don't index the content which people are not expect to search! You can define this at the time of content model definition.
  • Versioning is similar to indexing and use this wisely. The content which is versionable is handled separately by Alfresco. This might be affecting performance as your repository size grows. Don't mark content as versionable if you don't plan to maintain revisions for content.

I will continue this series with other experiences with Alfresco. Later.

Written by Sachin

September 13th, 2008 at 11:51 pm

Alfresco: Workflow managed by JavaScript

with 5 comments

If you are a regular reader of this blog, you might have figured out that I am currently working on a project involving alfresco at the center and it's a content management system. Earlier I have worked with Content repository (Apache Jackrabbit) and that was a good experience. Alfresco is next step of a content repository which extends it into a full blown content management system and much more. I was working on a problem where we defined a custom (Advanced workflow) to be precise in Alfresco lingo. This workflow was needed to be monitored, managed and accessed only via a webscript as we have used webscripts to do almost everything in our project. I was very pleased to see this, but that is only available in 2.9 labs release (as of now). We are using alfresco 2.2.0 version for our development and that is production stable version, so I have very little choice but go with production version. Alfresco has very limited JavaScript API support for workflow manipulation and that was difficult job for manage. There was no other option than writing custom JavaScript API which allows to manage workflow in Alfresco. We did that and it was very powerful and easy! :) I wanted following features for JavaScript API -

  • Easy to extend
  • Can handle any workflows
  • Provides easy ways to retrieve tasks, definitions, paths etc.
  • Provides as much functionality possible which is available in Alfresco Workflow Console.

Alfresco workflow console is command line interaction component which allows you to manipulate, get information about workflows using simple commands and I wanted to do all that using JavaScript. I started exploring the source code and found a class 'org.alfresco.service.cmr.workflow.WorkflowService'. This class has generic API which allows you to do all the operations possible through workflow console. This bean is used for workflow console operations. So all I needed was expose this bean in JavaScript as root object and start using it. That simple! I wrote a simple java class to expose the bean as follows:

package com.xxxx.yyyy.workflow;
 
import java.util.List;
 
import org.alfresco.repo.processor.BaseProcessorExtension;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.workflow.WorkflowService;
 
public class WorkflowManager extends BaseProcessorExtension {
	private ServiceRegistry services;
 
	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
		this.services = serviceRegistry;
	}
 
	public WorkflowService getWorkflowService(){
		return services.getWorkflowService();
	}
}

The method getWorkflowService() exposes the workflow service to the JavaScript calls. To expose the Workflow Manager as root object in JavaScript create WEB-INF/classes/alfresco/extension/custom-script-context.xml and you will be good! (If you don't know how to do that, read this) Now, you can get the handle of workflow service in JavaScript code. Yet, we need to write a small component which will allow us to retrieve the active workflows, tasks etc. To do so, I wrote a small JavaScript object which provides those functionality to the user.

var workflowService = workflow.getWorkflowService();
 
var W = {
	transitions: function(noderef){
		var task = W._currentTask(noderef);
		var trans = [];
		try{
		var tasks = task && task.path.node.transitions;
		for(var index=0; index < tasks.length; index++){
			trans[trans.length] = tasks[index].id;
		}
		}catch(error){
			// Ignore error
		}
		return trans;
	},
 
	move: function(noderef, command){
		workflowService.endTask(W._currentTask(noderef).id
                , command);
	},
 
	_workflowPath: function(noderef){
		var workFlows = workflow.getWorkflows
                      ("workspace://SpacesStore/" + noderef, true);
		if(workFlows.size()>0){
			return workFlows.get(0).id + "-@";
		}
		return "";
	},
 
	_currentTask: function(noderef){
		var curTask;
		var tasks;
		try{
		tasks = workflowService.getTasksForWorkflowPath
                           (W._workflowPath(noderef));
		if(tasks.size() > 0)
		      curTask = tasks.get(0);
		} catch(Error){
			// Ignore error
		}
		return curTask;
	}
}
 
function initWorkflow(noderef)
{
	var wflow = actions.create("start-workflow");
	wflow.parameters.workflowName
             = "jbpm$xxxxyyyy:abc"; // your workflow name
	wflow.parameters["bpm:assignee"]
             = person.properties.userName;
	wflow.parameters["bpm:workflowDescription"]
             = "Put your description";
	wflow.execute(noderef_for_which_workflow_will_associate);
}

Thats it! The initiate workflow method is used to apply a workflow to a node. Once that is done, the W object can be used to do operations like retrieving the active tasks, ending the workflow and making the workflow transition. Hope that helps. If you need more workflow related information and reading material you can visit following places:

  • JBPM jPDL Documentation (here)
  • Alfresco workflow wiki (here)
  • ECMArchitect Advance Workflow Guide (here)

Written by Sachin

May 29th, 2008 at 10:35 am