Sunday, August 7, 2011

5 things Usability is NOT

Thursday, August 4, 2011

[Caution] Don't change schemas in Cassandra

I came across this when I was executing the following segment of code. It main checks whether a column family is existent, and if not it creates one. Notice the synchronized block which doesn't allow multiple threads to execute this.


private boolean createCF(String CFName) { 
        BasicColumnFamilyDefinition columnFamilyDefinition = new 
BasicColumnFamilyDefinition(); 
        columnFamilyDefinition.setColumnType(ColumnType.STANDARD); 
        columnFamilyDefinition.setName(CFName); 
columnFamilyDefinition.setKeyspaceName(ReceiverConstants.BAM_KEYSPACE); 
        synchronized (this) { 
            boolean cfDefFound = false; 
            for (ColumnFamilyDefinition cfDef : 
bamKeyspaceDefinition.getCfDefs()) { 
                log.info("CF found : " + cfDef.getName()); 
                if (cfDef.getName().equals(CFName)) { 
                    cfDefFound = true; 
                    break; 
                } 
            } 
            // Column Family not found, so create it 
            if (!cfDefFound) { 
                ThriftCfDef cfDef = new 
ThriftCfDef(columnFamilyDefinition); 
                cluster.addColumnFamily(cfDef); 
            } 
            cfList.add(CFName); 
        } 
        return true; 
    } 

Problem is in a loaded scenario where multiple threads go through this code, it results in the following exception.

[2011-08-02 22:46:44,892]  INFO 
{me.prettyprint.cassandra.hector.TimingLogger} -  start[1312305404883] 
time[9] tag[META_WRITE.fail_] 
me.prettyprint.hector.api.exceptions.HInvalidRequestException: 
InvalidRequestException(why:CF is already defined in that keyspace.) 
        at 
me.prettyprint.cassandra.service.ExceptionsTranslatorImpl.translate(Excepti onsTranslatorImpl.java: 
42) 
        at me.prettyprint.cassandra.service.ThriftCluster 
$3.execute(ThriftCluster.java:68) 
        at me.prettyprint.cassandra.service.ThriftCluster 
$3.execute(ThriftCluster.java:62) 
        at 
me.prettyprint.cassandra.service.Operation.executeAndSetResult(Operation.ja va: 
101) 
        at 
me.prettyprint.cassandra.connection.HConnectionManager.operateWithFailover( HConnectionManager.java: 
156) 
        at 
me.prettyprint.cassandra.service.ThriftCluster.addColumnFamily(ThriftCluste r.java: 
72) 
        at 
org.wso2.carbon.bam.receiver.persistence.NoSQLDataStore.createCF(NoSQLDataS tore.java: 
168) 
        at 
org.wso2.carbon.bam.receiver.persistence.NoSQLDataStore.persistData(NoSQLDa taStore.java: 
124) 
        at 
org.wso2.carbon.bam.receiver.persistence.PersistenceManager.persistEvent(Pe rsistenceManager.java: 
55) 
        at 
org.wso2.carbon.bam.receiver.internal.QueueWorker.run(QueueWorker.java: 
69) 
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java: 
441) 
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
        at java.util.concurrent.ThreadPoolExecutor 
$Worker.runTask(ThreadPoolExecutor.java:886) 
        at java.util.concurrent.ThreadPoolExecutor 
$Worker.run(ThreadPoolExecutor.java:908) 
        at java.lang.Thread.run(Thread.java:619) 
Caused by: InvalidRequestException(why:CF is already defined in that 
keyspace.) 
        at org.apache.cassandra.thrift.Cassandra 
$system_add_column_family_result.read(Cassandra.java:23375) 
        at org.apache.cassandra.thrift.Cassandra 
$Client.recv_system_add_column_family(Cassandra.java:1333) 
        at org.apache.cassandra.thrift.Cassandra 
$Client.system_add_column_family(Cassandra.java:1308) 
        at me.prettyprint.cassandra.service.ThriftCluster 
$3.execute(ThriftCluster.java:66) 


This happens because, schema change methods such as cluster.addColumnFamily(cfDef) does not block. Cassandra takes time to propagate this schema change across it's nodes. Then the next thread that enters the synchronized block, fails the check to see that this column family already exists and tries to add it again. This results in the above exception.

Workaround: When you are doing schema changes such as this, try to do it in in your initialization code. Then as data is getting stored these changes will already get propagated without hitting this sort of exceptions. Or of course, if you have a static configuration, just make the changes in the Cassandra yaml file.

Tuesday, July 19, 2011

What the heck is Platform as a Service?

Software as a service or SaaS is something we come across everywhere. From Salesforce to Netsuite it's all around us and most probably plays an integral part in most companies' daily routine. So is SaaS and PaaS the same?

Actually, many SaaS companies do abuse the term this way. They provide a set of services and market it as a whole platform, and therefore term it as PaaS. PaaS is actually something that sits underneath your SaaS stack. PaaS allows you to build and integrate your customized solution on the cloud. So, basically, PaaS would allow you to build your SaaS and so much more. The real killer feature of a PaaS is that it can be a competitive advantage. Because you can leverage a PaaS and build your own solution, but SaaS provides just the same functionality to everyone. You only need to be able to afford to open up an account.

I learnt a lot of PaaS through contributing to the code of Stratos. The underlying concepts of multi tenancy, elasticity and provisioning gave me a lot of experience and actual knowledge how to implement them in running real life code. You can try the hosted version of this open source PaaS, at https://stratoslive.com/. Sign up is free, so please do give it a try. Also, if you are like me, you love to see the actual running code. You can download the source and set up Stratos on your own computer. Yes, you can do it on your laptop. I have 4GB RAM and it runs fine on my machine.

Sunday, July 17, 2011

Complex event processing (CEP) for business activity monitoring (BAM)

Business activity monitoring is mainly based around the ability to define key performance indicators (KPIs) and the ability to monitor them. Monitoring just does not mean being able to monitor visually, but the ability to generate alerts as well.

The inherent ability of CEP is to define queries for a time windows makes it ideal for defining KPIs. The ability to fire events based on the result of these queries allows us to make use of these events to fire alerts as well. So by integrating a CEP engine and a messaging system actually allows a product to have KPI definition and alerting functionality.

For a WSO2 product, we both have BAM and CEP features available in the feature repository. WSO2 Business Activity Monitor, or WSO2 BAM, already has a powerful visualization and monitoring framework. We can install the CEP feature into WSO2 BAM (If you haven't worked with WSO2 products, this just a few clicks on the UI). The CEP feature can subscribe to any broker that supports WS-Eventing or JMS and receive any events and fire alerts through the same. So, this means that BAM is now ready for defining KPIs. With BAM's dashboards and  data publishers you have a powerful monitoring product at your disposal.

Stay tuned with a tutorial on covering a whole scenario of KPI definition on alerting based on the WSO2 product stack.

MVYGRQT4TVDY

Saturday, July 16, 2011

HOWTO: Increase performance in your application

Monday, June 20, 2011

No power of operation in Java

Just found out that the usual power of (^) operation is not available in Java.

This wasted an hour of my time. So for anyone else who's about to try, please use Math.pow instead of this operator. And no, it doesn't give a compilation error either.

Instead of : 2 ^ 3, use Math.pow(2, 3).. tada, how convenient, NOT!

Sunday, June 12, 2011

WSO2 Business Activity Monitor 1.3.0 Released!

Today, I do my first release as the product manager of WSO2 Business Activity Monitor (BAM). We released WSO2 BAM version 1.3.0.

You can check it out at : http://wso2.org/library/bam

Yay!