TIBCO BusinessEvents - Locking Guidlines

TIBCO BusinessEvents - Locking Guidlines

book

Article ID: KB0078652

calendar_today

Updated On:

Products Versions
TIBCO BusinessEvents Enterprise Edition 5.x

Description

You have to implement locking in a PreProcessor Rulefunction in your project when multiple InferenceAgents started or/and concurrent RTC is enabled. This is required to avoid different worker threads updating same entities in different RTCs at the same time (corrupts the RTC). The InferenceAgent itself will release all locks taken as one of the PostRTC activities.

Issue/Introduction

TIBCO BusinessEvents - Locking Guidlines

Environment

All Operating Systems

Resolution

Here are some guidelines for using "Cluster.DataGrid.Lock()" catalog function to take locks:

- Avoid the usage of a timeout -1 to avoid deadlock situations.
- Instead of -1 add a loop and try with a random wait time multiple times.
- When you fail to acquire lock i.e Lock() function returns false you should not proceed with the transaction. We recommend to consume and route the input Event to the input destination to process the Event again.

The Lock() function signature, description, parameters and return values:
 
Function:Cluster.DataGrid.Lock
Signature:boolean Lock(String key, long timeout, boolean localOnly)
Description:Locks the object within a rule session. This call will wait for timeout. The timeout value of zero indicates wait indefinitely
Parameters:
NameTypeDescription
keyStringA key that uniquely identifies a lock.
timeoutlongSpecify in milliseconds the time to wait for the lock.
localOnlybooleantrue if the lock is local to the local session, false if the lock is cluster wide
Returns:boolean

Sample Code:

PreProcessor RuleFunction:
if (!rfLock("sLockKey")) {
    Event.routeTo(ev,"/Channels/chLocal/evDest",null);
    Event.consumeEvent(ev);
    return;
}

// RuleFunction ============================
boolean rulefunction RuleFunctions.rfLock {
attribute {
validity = ACTION;
}
scope {

String plockkey;
}
body {

boolean bLockSuccessful = false;
int iLockRetryMax = 3;
int iLockRetries = 0;
long lWait=0;
while ((!bLockSuccessful) && (iLockRetries<iLockRetryMax)){
     iLockRetries++;
     lWait = 5000 * Math.random();
    System.debugOut("Locktimeout: " + lWait);
     bLockSuccessful = Cluster.DataGrid.Lock (plockkey, lWait, false);
}

if (!bLockSuccessful)
    System.debugOut("RuleFunctions.rfLock(): Unable to acquire lock for key: "+plockkey);

return bLockSuccessful;
}
}
// end RuleFunction ============================

Note:
1.)
On any locking issues, you can add below CDD property and set it to true.

be.engine.lockManager.enableRecording=true

Now you are able to print the lock status for the InferenceAgent using JMX BEMBean to BE log.
JMX operation:
MBeans -> com.tibco.be -> Agent -> <number> -> AgentStat -> TAB Operations execute: PrintLockManagerDetails

Sample output:
<timeStamp> <ipAddress> Warning [RMI_TCP_Connection(3)- <ipAddress>] - [runtime.service] [LockManager]
================================= Locks =================================
Key [$default.be.mt$.Thread.9] details:
  Requested level : LEVEL2
  LEVEL1
     Thread          : $default.be.mt$.Thread.9
     Locked on       : 2019-04-15 12:18:08.812
     Locked at       : com.tibco.cep.runtime.session.impl.locks.AbstractConcurrentLockManager.recordLevel1Lock(AbstractConcurrentLockManager.java:321)
                       com.tibco.cep.runtime.session.impl.locks.AbstractConcurrentLockManager.tryLocalLock(AbstractConcurrentLockManager.java:255)
                       com.tibco.cep.runtime.session.impl.locks.AbstractConcurrentLockManager.lock(AbstractConcurrentLockManager.java:447)
                       com.tibco.cep.runtime.session.impl.locks.DefaultConcurrentLockManager.lock(DefaultConcurrentLockManager.java:91)
                       com.tibco.cep.runtime.session.impl.RuleSessionImpl.lock(RuleSessionImpl.java:1289)
                       com.tibco.be.functions.cluster.DataGridFunctionsProvider.lockImpl(DataGridFunctionsProvider.java:534)
                       com.tibco.be.functions.cluster.DataGridFunctionsProvider.lock(DataGridFunctionsProvider.java:520)
                       com.tibco.be.functions.cluster.DataGridFunctions.Lock(DataGridFunctions.java:414)
                       be.gen.Rules.rTeste$rTeste_a.execute(rTeste.java:31)
                       com.tibco.cep.kernel.core.rete.ReteWM.resolveConflict(ReteWM.java:401)
                       com.tibco.cep.kernel.core.rete.ReteWM.resolveConflict(ReteWM.java:377)
                       com.tibco.cep.kernel.core.rete.ReteWM.fireRepeatEvent(ReteWM.java:2208)
                       com.tibco.cep.runtime.session.impl.RuleSessionImpl$5.doTxnWork(RuleSessionImpl.java:1780)
                       com.tibco.cep.kernel.core.rete.BeTransaction.run(BeTransaction.java:156)
                       com.tibco.cep.kernel.core.rete.BeTransaction.execute(BeTransaction.java:101)
                       com.tibco.cep.runtime.session.impl.RuleSessionImpl.fireRepeatEvent(RuleSessionImpl.java:1786)
                       com.tibco.cep.runtime.service.cluster.scheduler.AgentTimeManager$RepeatAssertEventTask.run(AgentTimeManager.java:459)
                       java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
                       java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
                       com.tibco.cep.runtime.util.CustomBEManagedThread.run(CustomBEManagedThread.java:24)
     Other waiters   : None
  LEVEL2
     Thread          : $default.be.mt$.Thread.9
     Locked on       : 2019-04-15 12:18:08.812


2.)
To check the number of outstanding lock requests in AS cluster connect to TIBCO ActiveSpaces cluster in a as-admin session and check column Locks of space "dist-<clusterType>-<clustername>-ClusterLocks"

ex (5 locks outstanding):
show space "dist-unlimited-nobs-default--ClusterLocks"

Space Definition:
_____________________________________________________________________________________________

  Space Name             : dist-unlimited-nobs-default--ClusterLocks
  Space State            : ready
  Distribution Policy    : distributed


...

Server(Seeder) Statistics:
_____________________________________________________________________________________________________________________________________________________________________________
  Member Name        | Role    |Entries   |Replicas  |Puts      |Takes     |Gets      |Expires   |Evicts    |Locks     |Unlocks   |Invokes   |Queries   |Misses    |ToPersist |
  ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  NBUlf.10.98.48.135 | seeder  |         0|         0|         0|         0|         0|         0|         0|         5|         0|         0|         0|         0|         0|

_____________________________________________________________________________________________________________________________________________________________________________

Server(Seeder) Statistics Totals:
  Total              |         |         0|         0|         0|         0|         0|         0|         0|         5|         0|         0|         0|         0|         0|
_____________________________________________________________________________________________________________________________________________________________________________

Server (Seeder) Progress:
__________________________________________________________________________________________________________________________
  Member Name        | Role    | Status          | Entries   | Replicas  | Redistribution | Index | File Size | Recovery |
  ------------------------------------------------------------------------------------------------------------------------
  NBUlf.10.98.48.135 | seeder  | running         |          0|          0|                |       |           |          |

__________________________________________________________________________________________________________________________

Server (Seeder) Progress Totals:
  Total              |         |                 |          0|          0|                |       |           |          |
__________________________________________________________________________________________________________________________



 

Additional Information

Locking, Cluster.DataGrid.Lock()