Skip to content

Commit e67c91b

Browse files
committed
SessionOperations
1 parent 0ef3b6b commit e67c91b

File tree

1 file changed

+52
-50
lines changed
  • extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime

1 file changed

+52
-50
lines changed

extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java

+52-50
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
package io.quarkus.hibernate.reactive.panache.common.runtime;
22

3-
import java.util.function.Function;
4-
import java.util.function.Supplier;
5-
63
import org.hibernate.reactive.common.spi.Implementor;
74
import org.hibernate.reactive.context.Context.Key;
85
import org.hibernate.reactive.context.impl.BaseKey;
6+
import org.hibernate.reactive.context.impl.ContextualDataStorage;
97
import org.hibernate.reactive.mutiny.Mutiny;
108
import org.hibernate.reactive.mutiny.Mutiny.Session;
11-
import org.hibernate.reactive.mutiny.Mutiny.SessionFactory;
129
import org.hibernate.reactive.mutiny.Mutiny.Transaction;
1310

1411
import io.quarkus.arc.Arc;
1512
import io.quarkus.arc.ClientProxy;
1613
import io.quarkus.arc.impl.LazyValue;
1714
import io.quarkus.vertx.core.runtime.context.VertxContextSafetyToggle;
1815
import io.smallrye.mutiny.Uni;
19-
import io.vertx.core.Context;
20-
import io.vertx.core.Vertx;
16+
import io.vertx.core.impl.ContextInternal;
17+
import io.vertx.core.spi.context.storage.AccessMode;
18+
import java.util.Map;
19+
import java.util.concurrent.ConcurrentHashMap;
20+
import java.util.function.Function;
21+
import java.util.function.Supplier;
2122

