Attempt to use stateless sessions in read-only operations. (#301)

This commit is contained in:
Kavin 2022-07-04 06:42:01 +01:00 committed by GitHub
parent cdd8a962d7
commit 17b9a974de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 53 deletions

View file

@ -8,6 +8,7 @@ import me.kavin.piped.utils.*;
import me.kavin.piped.utils.obj.db.PubSub;
import me.kavin.piped.utils.obj.db.User;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import org.schabi.newpipe.extractor.NewPipe;
@ -54,7 +55,7 @@ public class Main {
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<PubSub> criteria = cb.createQuery(PubSub.class);

View file

@ -5,8 +5,8 @@ import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.Root;
import me.kavin.piped.utils.obj.db.*;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SharedSessionContract;
import org.hibernate.StatelessSession;
import java.util.List;
import java.util.UUID;
@ -14,13 +14,12 @@ import java.util.UUID;
public class DatabaseHelper {
public static User getUserFromSession(String session) {
try (Session s = DatabaseSessionFactory.createSession()) {
s.setHibernateFlushMode(FlushMode.MANUAL);
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
return getUserFromSession(session, s);
}
}
public static User getUserFromSession(String session, Session s) {
public static User getUserFromSession(String session, SharedSessionContract s) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<User> cr = cb.createQuery(User.class);
Root<User> root = cr.from(User.class);
@ -30,8 +29,7 @@ public class DatabaseHelper {
}
public static User getUserFromSessionWithSubscribed(String session) {
try (Session s = DatabaseSessionFactory.createSession()) {
s.setHibernateFlushMode(FlushMode.MANUAL);
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<User> cr = cb.createQuery(User.class);
Root<User> root = cr.from(User.class);
@ -42,7 +40,7 @@ public class DatabaseHelper {
}
}
public static Channel getChannelFromId(Session s, String id) {
public static Channel getChannelFromId(SharedSessionContract s, String id) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<Channel> cr = cb.createQuery(Channel.class);
Root<Channel> root = cr.from(Channel.class);
@ -52,13 +50,12 @@ public class DatabaseHelper {
}
public static Channel getChannelFromId(String id) {
try (Session s = DatabaseSessionFactory.createSession()) {
s.setHibernateFlushMode(FlushMode.MANUAL);
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
return getChannelFromId(s, id);
}
}
public static List<Channel> getChannelsFromIds(Session s, List<String> id) {
public static List<Channel> getChannelsFromIds(SharedSessionContract s, List<String> id) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<Channel> cr = cb.createQuery(Channel.class);
Root<Channel> root = cr.from(Channel.class);
@ -67,7 +64,7 @@ public class DatabaseHelper {
return s.createQuery(cr).list();
}
public static Video getVideoFromId(Session s, String id) {
public static Video getVideoFromId(SharedSessionContract s, String id) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<Video> cr = cb.createQuery(Video.class);
Root<Video> root = cr.from(Video.class);
@ -77,13 +74,12 @@ public class DatabaseHelper {
}
public static Video getVideoFromId(String id) {
try (Session s = DatabaseSessionFactory.createSession()) {
s.setHibernateFlushMode(FlushMode.MANUAL);
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
return getVideoFromId(s, id);
}
}
public static PlaylistVideo getPlaylistVideoFromId(Session s, String id) {
public static PlaylistVideo getPlaylistVideoFromId(SharedSessionContract s, String id) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<PlaylistVideo> cr = cb.createQuery(PlaylistVideo.class);
Root<PlaylistVideo> root = cr.from(PlaylistVideo.class);
@ -92,7 +88,7 @@ public class DatabaseHelper {
return s.createQuery(cr).uniqueResult();
}
public static Playlist getPlaylistFromId(Session s, String id) {
public static Playlist getPlaylistFromId(SharedSessionContract s, String id) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<Playlist> cr = cb.createQuery(Playlist.class);
Root<Playlist> root = cr.from(Playlist.class);
@ -101,7 +97,7 @@ public class DatabaseHelper {
return s.createQuery(cr).uniqueResult();
}
public static List<PlaylistVideo> getPlaylistVideosFromIds(Session s, List<String> id) {
public static List<PlaylistVideo> getPlaylistVideosFromIds(SharedSessionContract s, List<String> id) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<PlaylistVideo> cr = cb.createQuery(PlaylistVideo.class);
Root<PlaylistVideo> root = cr.from(PlaylistVideo.class);
@ -110,7 +106,7 @@ public class DatabaseHelper {
return s.createQuery(cr).list();
}
public static PubSub getPubSubFromId(Session s, String id) {
public static PubSub getPubSubFromId(SharedSessionContract s, String id) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<PubSub> cr = cb.createQuery(PubSub.class);
Root<PubSub> root = cr.from(PubSub.class);
@ -120,8 +116,7 @@ public class DatabaseHelper {
}
public static PubSub getPubSubFromId(String id) {
try (Session s = DatabaseSessionFactory.createSession()) {
s.setHibernateFlushMode(FlushMode.MANUAL);
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
return getPubSubFromId(s, id);
}
}

View file

@ -1,14 +1,10 @@
package me.kavin.piped.utils;
import me.kavin.piped.consts.Constants;
import me.kavin.piped.utils.obj.db.Channel;
import me.kavin.piped.utils.obj.db.Playlist;
import me.kavin.piped.utils.obj.db.PlaylistVideo;
import me.kavin.piped.utils.obj.db.PubSub;
import me.kavin.piped.utils.obj.db.User;
import me.kavin.piped.utils.obj.db.Video;
import me.kavin.piped.utils.obj.db.*;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.cfg.Configuration;
public class DatabaseSessionFactory {
@ -31,4 +27,8 @@ public class DatabaseSessionFactory {
public static final Session createSession() {
return sessionFactory.openSession();
}
public static StatelessSession createStatelessSession() {
return sessionFactory.openStatelessSession();
}
}

View file

@ -29,6 +29,7 @@ import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage;
import org.schabi.newpipe.extractor.Page;
@ -224,9 +225,10 @@ public class ResponseHelper {
info.getRelatedItems().forEach(o -> relatedStreams.add(collectRelatedStream(o)));
Multithreading.runAsync(() -> {
try (Session s = DatabaseSessionFactory.createSession()) {
me.kavin.piped.utils.obj.db.Channel channel = DatabaseHelper.getChannelFromId(s, info.getId());
me.kavin.piped.utils.obj.db.Channel channel = DatabaseHelper.getChannelFromId(info.getId());
try (Session s = DatabaseSessionFactory.createSession()) {
if (channel != null) {
if (channel.isVerified() != info.isVerified()
@ -324,7 +326,7 @@ public class ResponseHelper {
}
private static byte[] playlistPipedResponse(String playlistId) throws IOException {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
var cb = s.getCriteriaBuilder();
var cq = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
var root = cq.from(me.kavin.piped.utils.obj.db.Playlist.class);
@ -421,7 +423,7 @@ public class ResponseHelper {
private static byte[] playlistPipedRSSResponse(String playlistId)
throws FeedException {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
var cb = s.getCriteriaBuilder();
var cq = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
var root = cq.from(me.kavin.piped.utils.obj.db.Playlist.class);
@ -720,7 +722,7 @@ public class ResponseHelper {
user = user.toLowerCase();
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<User> cr = cb.createQuery(User.class);
Root<User> root = cr.from(User.class);
@ -786,12 +788,10 @@ public class ResponseHelper {
tr.commit();
Multithreading.runAsync(() -> {
try (Session s2 = DatabaseSessionFactory.createSession()) {
var channel = DatabaseHelper.getChannelFromId(s2, channelId);
var channel = DatabaseHelper.getChannelFromId(channelId);
if (channel == null) {
Multithreading.runAsync(() -> saveChannel(channelId));
}
}
});
}
@ -825,7 +825,7 @@ public class ResponseHelper {
}
public static byte[] isSubscribedResponse(String session, String channelId) throws IOException {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
var cb = s.getCriteriaBuilder();
var query = cb.createQuery(Long.class);
var root = query.from(User.class);
@ -848,7 +848,7 @@ public class ResponseHelper {
User user = DatabaseHelper.getUserFromSession(session);
if (user != null) {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
CriteriaBuilder cb = s.getCriteriaBuilder();
@ -892,7 +892,7 @@ public class ResponseHelper {
if (user != null) {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
SyndFeed feed = new SyndFeedImpl();
feed.setFeedType("atom_1.0");
@ -954,7 +954,7 @@ public class ResponseHelper {
if (user != null) {
Multithreading.runAsync(() -> {
try (Session sess = DatabaseSessionFactory.createSession()) {
try (Session s = DatabaseSessionFactory.createSession()) {
if (override) {
user.setSubscribed(Set.of(channelIds));
} else {
@ -963,15 +963,15 @@ public class ResponseHelper {
}
if (channelIds.length > 0) {
var tr = sess.beginTransaction();
sess.merge(user);
var tr = s.beginTransaction();
s.merge(user);
tr.commit();
}
}
});
Multithreading.runAsync(() -> {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
var channels = DatabaseHelper.getChannelsFromIds(s, Arrays.asList(channelIds));
Arrays.stream(channelIds).parallel()
@ -996,7 +996,7 @@ public class ResponseHelper {
User user = DatabaseHelper.getUserFromSession(session);
if (user != null) {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
CriteriaBuilder cb = s.getCriteriaBuilder();
var query = cb.createQuery(me.kavin.piped.utils.obj.db.Channel.class);
@ -1275,14 +1275,14 @@ public class ResponseHelper {
s.merge(playlist);
tr.commit();
Multithreading.runAsync(() -> pruneUnusedPlaylistVideos());
Multithreading.runAsync(ResponseHelper::pruneUnusedPlaylistVideos);
return mapper.writeValueAsBytes(new AcceptedResponse());
}
}
public static String registeredBadgeRedirect() {
try (Session s = DatabaseSessionFactory.createSession()) {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
long registered = (Long) s.createQuery("select count(*) from User").uniqueResult();
return String.format("https://img.shields.io/badge/Registered%%20Users-%s-blue", registered);
@ -1349,11 +1349,12 @@ public class ResponseHelper {
private static void updateVideo(String id, StreamInfoItem item, long time, boolean addIfNotExistent) {
Multithreading.runAsync(() -> {
try {
Session s = DatabaseSessionFactory.createSession();
Video video = DatabaseHelper.getVideoFromId(s, id);
Video video = DatabaseHelper.getVideoFromId(id);
if (video != null) {
try (Session s = DatabaseSessionFactory.createSession()) {
updateVideo(s, video, item.getViewCount(), item.getDuration(), item.getName());
}
} else if (addIfNotExistent) {
handleNewVideo("https://www.youtube.com/watch?v=" + id, time, null);
}
@ -1367,11 +1368,12 @@ public class ResponseHelper {
private static void updateVideo(String id, StreamInfo info, long time) {
Multithreading.runAsync(() -> {
try {
Session s = DatabaseSessionFactory.createSession();
Video video = DatabaseHelper.getVideoFromId(s, id);
Video video = DatabaseHelper.getVideoFromId(id);
if (video != null) {
try (Session s = DatabaseSessionFactory.createSession()) {
updateVideo(s, video, info.getViewCount(), info.getDuration(), info.getName());
}
} else {
handleNewVideo(info, time, null);
}