diff options
8 files changed, 85 insertions, 11 deletions
| diff --git a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/Bookmark.java b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/Bookmark.java index 5c1342a..a659049 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/Bookmark.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/Bookmark.java @@ -38,7 +38,7 @@ public class Bookmark extends Post {    @Transient    @CheckForNull -  public String getDescriptionHtml() { +  protected String computeDescriptionHtml() {      if (description == null) {        return null;      } diff --git a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java index 059335c..f81ed04 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java @@ -109,6 +109,7 @@ public class BookmarkResource extends PostResource {      bookmark.title = title;      bookmark.tags = Set.of();      bookmark.description = description; +    bookmark.cachedDescriptionHtml = null;      bookmark.owner = user;      assignPostTargets(visibility, user, bookmark); diff --git a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatMessage.java b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatMessage.java index ffafb96..5cec6aa 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatMessage.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatMessage.java @@ -31,10 +31,7 @@ public class LazychatMessage extends Post {    @JsonbTransient    @CheckForNull    public String getContentHtml() { -    if (content == null) { -      return null; -    } -    return new MarkdownConverter().htmlify(content); +    return getDescriptionHtml();    }    @CheckForNull @@ -52,8 +49,11 @@ public class LazychatMessage extends Post {    @CheckForNull    @Override    @JsonbTransient -  public String getDescriptionHtml() { -    return getContentHtml(); +  protected String computeDescriptionHtml() { +    if (content == null) { +      return null; +    } +    return new MarkdownConverter().htmlify(content);    }    @Override diff --git a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatResource.java b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatResource.java index cbdbe76..156b638 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatResource.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/lazychat/LazychatResource.java @@ -82,6 +82,7 @@ public class LazychatResource extends PostResource {      }      message.content = text; +    message.cachedDescriptionHtml = null;      message.format = "markdown";      assignPostTargets(visibility, user, message); diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java index bbfafa2..aa15fa2 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java @@ -47,6 +47,8 @@ public abstract class Post extends PanacheEntityBase {    private static final Logger log = Logger.getLogger(Post.class); +  private static final int DESCRIPTION_CACHE_VERSION = 1; +    @Id    @SequenceGenerator(        allocationSize = 1, @@ -61,6 +63,14 @@ public abstract class Post extends PanacheEntityBase {    @CheckForNull    public OffsetDateTime date; +  @Column(name = "cached_description_version", nullable = true) +  @CheckForNull +  public Integer cachedDescriptionVersion; + +  @Column(name = "cached_description_html", nullable = true) +  @CheckForNull +  public String cachedDescriptionHtml; +    @ManyToOne(fetch = FetchType.LAZY)    @JoinColumn(name = "owner", referencedColumnName = "id")    @CheckForNull @@ -93,7 +103,21 @@ public abstract class Post extends PanacheEntityBase {    public abstract String getTitle();    @CheckForNull -  public abstract String getDescriptionHtml(); +  public final String getDescriptionHtml() { +    if (cachedDescriptionHtml != null && +        cachedDescriptionVersion != null && +        cachedDescriptionVersion >= DESCRIPTION_CACHE_VERSION){ +      return cachedDescriptionHtml; +    } else { +      @CheckForNull var descriptionHtml = computeDescriptionHtml(); +      cachedDescriptionHtml = descriptionHtml; +      cachedDescriptionVersion = DESCRIPTION_CACHE_VERSION; +      return descriptionHtml; +    } +  } + +  @CheckForNull +  protected abstract String computeDescriptionHtml();    @CheckForNull    public abstract String getUri(); @@ -190,6 +214,10 @@ public abstract class Post extends PanacheEntityBase {        this.posts = resultList;      } +    public void cacheDescriptions() { +      days().forEach(Day::cacheDescriptions); +    } +      public class Day {        public final @CheckForNull LocalDate date;        public final List<T> posts; @@ -198,6 +226,12 @@ public abstract class Post extends PanacheEntityBase {          this.date = date;          this.posts = posts;        } + +      public void cacheDescriptions() { +        for (var post : posts) { +          post.getDescriptionHtml(); +        } +      }      }      public List<Day> days() { @@ -211,9 +245,9 @@ public abstract class Post extends PanacheEntityBase {      }    } -  public static List<Post> findViewable( +  public static PostPage<Post> findViewable(        PostFilter postFilter, Session session, @CheckForNull User viewer, @CheckForNull User owner) { -    return findViewable(postFilter, session, viewer, owner, null, null).posts; +    return findViewable(postFilter, session, viewer, owner, null, null);    }    public static PostPage<Post> findViewable( diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java index 580f8bc..f58140e 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java @@ -113,6 +113,7 @@ public abstract class PostResource {    @GET    @Produces(TEXT_HTML) +  @Transactional    public TemplateInstance getIndex(        @QueryParam("i") @CheckForNull Integer cursor,        @QueryParam("n") @CheckForNull Integer maxResults) { @@ -123,6 +124,8 @@ public abstract class PostResource {      var session = entityManager.unwrap(Session.class);      var q = Post.findViewable(postFilter, session, reader, null, cursor, maxResults); +    q.cacheDescriptions(); +      var feedUri = uri.getPath() + "/feed";      if (reader != null) {        var pageKey = ensurePageKey(reader, feedUri); @@ -145,6 +148,7 @@ public abstract class PostResource {    @GET    @Path("~{ownerName}")    @Produces(TEXT_HTML) +  @Transactional    public TemplateInstance getUserIndex(        @PathParam("ownerName") String ownerName,        @QueryParam("i") @CheckForNull Integer cursor, @@ -157,6 +161,8 @@ public abstract class PostResource {      var session = entityManager.unwrap(Session.class);      var q = Post.findViewable(postFilter, session, reader, owner, cursor, maxResults); +    q.cacheDescriptions(); +      var feedUri = uri.getPath() + "/feed";      if (reader != null) {        var pageKey = ensurePageKey(reader, feedUri); @@ -219,6 +225,7 @@ public abstract class PostResource {    @GET    @Path("feed")    @Produces(APPLICATION_ATOM_XML) +  @Transactional    public String getFeed(@QueryParam("page-key") @CheckForNull String pageKeyBase36)        throws FeedException {      @CheckForNull var pageKey = pageKeyBase36 == null ? null : new BigInteger(pageKeyBase36, 36); @@ -228,6 +235,7 @@ public abstract class PostResource {    @GET    @Path("~{ownerName}/feed")    @Produces(APPLICATION_ATOM_XML) +  @Transactional    public String getUserFeed(        @QueryParam("page-key") @CheckForNull String pageKeyBase36,        @PathParam("ownerName") String ownerName) @@ -257,7 +265,10 @@ public abstract class PostResource {    private String makeFeed(        @CheckForNull User reader, @Nullable User owner, @Nullable String ownerName)        throws FeedException { -    var posts = Post.findViewable(postFilter, entityManager.unwrap(Session.class), reader, owner); +    var q = Post.findViewable(postFilter, entityManager.unwrap(Session.class), reader, owner); +    q.cacheDescriptions(); +    var posts = q.posts; +      var feed = new Feed("atom_1.0");      var feedSubId = owner == null ? "" : String.format("/%d", owner.id); diff --git a/src/main/resources/db/changeLog-1.1.xml b/src/main/resources/db/changeLog-1.1.xml new file mode 100644 index 0000000..b32f983 --- /dev/null +++ b/src/main/resources/db/changeLog-1.1.xml @@ -0,0 +1,26 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<databaseChangeLog +  xmlns="http://www.liquibase.org/xml/ns/dbchangelog" +  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +  xsi:schemaLocation=" +    http://www.liquibase.org/xml/ns/dbchangelog +    http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.9.xsd"> + +  <changeSet author="mulk" id="1.1-1"> +    <addColumn tableName="lazychat_messages" schemaName="benki"> +      <column name="cached_description_html" type="varchar"/> +      <column name="cached_description_version" type="integer"/> +    </addColumn> + +    <addColumn tableName="bookmarks" schemaName="benki"> +      <column name="cached_description_html" type="varchar"/> +      <column name="cached_description_version" type="integer"/> +    </addColumn> + +    <addColumn tableName="posts" schemaName="benki"> +      <column name="cached_description_html" type="varchar"/> +      <column name="cached_description_version" type="integer"/> +    </addColumn> +  </changeSet> + +</databaseChangeLog> diff --git a/src/main/resources/db/changeLog.xml b/src/main/resources/db/changeLog.xml index bae8dda..7d346aa 100644 --- a/src/main/resources/db/changeLog.xml +++ b/src/main/resources/db/changeLog.xml @@ -7,5 +7,6 @@      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.9.xsd">    <include file="db/changeLog-1.0.xml"/> +  <include file="db/changeLog-1.1.xml"/>  </databaseChangeLog> | 
