【Ovirt 笔记】session 机制分析

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

分析整理的版本为 Ovirt 3.4.5 版本。

  • enginesession 交由 SessionDataContainer 单例对象统一处理。

用户登录

通过 LoginBaseCommandattachUserToSession 方法实现。

  • 登录成功,将用户添加到 session 中。
SessionDataContainer.getInstance().setUser(getParameters().getSessionId(), getCurrentUser());
  • 同时设置 登录 IP登录方式 等。
SessionDataContainer.getInstance().setUserIp(getParameters().getIp());
SessionDataContainer.getInstance().setKind(getParameters().getKind());

用户登出

通过 LogoutUserCommandexecuteCommand() 方法实现。

  • 登出,将用户从 session 中删除。
public final void removeSession(String sessionId) {
    oldContext.remove(sessionId);
    newContext.remove(sessionId);
}

session 实现原理分析

  • SessionDataContainer 对象中,提供了两个 session 列表。
  • oldContext 中保存旧的 session
  • newContext 中保存新的 session
  • SessionDataContainer 放入 engine 的后台调度,每 30 分钟,执行一次 cleanExpiredUsersSessions 方法。
SchedulerUtilQuartzImpl.getInstance().scheduleAFixedDelayJob(SessionDataContainer.getInstance(),
                    "cleanExpiredUsersSessions", new Class[] {}, new Object[] {},
                    sessionTimeoutInterval,
                    sessionTimeoutInterval, TimeUnit.MINUTES);
@TypeConverterAttribute(Integer.class)
@DefaultValueAttribute("30")
UserSessionTimeOutInterval,
@OnTimerMethodAnnotation("cleanExpiredUsersSessions")
public final void cleanExpiredUsersSessions() {
    deleteOldGeneration();
}
  • cleanExpiredUsersSessions 方法中,用 newContext 覆盖 oldContext,再重新创建 newContext
private Map> deleteOldGeneration() {
    Map> temp = oldContext;
    oldContext = newContext;
    newContext = new ConcurrentHashMap>();
    return temp;
}
  • session 的生命周期

    • 将数据加入 newContext 列表。
    • 数据由 newContext 列表迁移到 oldContext 列表。
    • oldContext 数据被其他 newContext 数据所覆盖而过期。
  • session 的续签

public final Object getData(String sessionId, String key, boolean refresh) {
    Map currentContext = null;
    if ((currentContext = newContext.get(sessionId)) != null) {
        return currentContext.get(key);
    }
    if (refresh) {
        if ((currentContext = oldContext.remove(sessionId)) != null) {
            newContext.put(sessionId, currentContext);
        }
    } else {
        currentContext = oldContext.get(sessionId);
    }
    if (currentContext != null) {
        return currentContext.get(key);
    }
    return null;
}

用户在界面上进行功能操作,使用 session,执行 getData 方法,设置 refreshtrue,表明续签 session

该操作会将 session 数据由 oldContext 列表迁移到 newContext 列表,并且等待下一次的 cleanExpiredUsersSessions 调用。

  • session 的数据过期

    • 如果用户在规定时间内,未进行界面操作,数据从 newContext 列表迁移到 oldContext 列表,再被其他 newContext 数据覆盖而过期。
    • sessionnewContext 列表迁移到 oldContext 列表的时间间隔为 30 分钟。oldContext 中的 session 失效也是 30 分钟。
    • session 数据在 newContext 列表即将迁移的最后一分钟加入,则该 session 最长失效时间为 31 分钟。
    • session 数据在 newContext 列表迁移后一分钟加入,则该 session 最长失效时间为 59 分钟。
  • session 的检测处理

    • ApplicationPlaceManager 中绑定了界面区域变化操作,如果发现 session 不存在,则退出系统。
@Override
public void revealDefaultPlace() {
    // revealPlace(getDefaultPlace());
    PlaceRequest pr = getDefaultPlace();
    if (pr == null) {
        Window.Location.replace("/"); //$NON-NLS-1$
    } else {
        revealPlace(pr);
    }
}

protected PlaceRequest getDefaultPlace() {
    if (user.isLoggedIn()) {
        return getDefaultMainSectionPlace();
    } else {
        // return defaultLoginSectionRequest;
        return null;
    }
}
  • session 的读取

    • 首先从 newContext 列表中读取,未发现再从 oldContext 列表中读取。

你可能感兴趣的:(【Ovirt 笔记】session 机制分析)