Thursday, June 30, 2011

Enums, PropertyChangeListener and State machine

State machines are key structures to build stateful applications over stateless messages. Following is a simple uni-directional state machine used as a compute engine with different processes triggering at different state of the machine. The machine has three states - Begin, Work and Finish.

When a Session is started the Machine sets itself in a Begin state, Each next() then switches the machine from the current state to the next. Processor(s) can be registered at different states of the machine.

The states are Begin -> Work -> Finish -> Null (Sink) and are defined via an Enum:

public enum State {
BEGIN,
WORK,
FINISH;
}

Lets start with a Session (Also the state machine)

public class Session {
private String BEGIN;
private String WORK;
private String END;

/**
* Create a Session state machine with three uni-directional states.
* BEGIN -> WORK -> FINISH -> Null
*/
private enum SessionState {

BEGIN() {
@Override
public SessionState next() {
return WORK;
}
},

WORK() {
@Override
public SessionState next() {
return FINISH;
}
},

FINISH() {
@Override
public SessionState next() {
return null;
}
};

public abstract SessionState next();

}

private SessionState STATE = SessionState.BEGIN;

private String sessionId;

private PropertyChangeSupport propertyChangeSupport;

private Session() {
propertyChangeSupport = new PropertyChangeSupport(this);
}

public static Session newSession() {
return new Session();
}

void next() {
synchronized (STATE) {
SessionState old = STATE;
STATE = STATE.next();
if (STATE != null) {
propertyChangeSupport.firePropertyChange(STATE.name(), old, STATE);
}
}
}

boolean isValid() {
return STATE != null;
}

String sessionId() {
switch (STATE) {
case BEGIN:
if (sessionId == null) {
sessionId = UUID.randomUUID().toString();
}
return sessionId;
case WORK:
if (sessionId == null || sessionId.trim().equals("")) {
throw new IllegalStateException("Session Id can not be null in WORK");
}
return sessionId;
case FINISH:
if (sessionId == null || sessionId.trim().equals("")) {
throw new IllegalStateException("Session Id can not be null in FINISH");
}
return sessionId;
default:
throw new IllegalStateException("Session has not yet started");
}
}

void addStateChangeListener(State state, PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(state.name(), listener);
}

}


Lets build some processing units - One for Work and the other for Finish states


public class WorkSessionListener implements PropertyChangeListener {
private final String sessionId;

public WorkSessionListener(String sessionId) {
this.sessionId = sessionId;
}

public void propertyChange(PropertyChangeEvent evt) {
System.out.println ("[" + sessionId + " - Working]=" + evt.getOldValue() + " -> " + evt.getNewValue());
}
}

public class FinishSessionListener implements PropertyChangeListener {

private final String sessionId;

public FinishSessionListener(String sessionId) {
this.sessionId = sessionId;
}

public void propertyChange(PropertyChangeEvent evt) {
System.out.println ("[" + sessionId + " - Finish]=" + evt.getOldValue() + " -> " + evt.getNewValue());
}
}


Now lets test it


import org.junit.Test;

public class SessionStateChangeTest {
@Test
public void testSessionStateChange() {
final Session session = Session.newSession();
final Session session2 = Session.newSession();

session.addStateChangeListener(State.WORK, new WorkSessionListener(session.sessionId()));
session.addStateChangeListener(State.FINISH, new FinishSessionListener(session.sessionId()));


session2.addStateChangeListener(State.WORK, new WorkSessionListener(session2.sessionId()));

Thread t1 = new Thread(new Runnable() {
public void run() {
while (session.isValid()) {
session.next();
}
}
});

Thread t2 = new Thread(new Runnable() {
public void run() {
while (session2.isValid()) {
session2.next();
}
}
});

t1.start();
t2.start();

try {
t1.join();
t2.join();
} catch (InterruptedException exp) {

}
}

}


We should see two BEGIN -> WORK and one WORK -> FINISH messages for two session ids.

Enjoy!

Wednesday, June 29, 2011

Adios chavanni

