Skip to content

Commit

Permalink
Thread-safe session management.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmihajlovski committed Jul 21, 2016
1 parent 6225c06 commit c276db8
Showing 1 changed file with 37 additions and 8 deletions.
Expand Up @@ -30,28 +30,57 @@


import java.io.Serializable; import java.io.Serializable;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;


@Authors("Nikolche Mihajlovski") @Authors("Nikolche Mihajlovski")
@Since("5.2.0") @Since("5.2.0")
public class DefaultSessionManager extends RapidoidThing implements SessionManager { public class DefaultSessionManager extends RapidoidThing implements SessionManager {


private final Map<String, byte[]> sessions = Coll.concurrentMap(); public static class SessionHolder {
volatile byte[] serialized;
volatile Map<String, Serializable> session;
final AtomicLong refCounter = new AtomicLong();
}

private final Map<String, SessionHolder> sessions = Coll.autoExpandingMap(SessionHolder.class);


@Override @Override
public Map<String, Serializable> loadSession(Req req, String sessionId) throws Exception { public Map<String, Serializable> loadSession(Req req, String sessionId) throws Exception {
byte[] bytes = sessions.get(sessionId); SessionHolder holder = sessions.get(sessionId);


if (bytes != null) { if (holder.session == null) {
return U.cast(Msc.deserialize(bytes)); synchronized (holder) {
} else { if (holder.session == null) {
return U.map();
if (holder.serialized != null) {
holder.session = U.cast(Msc.deserialize(holder.serialized));
} else {
holder.session = Coll.concurrentMap();
}
}
}
} }

holder.refCounter.incrementAndGet();

return holder.session;
} }


@Override @Override
public void saveSession(Req req, String sessionId, Map<String, Serializable> session) throws Exception { public void saveSession(Req req, String sessionId, Map<String, Serializable> session) throws Exception {
byte[] bytes = Msc.serialize(session); SessionHolder holder = sessions.get(sessionId);
sessions.put(sessionId, bytes); long refN = holder.refCounter.decrementAndGet();

U.must(refN >= 0, "The session has negative reference counter!");

if (refN == 0) {
synchronized (holder) {
if (holder.refCounter.get() == 0) {
holder.serialized = Msc.serialize(session);
holder.session = null;
}
}
}
} }


} }

0 comments on commit c276db8

Please sign in to comment.