如何清除Google app engine里data store过期的_ah_session
Google app engine把session数据存储在datastore里的_ah_session表里,并且不会清除,即使session已经过期了。这让我想到了weblogic似乎也不会清除过期了的jdbc session数据。
_ah_session不清除的话,_ah_session会越来越大,直到达到空间限制。那么应该清除过期了的_ah_session,新建一个cron job,定时请求servlet清除存储session的_ah_session。
public class SessionCleanup extends StandardServlet {
private static final long serialVersionUID =
7896915936685966869L;
private static final Logger logger =
Logger.getLogger(SessionCleanup.class.getName());
private Cache cache = null;
private static final String EXPIRES = "_expires";
@Override
public void init() throws ServletException {
try {
final CacheFactory cacheFactory =
CacheManager.getInstance().getCacheFactory();
cache =
cacheFactory.createCache(Collections.emptyMap());
} catch (final CacheException e) {
logger.log(Level.SEVERE, "failed to configure
cache", e);
}
}
@Override
protected void processRequest(final HttpServletRequest
request, final HttpServletResponse response) throws ServletException,
IOException {
final long now = new Date().getTime();
final DatastoreService datastore =
DatastoreServiceFactory.getDatastoreService();
final Query query = new Query("_ah_SESSION");
// TODO make this a task
for (final Entity session :
datastore.prepare(query).asIterable(FetchOptions.Builder.withLimit(100)))
{
Long expires = (Long)
session.getProperty(EXPIRES);
if (expires < now) {
final Key key = session.getKey();
datastore.delete(key);
final StringBuilder sb = new
StringBuilder("Removed session with expiration ").append((new
Date(expires)).toString());
if (cache != null)
if
(cache.containsKey(key.getName())) {
cache.remove(key.getName());
sb.append(", also from
memcache");
}
logger.log(Level.INFO, sb.toString());
}
}
}