/**
* Licensed to Ravel, Inc. under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Ravel, Inc. licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.goldenorb.zookeeper;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.ZooKeeper;
import org.goldenorb.JobManager;
import org.goldenorb.conf.OrbConfigurable;
import org.goldenorb.conf.OrbConfiguration;
import org.goldenorb.event.OrbCallback;
import org.goldenorb.event.OrbEvent;
import org.goldenorb.event.OrbExceptionEvent;
import org.goldenorb.jet.OrbTrackerMember;
import org.goldenorb.util.ResourceAllocator;
import org.goldenorb.zookeeper.LeaderGroup;
public class TJTracker implements Runnable, OrbConfigurable {
private ZooKeeper zk;
private CountDownLatch joinLeaderGroup;
private CountDownLatch exit;
private OrbConfiguration orbConf;
private TMember member;
private LeaderGroup<TMember> leaderGroup;
private String basePath;
private JobManager jobManager;
private OrbCallback orbCallback;
private boolean runTracker = true;
private boolean leader = false;
private ResourceAllocator allocator;
/**
* Constructor
*
* @param ZooKeeper zk
* @param CountDownLatch joinLeaderGroup
* @param CountDownLatch exit
* @param OrbConfiguration orbConf
* @param int data
* @param String basePath
*/
public TJTracker(ZooKeeper zk,
CountDownLatch joinLeaderGroup,
CountDownLatch exit,
OrbConfiguration orbConf,
int data,
String basePath) {
this.joinLeaderGroup = joinLeaderGroup;
this.exit = exit;
this.zk = zk;
this.orbConf = orbConf;
this.basePath = basePath;
member = new TMember();
member.setData(data);
}
/**
*
*/
@Override
public void run() {
orbCallback = new OrbTJTrackerCallback();
leaderGroup = new LeaderGroup<TMember>(zk, orbCallback, "/GoldenOrb/" + orbConf.getOrbClusterName()
+ "/OrbTrackerLeaderGroup", member, TMember.class);
joinLeaderGroup.countDown();
if (leaderGroup.isLeader()) {
leader();
} else {
slave();
}
}
/**
* Set the orbConf
* @param OrbConfiguration orbConf
*/
@Override
public void setOrbConf(OrbConfiguration orbConf) {
this.orbConf = orbConf;
}
/**
* Return the orbConf
*/
@Override
public OrbConfiguration getOrbConf() {
return orbConf;
}
/**
*
*/
private void leader() {
synchronized (this) {
leader = true;
allocator = new ResourceAllocator(orbConf, leaderGroup.getMembers());
jobManager = new JobManager(orbCallback, orbConf, zk, allocator, leaderGroup.getMembers());
}
waitLoop();
}
/**
*
*/
private void slave() {
synchronized (this) {
leader = false;
if (jobManager != null) {
jobManager.shutdown();
}
}
waitLoop();
}
/**
*
*/
private void waitLoop() {
while (runTracker) {
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (leaderGroup.isLeader()) {
leader();
} else {
slave();
}
}
}
private class OrbTJTrackerCallback implements OrbCallback {
/**
*
* @param OrbEvent e
*/
@Override
public void process(OrbEvent e) {
if (e.getType() == OrbEvent.ORB_EXCEPTION) {
((OrbExceptionEvent) e).getException().printStackTrace();
} else {
if (e.getType() == OrbEvent.LEADERSHIP_CHANGE) {
synchronized (TJTracker.this) {
if ((leaderGroup.isLeader() && !leader) || (!leaderGroup.isLeader() && leader)) {
TJTracker.this.notify();
}
}
}
}
}
}
/**
*
*/
public void leave() {
runTracker = false;
leaderGroup.leave();
if (jobManager != null) {
jobManager.shutdown();
}
exit.countDown();
}
/**
* Return the eader
*/
public boolean isLeader() {
return leaderGroup.isLeader();
}
}