Archive for 2010

BusinessEvents 4: using Scorecards in a clustered environment

Scorecards have a special purpose in TIBCO BE. There are often used for static (as in Java-style static) values which should be globally accessible through the whole engine. As Java statics, TIBCO describes its main purpose in instance dependent Variables which are only valid in the context of one Processing Unit in an Inference engine.
Here a little citation of the TIBCO documentation on this topic (p.144 – Understanding and Working With Scorecards):

A scorecard is a special type of concept. A scorecard serves as a set of static
variables that is available throughout the project.

It is more accurate to say there is one instance of a scorecard per inference agent.
Each inference agent in an application has its own instance of the score card.
Scorecards are not shared between agents.

So you can use Scorecards without any Issues as long as you consider the per Instance rule. Now I have a project where Timeouts are calculated an stored in Scorecards. This solution works perfectly in single instance environment because of the special behavior described above. Now there comes a new Requirement into the project. The Agents should be clustered over 2 Instances to ensure high availability. This really ruins the simplicity of the scorecard approach.

Digging a little deeper into the documentation I came to the conclusion that all the scorecards had to be stored in the cache-server. Knowing this, it came to me mind that the only thing I must accomplish would be, that all inference agents use the same instance of the scorecard.

To achieve the single Instance per Agent approach, TIBCO uses Instance keys for every Processing Unit. So if you could change this instance key, all agents had to us the same instance of the scorecards and the timeout-solution would still work. Searching the documentation the answer was also found really quickly on page 144 (Understanding and Working With Scorecards).
On that page TIBCO described how to set this instance key via CDD.

Any agent that uses scorecards, and also uses Cache Manager, must be assigned a
unique key so that the correct scorecard can be retrieved from the cache. The key
is set in the Processing Unit tab of the CDD.

I also tried this approach on a little test project and it worked right away.

What this means is, you can change the behavior of Scorecards depending on your needs. If you need a per Instance Variable you just have to set different Instance keys for every Agent. On the other hand if you want a globally shared Variable you can achieve this by setting the same value to all instances.

, ,

No Comments

URL encode / decode in JavaScript

Decoding and Encoding URLs in JavaScript should be a pretty easy thing to do especially since all browsers still have the functionality built-in. Interestingly no browser allows the JavaScript runtime to use this feature. So I had to write it for myself.
The code I came up with is far from perfect but it worked for me. To decode an URL use url_decode(url) and to reverse it just call the utf16to8 function. The rest does your browser for you.

function url_decode(str){
var hex = /^[0-9a-fA-F]{2}/;
var out='';
var arr = str.split('%');
if(arr.length<2) return str;
for(var i=0;i<arr.length;i++)
{
  /*look for hex values */
  if(hex.exec(arr[i])) {
    out += String.fromCharCode(parseInt(arr[i].substring(0,2),16))+arr[i].substring(2,arr[i].length);
  } else { if(i==0) out+=arr[i]; else out+='%'+arr[i];
  }
}
return utf8to16(out);
}

function utf16to8(str) {
    var out, i, len, c;

    out = "";
    len = str.length;
    for(i = 0; i < len; i++) {
	c = str.charCodeAt(i);
	if ((c >= 0x0001) && (c <= 0x007F)) {
	    out += str.charAt(i);
	} else if (c > 0x07FF) {
	    out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
	    out += String.fromCharCode(0x80 | ((c >>  6) & 0x3F));
	    out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
	} else {
	    out += String.fromCharCode(0xC0 | ((c >>  6) & 0x1F));
	    out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
	}
    }
    return out;
}

function utf8to16(str) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = str.length;
    i = 0;
    while(i < len) {
	c = str.charCodeAt(i++);
	switch(c >> 4)
	{
	  case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
	    // 0xxxxxxx
	    out += str.charAt(i-1);
	    break;
	  case 12: case 13:
	    // 110x xxxx   10xx xxxx
	    char2 = str.charCodeAt(i++);
	    out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
	    break;
	  case 14:
	    // 1110 xxxx  10xx xxxx  10xx xxxx
	    char2 = str.charCodeAt(i++);
	    char3 = str.charCodeAt(i++);
	    out += String.fromCharCode(((c & 0x0F) << 12) |
					   ((char2 & 0x3F) << 6) |
					   ((char3 & 0x3F) << 0));
	    break;
	}
    }
    return out;
}

, ,

No Comments

tracking virtual links with google analytics

Tracking dynamic sites is sometimes a bit tricky. Typically tracking systems are specialized in tracking page views. More sophisticated system have there own way of tracking custom event (like shown here).
Unfortunately I needed to track clicks on a HTML canvas. To make these clicks visible to a tracking system, I wanted to transform each click to virtual URL. That way I could use Google analytics not only for tracking but also for popularity statistics of certain content.
The script for doing so is actually pretty simple.

function trace(url){
var tracker = _gat._getTracker("UA-XXXXXXX-X");
tracker._trackPageview(url);
}

Now every time I need to track something I call this function with a custom build URL.

, ,

No Comments