Today was the last day of Indian chavvani or chaar aana that to be legally used. It was launched in 1950 as an Indian rupee unit and served its purpose well for 61 years. I still remember seeing ek aana or one paisa being in circulation. Though, as I started to recognize the world around me ek aana was put to rest. It became a collector's item and we as kids could not keep our hands off of one. As I lost my piggybank I don't even know if I will ever see it again. That time ek aana could not buy anything but one single "Kampat" a locally made toffy. On the other hand while ek aana was setting down in oblivion the other unit - 10 paisa quietly lost its value. Time spiked and even beggars stopped asking for a 10 paisa grant. Thats when the chavanni had its value. Unlike its predecessors chavanni was special. Its value hovered around as a unit that can make the "other unit" bigger. An increase of 25 paisa in bus/tempo fair raised eyebrows as students. Having one in my pockets made me feel richer and losing one could have meant loss in purchasing power. Chavanni was small and circular, like our world. It was easy to exchange as a favor, like love that could put a smile on a face without hurting the giver. Chavanni was the only unit that I have ever heard used as a name to call the boys working on road side dhabas or assistance to truckers. But like many other good things it did find its abuser too. It came with a class system. Calling one a chavanni would mean to demean him. Many people would not know that India used a different metric system in its past. 1 Rupee (or 100 paisa) was equivalent to 16 aanas. Chavanni (a quarter - 4 aanas) and Atthanni (8 aanas or 50 paisa) were the only two units that were quietly migrated to the new metric system as they were easier to divide between 100 and 16 a challenge that 10 paisa could not deal with. Now Atthanni is alone. It has lost its partner. Its the last bastion of the old aana system though not in use. As Chavvanni slowly leaves the market with heavy remembrance of its past I can hear it sing this tune:

जाते हैं ये जगह छोड़ के अंधेरों कि तरफ,
काश बैठा न होता मैं संग नोट हज़ार के।
जबकि उड़ते रहे बड़े नोट मॉलों में हर तरफ,
मैं धूल खाता रहा ताउम्र छोटे बाज़ार के।

Sunday, June 26, 2011

Has Hindi Literature died after Agyeya? Or not!

Its ironic to write about Hindi literature in English. But if your sentiments are not publicly searchable in Google then I guess they do not exist, times have changed. If there were no Jai Shankar Prasad, Premchand or Mahadevi Verma Hindi would still have only be known for Tulsi, Sur and Kabir. But after this era as time got shorter and shorter new literature started to find its place more on podiums than in books and even lesser in class rooms. Hasya Kavi Sammelans became forefront channels to spread what they thought was Hindi. Poems became story telling that has little to no lifetime beyond the relevancy of the story itself. The conditions of writers fared not so bad some even turned out to be huge commercial success, thanks to the Bollywood and Television. Now some of the same very writers question why Hindi should be easier, I guess they are the ones who could find their roots in novels sold on the Railways kiosks. So where is this language? Like many other non-English international languages it does find challenging to keep up. The most dangerous is lack of quality Writers who can express today's challenges in a timeless manner. Aloofness from Government and mid to poor financial backing from India's Hindi belt are also some contributing factors. मंचीय कवियों पर Doctorate हो रहे हैं। चुटकुले लिखने वाले आज के साहित्यकार बन बैठे हैं। बस अब तो यही कह सकते हैं:

न रह गयी समझ मुझमे, न लिखने का मन ही करता है।
कभी थे यायावर हम भी, अब तो बस कल की ही चिंता है।
जो अग्नि थी भी कभी मुझमे, बुझी सी अब वो रहती है,
जलाया सोच कर ये था कि स्याही इसी से बनती है।
किताबें हो गयीं वो कम कसम खाके जिसे सच बोलूँ,
सुनेगा कौन सच मेरा किताबें झूठ की जो खोलूँ?
कवि वो जा चुके हैं सुन जिन्हें आँखें नम होती थीं,
कलम उठता नहीं मेरा खीझ अब मेरी ये पीड़ा है।
कभी थे यायावर हम भी, अब तो बस कल की ही चिंता है।

Wednesday, June 01, 2011

Are the new age companies bastardizing names?

There was a time when the name of the killer companies (Companies at the forefront) had a lot of weight. "International Business Machine", "Computer Science Corporation", "General Electrics", "General Motors", "Scientific American" and so on. The names sound similar to people of that era like the names of our Grand parents. Each name has at least two words compounded with titles. Names had deep meanings and somewhat reflective of what they do. Then like an era of James Brown, Father of todays Rap music names of the companies turned more hip and shorter. "Oracle", "Apple", "Sun", "Amazon". Things started to change and the names reflected a new generation of companies. Instead of names that sounded more like "King Richard 1 The Lion Heart" it became simpler but still meaningful like "Prince Charles". The best thing about Generation is that it changes and brings new approach to life. "Google", "Twitter", "Facebook", "LinkedIn" - you won't know what they do unless you use them. Websters and Oxford must be having hard time scratching their heads on how to recognize these vehemently meaningful names in their dictionary? How would "Search anything on the web Corporation" sound instead of just Google? Or "Express thoughts in 140 characters Private limited" for Twitter? No they won't sound right. Name of a company has nothing to do with what they do. In this fast paced life we don't have three seconds to pronounce a name, we only have one - so better use it right.