Skip to content

Commit

Permalink
fixes igniterealtime#373: Separate stanza parsing from database loading
Browse files Browse the repository at this point in the history
By not parsing database content immediately, this parsing can be done after the database connection has been released. This should reduce resource contention.
  • Loading branch information
guusdk committed Feb 16, 2024
1 parent 82f273f commit 25de93f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 26 deletions.
1 change: 1 addition & 0 deletions changelog.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ <h1>

<p><b>2.5.1</b> -- (tbd)</p>
<ul>
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/373'>Issue #373</a>] - Separate stanza parsing from database loading</li>
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/367'>Issue #367</a>] - Fixes: JRobin's repository uses invalid certificate</li>
</ul>

Expand Down
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<description>Monitors conversations and statistics of the server.</description>
<author>Ignite Realtime</author>
<version>${project.version}</version>
<date>2023-05-23</date>
<date>2024-02-16</date>
<minServerVersion>4.7.0</minServerVersion>
<minJavaVersion>1.8</minJavaVersion>
<databaseKey>monitoring</databaseKey>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,13 @@ public static Direction getDirection(@Nonnull final JID owner, @Nonnull final JI
@Nonnull
private final JID with;

// Issue #373: Lazily populated with the value of #rawStanza
@Nullable
private final Message stanza;
private Message stanza;

@Nullable
// Issue #373: Lazily populates #stanza
private String rawStanza;

public ArchivedMessage(@Nullable final Long id, @Nonnull final Date time, @Nonnull final Direction direction, @Nonnull final JID with, @Nullable final String body, @Nullable final String stanza) throws DocumentException {
this.id = id;
Expand All @@ -85,27 +90,9 @@ public ArchivedMessage(@Nullable final Long id, @Nonnull final Date time, @Nonnu
this.with = with;
this.body = body;

if ( stanza != null && stanza.length() > 0 ) {
Message stanzaResult;
try {
final Document doc = DocumentHelper.parseText( stanza );
stanzaResult = new Message( doc.getRootElement() );
} catch (DocumentException de) {
Log.debug("Unable to parse (non-empty) stanza (id: {})", id, de);
stanzaResult = null;
}
this.stanza = stanzaResult;
} else {
this.stanza = null;
}

if ( this.stanza != null && !OF1804_DISABLE.getValue() )
{
// Prior to OF-1804 (Openfire 4.4.0), the stanza was logged with a formatter applied.
// This causes message formatting to be modified (notably, new lines could be altered).
// This workaround restores the original body text, that was stored in a different column.
this.stanza.setBody( body );
}
// Issue #373: Do not parse the stanza now, as this incurs quite a bit of resource usage. This constructor is
// often called when a database resource is held. It is desirable to release that database resource as soon as possible.
this.rawStanza = stanza;
}

/**
Expand Down Expand Up @@ -159,7 +146,41 @@ public String getBody() {
*/
@Nullable
public Message getStanza() {
return stanza;
if (this.stanza != null) {
// Return lazily-loaded stanza
return this.stanza;
}

if (rawStanza == null || rawStanza.isEmpty()) {
// There is no data to lazily load.
return null;
}

synchronized (this) {
// Issue #373: Lazily load stanza from rawStanza. This can be resource intensive. Guarded with mutex to prevent duplicate execution.
Message stanzaResult;
try {
final Document doc = DocumentHelper.parseText(rawStanza);
stanzaResult = new Message(doc.getRootElement());
} catch (DocumentException de) {
Log.debug("Unable to parse (non-empty) stanza (id: {})", id, de);
stanzaResult = null;
}
this.stanza = stanzaResult;

if (this.stanza != null && !OF1804_DISABLE.getValue())
{
// Prior to OF-1804 (Openfire 4.4.0), the stanza was logged with a formatter applied.
// This causes message formatting to be modified (notably, new lines could be altered).
// This workaround restores the original body text, that was stored in a different column.
this.stanza.setBody( body );
}

// Prevent data duplication: Remove the now-processed raw data.
this.rawStanza = null;
}

return this.stanza;
}

/**
Expand All @@ -185,12 +206,13 @@ public JID getWith() {
@Nullable
public String getStableId(final JID owner)
{
if (this.stanza == null) {
final Message stanza = getStanza();
if (stanza == null) {
return null;
}

try {
return StanzaIDUtil.findFirstUniqueAndStableStanzaID(this.stanza, owner.toBareJID());
return StanzaIDUtil.findFirstUniqueAndStableStanzaID(stanza, owner.toBareJID());
} catch (Exception e) {
Log.warn("An exception occurred while parsing message with ID {}", id, e);
return null;
Expand Down

0 comments on commit 25de93f

Please sign in to comment.