2223
/**
2324
* Static util methods for {@link Mutiny.Session}.
@@ -26,32 +27,23 @@ public final class SessionOperations {
2627

2728
private static final String ERROR_MSG = "Hibernate Reactive Panache requires a safe (isolated) Vert.x sub-context, but the current context hasn't been flagged as such.";
2829

29-
private static final LazyValue<Mutiny.SessionFactory> SESSION_FACTORY = new LazyValue<>(
30-
new Supplier<Mutiny.SessionFactory>() {
31-
@Override
32-
public SessionFactory get() {
33-
// Note that Mutiny.SessionFactory is @ApplicationScoped bean - it's safe to use the cached client proxy
34-
Mutiny.SessionFactory sessionFactory = Arc.container().instance(Mutiny.SessionFactory.class).get();
35-
if (sessionFactory == null) {
36-
throw new IllegalStateException("Mutiny.SessionFactory bean not found");
37-
}
38-
return sessionFactory;
39-
}
40-
});
41-
42-
private static final LazyValue<Key<Mutiny.Session>> SESSION_KEY = new LazyValue<>(
43-
new Supplier<Key<Mutiny.Session>>() {
30+
private static final LazyValue<Mutiny.SessionFactory> SESSION_FACTORY = new LazyValue<>(() -> {
31+
// Note that Mutiny.SessionFactory is @ApplicationScoped bean - it's safe to use the cached client proxy
32+
Mutiny.SessionFactory sessionFactory = Arc.container().instance(Mutiny.SessionFactory.class).get();
33+
if (sessionFactory == null) {
34+
throw new IllegalStateException("Mutiny.SessionFactory bean not found");
35+
}
36+
return sessionFactory;
37+
});
4438

45-
@Override
46-
public Key<Session> get() {
47-
Implementor implementor = (Implementor) ClientProxy.unwrap(SESSION_FACTORY.get());
48-
return new BaseKey<>(Mutiny.Session.class, implementor.getUuid());
49-
}
50-
});
39+
private static final LazyValue<Key<Mutiny.Session>> SESSION_KEY = new LazyValue<>(() -> {
40+
Implementor implementor = (Implementor) ClientProxy.unwrap(SESSION_FACTORY.get());
41+
return new BaseKey<>(Mutiny.Session.class, implementor.getUuid());
42+
});
5143

5244
// This key is used to indicate that a reactive session should be opened lazily (when needed) in the current vertx context
53-
private static final String SESSION_ON_DEMAND_KEY = "hibernate.reactive.panache.sessionOnDemand";
54-
private static final String SESSION_ON_DEMAND_OPENED_KEY = "hibernate.reactive.panache.sessionOnDemandOpened";
45+
private static final Key<Boolean> SESSION_ON_DEMAND_KEY = new BaseKey<>(Boolean.class, "hibernate.reactive.panache.sessionOnDemand");
46+
private static final Key<Boolean> SESSION_ON_DEMAND_OPENED_KEY = new BaseKey<>(Boolean.class, "hibernate.reactive.panache.sessionOnDemandOpened");
5547

5648
/**
5749
* Marks the current vertx duplicated context as "lazy" which indicates that a reactive session should be opened lazily if
@@ -63,17 +55,17 @@ public Key<Session> get() {
6355
* @see #getSession()
6456
*/
6557
static <T> Uni<T> withSessionOnDemand(Supplier<Uni<T>> work) {
66-
Context context = vertxContext();
67-
if (context.getLocal(SESSION_ON_DEMAND_KEY) != null) {
58+
Map<Key<Boolean>, Boolean> contextualDataMap = contextualDataMap(vertxContext());
59+
if (contextualDataMap.get(SESSION_ON_DEMAND_KEY) != null) {
6860
// context already marked - no need to set the key and close the session
6961
return work.get();
7062
} else {
7163
// mark the lazy session
72-
context.putLocal(SESSION_ON_DEMAND_KEY, true);
64+
contextualDataMap.put(SESSION_ON_DEMAND_KEY, Boolean.TRUE);
7365
// perform the work and eventually close the session and remove the key
7466
return work.get().eventually(() -> {
75-
context.removeLocal(SESSION_ON_DEMAND_KEY);
76-
context.removeLocal(SESSION_ON_DEMAND_OPENED_KEY);
67+
contextualDataMap.remove(SESSION_ON_DEMAND_KEY);
68+
contextualDataMap.remove(SESSION_ON_DEMAND_OPENED_KEY);
7769
return closeSession();
7870
});
7971
}
@@ -109,17 +101,17 @@ public static <T> Uni<T> withTransaction(Function<Transaction, Uni<T>> work) {
109101
* @return a new {@link Uni}
110102
*/
111103
public static <T> Uni<T> withSession(Function<Mutiny.Session, Uni<T>> work) {
112-
Context context = vertxContext();
104+
Map<Key<Session>, Session> contextualDataMap = SessionOperations.<Session> contextualDataMap(vertxContext());
113105
Key<Mutiny.Session> key = getSessionKey();
114-
Mutiny.Session current = context.getLocal(key);
106+
Mutiny.Session current = contextualDataMap.get(key);
115107
if (current != null && current.isOpen()) {
116108
// reactive session exists - reuse this session
117109
return work.apply(current);
118110
} else {
119111
// reactive session does not exist - open a new one and close it when the returned Uni completes
120112
return getSessionFactory()
121113
.openSession()
122-
.invoke(s -> context.putLocal(key, s))
114+
.invoke(s -> contextualDataMap.put(key, s))
123115
.chain(work::apply)
124116
.eventually(SessionOperations::closeSession);
125117
}
@@ -140,22 +132,24 @@ public static <T> Uni<T> withSession(Function<Mutiny.Session, Uni<T>> work) {
140132
* @return the {@link Mutiny.Session}
141133
*/
142134
public static Uni<Mutiny.Session> getSession() {
143-
Context context = vertxContext();
135+
ContextInternal context = vertxContext();
144136
Key<Mutiny.Session> key = getSessionKey();
145-
Mutiny.Session current = context.getLocal(key);
137+
final Mutiny.Session current = SessionOperations.<Session> contextualDataMap(context).get(key);
138+
final Map<Key<Boolean>, Boolean> objectsDataMap = contextualDataMap(context);
146139
if (current != null && current.isOpen()) {
147140
// reuse the existing reactive session
148141
return Uni.createFrom().item(current);
149142
} else {
150-
if (context.getLocal(SESSION_ON_DEMAND_KEY) != null) {
151-
if (context.getLocal(SESSION_ON_DEMAND_OPENED_KEY) != null) {
143+
if (objectsDataMap.get(SESSION_ON_DEMAND_KEY) != null) {
144+
if (objectsDataMap.get(SESSION_ON_DEMAND_OPENED_KEY) != null) {
152145
// a new reactive session is opened in a previous stage
153146
return Uni.createFrom().item(SessionOperations::getCurrentSession);
154147
} else {
155148
// open a new reactive session and store it in the vertx duplicated context
156149
// the context was marked as "lazy" which means that the session will be eventually closed
157-
context.putLocal(SESSION_ON_DEMAND_OPENED_KEY, true);
158-
return getSessionFactory().openSession().invoke(s -> context.putLocal(key, s));
150+
objectsDataMap.put(SESSION_ON_DEMAND_OPENED_KEY, Boolean.TRUE);
151+
return getSessionFactory().openSession().invoke(s -> SessionOperations
152+
.<Session> contextualDataMap(context).put(key, s));
159153
}
160154
} else {
161155
throw new IllegalStateException("No current Mutiny.Session found"
@@ -170,23 +164,31 @@ public static Uni<Mutiny.Session> getSession() {
170164
* @return the current reactive session stored in the context, or {@code null} if no session exists
171165
*/
172166
public static Mutiny.Session getCurrentSession() {
173-
Context context = vertxContext();
174-
Mutiny.Session current = context.getLocal(getSessionKey());
167+
Mutiny.Session current = SessionOperations.<Session> contextualDataMap(vertxContext()).get(getSessionKey());
175168
if (current != null && current.isOpen()) {
176169
return current;
177170
}
178171
return null;
179172
}
180173

174+
@SuppressWarnings({ "unchecked" })
175+
private static <T> Map<Key<T>, T> contextualDataMap(ContextInternal vertxContext) {
176+
return vertxContext.getLocal(
177+
ContextualDataStorage.CONTEXTUAL_DATA_KEY,
178+
AccessMode.CONCURRENT,
179+
ConcurrentHashMap::new);
180+
}
181+
181182
/**
182183
*
183184
* @return the current vertx duplicated context
184185
* @throws IllegalStateException If no vertx context is found or is not a safe context as mandated by the
185186
* {@link VertxContextSafetyToggle}
186187
*/
187-
private static Context vertxContext() {
188-
Context context = Vertx.currentContext();
188+
private static ContextInternal vertxContext() {
189+
ContextInternal context = ContextInternal.current();
189190
if (context != null) {
191+
// TODO: Update check for ContextItnernal
190192
VertxContextSafetyToggle.validateContextIfExists(ERROR_MSG, ERROR_MSG);
191193
return context;
192194
} else {
@@ -195,11 +197,11 @@ private static Context vertxContext() {
195197
}
196198

197199
static Uni<Void> closeSession() {
198-
Context context = vertxContext();
199200
Key<Mutiny.Session> key = getSessionKey();
200-
Mutiny.Session current = context.getLocal(key);
201+
Map<Key<Session>, Session> contextualDataMap = contextualDataMap(vertxContext());
202+
Mutiny.Session current = contextualDataMap.get(key);
201203
if (current != null && current.isOpen()) {
202-
return current.close().eventually(() -> context.removeLocal(key));
204+
return current.close().eventually(() -> contextualDataMap.remove(key));
203205
}
204206
return Uni.createFrom().voidItem();
205207
}

0 commit comments

Comments
 (0)