diff --git a/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java b/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java index 874546c..d84a4e7 100644 --- a/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java +++ b/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java @@ -106,6 +106,7 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi implements ApplicationEventPublisherAware, FindByIndexNameSessionRepository, InitializingBean { private static final AtomicBoolean usingDataSerialization = new AtomicBoolean(false); + private static final AtomicBoolean usingEagerCommit = new AtomicBoolean(false); private ApplicationEventPublisher applicationEventPublisher = event -> {}; @@ -275,6 +276,25 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi return usingDataSerialization.get(); } + /** + * Set a condition to determine whether a {@link Session} is copied and committed before saving. + * + * @param useEagerCommit boolean to determine whether to copy and commit a {@link Session} before saving. + */ + @SuppressWarnings("unused") + public void setUseEagerCommit(boolean useEagerCommit) { + usingEagerCommit.set(useEagerCommit); + } + + /** + * Determines whether a {@link Session} is copied and committed before saving. + * + * @return a boolean value indicating whether a {@link Session} is copied and committed before saving. + */ + protected boolean isUsingEagerCommit() { + return usingEagerCommit.get(); + } + /** * Callback method during Spring bean initialization that will capture the fully-qualified name * of the cache {@link Region} used to manage {@link Session} state and register this {@link SessionRepository} @@ -677,6 +697,21 @@ public abstract class AbstractGemFireOperationsSessionRepository extends CacheLi : new GemFireSession(session); } + @SuppressWarnings("all") + public static GemFireSession copyCommitted(Session session) { + + synchronized (session) { + + GemFireSession sessionCopy = copy(session); + + if (session instanceof GemFireSession) { + ((GemFireSession) session).commit(); + } + + return sessionCopy; + } + } + @SuppressWarnings("unchecked") public static T from(Session session) { return (T) (session instanceof GemFireSession ? session : copy(session)); diff --git a/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java b/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java index 2065b0a..8894e75 100644 --- a/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java +++ b/spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java @@ -166,14 +166,22 @@ public class GemFireOperationsSessionRepository extends AbstractGemFireOperation /*private*/ void doSave(@NonNull Session session) { - // Save Session As GemFireSession - getTemplate().put(session.getId(), GemFireSession.from(session)); + GemFireSession sessionToSave = isUsingEagerCommit() + ? GemFireSession.copyCommitted(session) + : GemFireSession.from(session); - if (session instanceof GemFireSession) { + // Save Session As GemFireSession + getTemplate().put(session.getId(), sessionToSave); + + if (isCommittable(session)) { ((GemFireSession) session).commit(); } } + private boolean isCommittable(@Nullable Session session) { + return !isUsingEagerCommit() && session instanceof GemFireSession; + } + /** * Deletes (removes) any existing {@link Session} from GemFire. This operation * also results in a SessionDeletedEvent.