protected void cleanupLocks( Set<String> activeSessionIds ) {
try {
ExecutionContext context = repository.context();
DateTimeFactory dates = context.getValueFactories().getDateFactory();
DateTime now = dates.create();
DateTime newExpiration = dates.create(now, RepositoryConfiguration.LOCK_EXTENSION_INTERVAL_IN_MILLIS);
PropertyFactory propertyFactory = context.getPropertyFactory();
SessionCache systemSession = repository.createSystemSession(context, false);
SystemContent systemContent = new SystemContent(systemSession);
Map<String, List<NodeKey>> lockedNodesByWorkspaceName = new HashMap<>();
// Iterate over the locks ...
MutableCachedNode locksNode = systemContent.mutableLocksNode();
for (ChildReference ref : locksNode.getChildReferences(systemSession)) {
NodeKey lockKey = ref.getKey();
CachedNode lockNode = systemSession.getNode(lockKey);
if (lockNode == null) {
//it may happen that another thread has performed a session.logout which means the lock might have been removed
continue;
}
ModeShapeLock lock = new ModeShapeLock(lockNode, systemSession);
NodeKey lockedNodeKey = lock.getLockedNodeKey();
if (lock.isSessionScoped() && activeSessionIds.contains(lock.getLockingSessionId())) {
//for active session locks belonging to the sessions of this process, we want to extend the expiration date
//so that other processes in a cluster can tell that this lock is still active
MutableCachedNode mutableLockNode = systemSession.mutable(lockKey);
Property prop = propertyFactory.create(ModeShapeLexicon.EXPIRATION_DATE, newExpiration);
mutableLockNode.setProperty(systemSession, prop);
//reflect the change in the expiry date in the internal map
this.locksByNodeKey.replace(lockedNodeKey, lock.withExpiryTime(newExpiration));
continue;
}
//if it's not an active session lock, we always check the expiry date
DateTime expirationDate = firstDate(lockNode.getProperty(ModeShapeLexicon.EXPIRATION_DATE, systemSession));
if (expirationDate.isBefore(now)) {
//remove the lock from the system area
systemContent.removeLock(lock);
//register the target node which needs cleaning
List<NodeKey> lockedNodes = lockedNodesByWorkspaceName.get(lock.getWorkspaceName());
if (lockedNodes == null) {