Skip to content

Instantly share code, notes, and snippets.

@jbrisbin
Created May 5, 2015 17:35
Show Gist options
  • Save jbrisbin/8f314b032a30ec682465 to your computer and use it in GitHub Desktop.
Save jbrisbin/8f314b032a30ec682465 to your computer and use it in GitHub Desktop.
DeltaAwareExpiringSession
public class DeltaAwareExpiringSession implements ExpiringSession {
private final Queue<Map.Entry<String, Object>> deltas = new LinkedList<Map.Entry<String, Object>>();
@Id
private String id = UUID.randomUUID().toString();
private long creationTime = System.currentTimeMillis();
private long lastAccessedTime = creationTime;
private int maxInactiveInterval = DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
private volatile Map<String, Object> sessionAttrs;
public DeltaAwareExpiringSession(Map<String, Object> sessionAttrs) {
this.sessionAttrs = sessionAttrs;
}
@Override
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public long getCreationTime() {
return creationTime;
}
public void setCreationTime(long creationTime) {
this.creationTime = creationTime;
}
@Override
public long getLastAccessedTime() {
return lastAccessedTime;
}
public void setLastAccessedTime(long lastAccessedTime) {
this.lastAccessedTime = lastAccessedTime;
}
@Override
public int getMaxInactiveIntervalInSeconds() {
return maxInactiveInterval;
}
@Override
public void setMaxInactiveIntervalInSeconds(int interval) {
this.maxInactiveInterval = interval;
}
@Override
public boolean isExpired() {
return isExpired(System.currentTimeMillis());
}
@Override
public Set<String> getAttributeNames() {
applyDeltas();
return sessionAttrs.keySet();
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAttribute(String attributeName) {
applyDeltas();
return (T) sessionAttrs.get(attributeName);
}
@Override
public void setAttribute(String attributeName, Object attributeValue) {
addDelta(new AbstractMap.SimpleImmutableEntry<String, Object>(attributeName, attributeValue));
}
@Override
public void removeAttribute(String attributeName) {
setAttribute(attributeName, null);
}
public void applyDeltas() {
if (deltas.isEmpty()) {
return;
}
synchronized (deltas) {
if (deltas.isEmpty()) {
return;
}
Map<String, Object> sessionAttrs = new HashMap<String, Object>(this.sessionAttrs);
Map.Entry<String, Object> attr;
while (null != (attr = deltas.poll())) {
if (null == attr.getValue()) {
sessionAttrs.remove(attr.getKey());
} else {
sessionAttrs.put(attr.getKey(), attr.getValue());
}
}
this.sessionAttrs = sessionAttrs;
}
}
protected void addDelta(Map.Entry attribute) {
deltas.add(attribute);
}
protected boolean isExpired(long now) {
if (maxInactiveInterval < 0) {
return false;
}
return now - TimeUnit.SECONDS.toMillis(maxInactiveInterval) >= lastAccessedTime;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Session)) {
return false;
}
Session that = (Session) o;
if (!id.equals(that.getId())) {
return false;
}
return true;
}
@Override
public int hashCode() {
return id.hashCode();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment