LearnerSessionTracker
// 从节点用于管理会话
public class LearnerSessionTracker extends UpgradeableSessionTracker
{
// 日志记录对象
private static final Logger LOG = LoggerFactory.getLogger(LearnerSessionTracker.class);
// 会话超期
private final SessionExpirer expirer;
//
private final AtomicReference<Map<Long, Integer>> touchTable
= new AtomicReference<Map<Long, Integer>>();
// 服务id
private final long serverId;
// 下一会话id
private final AtomicLong nextSessionId = new AtomicLong();
// 全局会话及其超时时间
private final ConcurrentMap<Long, Integer> globalSessionsWithTimeouts;
public LearnerSessionTracker(
SessionExpirer expirer,
ConcurrentMap<Long, Integer> sessionsWithTimeouts,
int tickTime, long id, boolean localSessionsEnabled, ZooKeeperServerListener listener)
{
// 会话超期对象
this.expirer = expirer;
// 会话id及其超时时间?
this.touchTable.set(new ConcurrentHashMap<Long, Integer>());
// 全局会话id及其超时时间
this.globalSessionsWithTimeouts = sessionsWithTimeouts;
// 服务id
this.serverId = id;
// 下一会话id
nextSessionId.set(SessionTrackerImpl.initializeNextSessionId(serverId));
// 支持本地会话
this.localSessionsEnabled = localSessionsEnabled;
if (this.localSessionsEnabled)
{
// 创建本地会话追踪
createLocalSessionTracker(expirer, tickTime, id, listener);
}
}
// 移除会话
public void removeSession(long sessionId)
{
// 从本地会话追踪对象中移除此会话
if (localSessionTracker != null)
{
localSessionTracker.removeSession(sessionId);
}
// 从全局会话及其超时时间中移除此会话
globalSessionsWithTimeouts.remove(sessionId);
// 从touchTable中移除此会话
touchTable.get().remove(sessionId);
}
// 开始
public void start()
{
if (localSessionTracker != null)
{
// 通过本地会话追踪对象执行开始
localSessionTracker.start();
}
}
// 关闭
public void shutdown()
{
// 通过本地会话追踪对象执行关闭
if (localSessionTracker != null)
{
localSessionTracker.shutdown();
}
}
// 全局会话id及其超时时间中是否包含此会话id
public boolean isGlobalSession(long sessionId)
{
return globalSessionsWithTimeouts.containsKey(sessionId);
}
// 追踪会话--直接返回了false
public boolean trackSession(long sessionId, int sessionTimeout)
{
return false;
}
// 提交会话
public synchronized boolean commitSession(long sessionId, int sessionTimeout)
{
// 在全局会话及其超时时间中加入此会话id--超时时间
boolean added = globalSessionsWithTimeouts.put(sessionId, sessionTimeout) == null;
if (added)
{
LOG.info("Committing global session 0x{}", Long.toHexString(sessionId));
}
// 如果支持本地会话
if (localSessionsEnabled)
{
// 从本地会话中移除此会话id
removeLocalSession(sessionId);
// 完成会话升级
finishedUpgrading(sessionId);
}
// 在touchTable中放入此会话id及其超时时间
touchTable.get().put(sessionId, sessionTimeout);
return added;
}
// touchSession
public boolean touchSession(long sessionId, int sessionTimeout)
{
// 本地会话使能下
if (localSessionsEnabled)
{
// 通过本地会话追踪对象执行touchSession
// 如果成功,则返回
if (localSessionTracker.touchSession(sessionId, sessionTimeout))
{
return true;
}
// 如果会话id既不是全局会话,又不是升级中会话,返回
if (!isGlobalSession(sessionId) && !isUpgradingSession(sessionId))
{
return false;
}
}
// 在touchTable中放入此会话id及其超时时间
touchTable.get().put(sessionId, sessionTimeout);
return true;
}
// 会话id及其超时时间的快照
public Map<Long, Integer> snapshot()
{
// 通过touchTable得到,得到后touchTable内容被置空
return touchTable.getAndSet(new ConcurrentHashMap<Long, Integer>());
}
// 创建会话
public long createSession(int sessionTimeout)
{
// 支持本地会话下
if (localSessionsEnabled)
{
// 本地会话追踪对象执行创建会话
return localSessionTracker.createSession(sessionTimeout);
}
// 得到下一会话id
return nextSessionId.getAndIncrement();
}
// 检查会话
public void checkSession(
long sessionId, Object owner) throws SessionExpiredException, SessionMovedException
{
// 本地会话追踪对象存在
if (localSessionTracker != null)
{
try
{
// 通过本地会话追踪对象执行会话检查
localSessionTracker.checkSession(sessionId, owner);
return;
}
// 抛出未知会话异常下
catch (UnknownSessionException e)
{
// 如果会话id也不是全局会话
if (!isGlobalSession(sessionId))
{
// 抛出会话超期异常
throw new SessionExpiredException();
}
}
}
}
// 设置会话拥有者
public void setOwner(long sessionId, Object owner) throws SessionExpiredException
{
// 本地会话追踪对象存在
if (localSessionTracker != null)
{
try
{
// 通过本地会话追踪对象设置会话拥有者
localSessionTracker.setOwner(sessionId, owner);
return;
}
// 会话超期异常
catch (SessionExpiredException e)
{
// 如果会话id不是全局会话
if (!isGlobalSession(sessionId))
{
// 继续抛出异常
throw e;
}
}
}
}
// 打印会话
public void dumpSessions(PrintWriter pwriter)
{
// 本地会话追踪对象
if (localSessionTracker != null)
{
// 打印
pwriter.print("Local ");
// 打印本地会话追踪对象
localSessionTracker.dumpSessions(pwriter);
}
// 打印全局会话
pwriter.print("Global Sessions(");
// 打印全局会话及其超时时间
pwriter.print(globalSessionsWithTimeouts.size());
pwriter.println("):");
// 全局会话及其超时时间中会话id集合
SortedSet<Long> sessionIds = new TreeSet<Long>(globalSessionsWithTimeouts.keySet());
// 对每个全局会话
for (long sessionId : sessionIds)
{
pwriter.print("0x");
// 会话id
pwriter.print(Long.toHexString(sessionId));
pwriter.print("\t");
// 超时时间
pwriter.print(globalSessionsWithTimeouts.get(sessionId));
pwriter.println("ms");
}
}
// 设置会话关闭标志为关闭中
public void setSessionClosing(long sessionId)
{
// 本地会话追踪对象存在下,通过本地会话追踪对象设置会话关闭中
if (localSessionTracker != null)
{
localSessionTracker.setSessionClosing(sessionId);
}
}
// 获取 时间点--超期会话id集合 映射表
@Override
public Map<Long, Set<Long>> getSessionExpiryMap()
{
return new HashMap<Long, Set<Long>>();
}
// 获取全局会话id集合
public Set<Long> globalSessions()
{
return globalSessionsWithTimeouts.keySet();
}
}