From b5a25801b4d760fa21b4424923e542b3b80dff0d Mon Sep 17 00:00:00 2001 From: jrandom <jrandom> Date: Fri, 28 Oct 2005 22:26:47 +0000 Subject: [PATCH] 2005-10-26 jrandom * In Syndie, propogate the subject and tags in a reply, and show the parent post on the edit page for easy quoting. (thanks identiguy and CofE!) * Streamline some netDb query handling to run outside the jobqueue - which means they'll run on the particular SSU thread that handles the message. This should help out heavily loaded netDb peers. --- .../java/src/net/i2p/i2ptunnel/I2PTunnel.java | 2 + .../net/i2p/i2ptunnel/I2PTunnelIRCClient.java | 124 +++++++++--------- .../i2p/syndie/sml/HTMLPreviewRenderer.java | 2 + .../src/net/i2p/syndie/sml/HTMLRenderer.java | 61 ++++++--- .../net/i2p/syndie/web/ArchiveViewerBean.java | 7 + .../java/src/net/i2p/syndie/web/PostBean.java | 12 ++ apps/syndie/jsp/post.jsp | 21 +++ history.txt | 9 +- .../src/net/i2p/router/InNetMessagePool.java | 4 + .../src/net/i2p/router/RouterVersion.java | 4 +- .../router/message/GarlicMessageBuilder.java | 4 +- ...FloodfillDatabaseLookupMessageHandler.java | 9 +- .../FloodfillDatabaseStoreMessageHandler.java | 8 +- 13 files changed, 180 insertions(+), 87 deletions(-) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java index ce0ef76313..b96454b4e3 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java @@ -240,6 +240,8 @@ public class I2PTunnel implements Logging, EventDispatcher { runClient(args, l); } else if ("httpclient".equals(cmdname)) { runHttpClient(args, l); + } else if ("ircclient".equals(cmdname)) { + runIrcClient(args, l); } else if ("sockstunnel".equals(cmdname)) { runSOCKSTunnel(args, l); } else if ("config".equals(cmdname)) { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java index 1e5fb7ab99..e4a5a957fc 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java @@ -1,8 +1,6 @@ package net.i2p.i2ptunnel; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.net.Socket; import java.util.ArrayList; import java.util.List; @@ -139,41 +137,43 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable } if (_log.shouldLog(Log.DEBUG)) _log.debug("IrcInboundFilter: Running."); - while(true) - { - try { - String inmsg = DataHelper.readLine(input); - if(inmsg==null) - break; - if(inmsg.endsWith("\r")) - inmsg=inmsg.substring(0,inmsg.length()-1); - String outmsg = inboundFilter(inmsg); - if(outmsg!=null) - { - if(!inmsg.equals(outmsg)) { - if (_log.shouldLog(Log.WARN)) { - _log.warn("inbound FILTERED: "+outmsg); - _log.warn(" - inbound was: "+inmsg); + try { + while(true) + { + try { + String inmsg = DataHelper.readLine(input); + if(inmsg==null) + break; + if(inmsg.endsWith("\r")) + inmsg=inmsg.substring(0,inmsg.length()-1); + String outmsg = inboundFilter(inmsg); + if(outmsg!=null) + { + if(!inmsg.equals(outmsg)) { + if (_log.shouldLog(Log.WARN)) { + _log.warn("inbound FILTERED: "+outmsg); + _log.warn(" - inbound was: "+inmsg); + } + } else { + if (_log.shouldLog(Log.INFO)) + _log.info("inbound: "+outmsg); } + outmsg=outmsg+"\n"; + output.write(outmsg.getBytes()); } else { - if (_log.shouldLog(Log.INFO)) - _log.info("inbound: "+outmsg); + if (_log.shouldLog(Log.WARN)) + _log.warn("inbound BLOCKED: "+inmsg); } - outmsg=outmsg+"\n"; - output.write(outmsg.getBytes()); - } else { + } catch (IOException e1) { if (_log.shouldLog(Log.WARN)) - _log.warn("inbound BLOCKED: "+inmsg); + _log.warn("IrcInboundFilter: disconnected",e1); + break; } - } catch (IOException e1) { - if (_log.shouldLog(Log.ERROR)) - _log.error("IrcInboundFilter: disconnected",e1); - break; } - } - try { - local.close(); - } catch (IOException e) { + } catch (RuntimeException re) { + _log.error("Error filtering inbound data", re); + } finally { + if (local != null) try { local.close(); } catch (IOException e) {} } if(_log.shouldLog(Log.DEBUG)) _log.debug("IrcInboundFilter: Done."); @@ -207,41 +207,43 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable } if (_log.shouldLog(Log.DEBUG)) _log.debug("IrcOutboundFilter: Running."); - while(true) - { - try { - String inmsg = DataHelper.readLine(input); - if(inmsg==null) - break; - if(inmsg.endsWith("\r")) - inmsg=inmsg.substring(0,inmsg.length()-1); - String outmsg = outboundFilter(inmsg); - if(outmsg!=null) - { - if(!inmsg.equals(outmsg)) { - if (_log.shouldLog(Log.WARN)) { - _log.warn("outbound FILTERED: "+outmsg); - _log.warn(" - outbound was: "+inmsg); + try { + while(true) + { + try { + String inmsg = DataHelper.readLine(input); + if(inmsg==null) + break; + if(inmsg.endsWith("\r")) + inmsg=inmsg.substring(0,inmsg.length()-1); + String outmsg = outboundFilter(inmsg); + if(outmsg!=null) + { + if(!inmsg.equals(outmsg)) { + if (_log.shouldLog(Log.WARN)) { + _log.warn("outbound FILTERED: "+outmsg); + _log.warn(" - outbound was: "+inmsg); + } + } else { + if (_log.shouldLog(Log.INFO)) + _log.info("outbound: "+outmsg); } + outmsg=outmsg+"\n"; + output.write(outmsg.getBytes()); } else { - if (_log.shouldLog(Log.INFO)) - _log.info("outbound: "+outmsg); + if (_log.shouldLog(Log.WARN)) + _log.warn("outbound BLOCKED: "+"\""+inmsg+"\""); } - outmsg=outmsg+"\n"; - output.write(outmsg.getBytes()); - } else { + } catch (IOException e1) { if (_log.shouldLog(Log.WARN)) - _log.warn("outbound BLOCKED: "+"\""+inmsg+"\""); + _log.warn("IrcOutboundFilter: disconnected",e1); + break; } - } catch (IOException e1) { - if (_log.shouldLog(Log.ERROR)) - _log.error("IrcOutboundFilter: disconnected",e1); - break; } - } - try { - remote.close(); - } catch (IOException e) { + } catch (RuntimeException re) { + _log.error("Error filtering outbound data", re); + } finally { + if (remote != null) try { remote.close(); } catch (IOException e) {} } if (_log.shouldLog(Log.DEBUG)) _log.debug("IrcOutboundFilter: Done."); diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLPreviewRenderer.java b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLPreviewRenderer.java index 51085cf087..ff1d435862 100644 --- a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLPreviewRenderer.java +++ b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLPreviewRenderer.java @@ -145,4 +145,6 @@ public class HTMLPreviewRenderer extends HTMLRenderer { _postBodyBuffer.append("</td>\n</form>\n</tr>\n"); _postBodyBuffer.append("</table>\n"); } + + protected void renderMetaCell() { _preBodyBuffer.append("<td></td></tr>"); } } diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java index 1c2648f45d..b3e403c702 100644 --- a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java +++ b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java @@ -754,6 +754,7 @@ public class HTMLRenderer extends EventReceiverImpl { public static final String HEADER_IN_REPLY_TO = "InReplyTo"; public static final String HEADER_STYLE = "Style"; public static final String HEADER_PETNAME = "PetName"; + public static final String HEADER_TAGS = "Tags"; private void renderSubjectCell() { _preBodyBuffer.append("<form action=\"index.jsp\">"); @@ -774,20 +775,7 @@ public class HTMLRenderer extends EventReceiverImpl { _preBodyBuffer.append((bgcolor != null ? " bgcolor=\"" + sanitizeTagParam(bgcolor) + "\"" : "") + ">"); } - private void renderMetaCell() { - String tags[] = (_entry != null ? _entry.getTags() : null); - _preBodyBuffer.append("<td nowrap=\"nowrap\" align=\"right\" valign=\"top\" "); - _preBodyBuffer.append(getClass("meta")).append(">\n"); - - PetName pn = null; - if ( (_entry != null) && (_user != null) ) - pn = _user.getPetNameDB().getByLocation(_entry.getURI().getKeyHash().toBase64()); - //if (knownName != null) - // _preBodyBuffer.append("Pet name: ").append(sanitizeString(knownName)).append(" "); - - BlogInfo info = null; - if (_entry != null) - info = _archive.getBlogInfo(_entry.getURI()); + private void renderMetaPetname(PetName pn, BlogInfo info) { if (info != null) { _preBodyBuffer.append("<a ").append(getClass("metaLink")).append(" href=\"").append(getMetadataURL()).append("\">"); if (pn != null) { @@ -803,7 +791,23 @@ public class HTMLRenderer extends EventReceiverImpl { } else { _preBodyBuffer.append(getSpan("metaUnknown")).append("[unknown blog]</span>"); } + } + + protected void renderMetaCell() { + String tags[] = (_entry != null ? _entry.getTags() : null); + _preBodyBuffer.append("<td nowrap=\"nowrap\" align=\"right\" valign=\"top\" "); + _preBodyBuffer.append(getClass("meta")).append(">\n"); + + PetName pn = null; + if ( (_entry != null) && (_user != null) ) + pn = _user.getPetNameDB().getByLocation(_entry.getURI().getKeyHash().toBase64()); + //if (knownName != null) + // _preBodyBuffer.append("Pet name: ").append(sanitizeString(knownName)).append(" "); + BlogInfo info = null; + if (_entry != null) + info = _archive.getBlogInfo(_entry.getURI()); + renderMetaPetname(pn, info); if ( (_user != null) && (_user.getAuthenticated()) && (_entry != null) ) { if ( (pn == null) || (!pn.isMember("Favorites")) ) @@ -857,7 +861,19 @@ public class HTMLRenderer extends EventReceiverImpl { if ( (_user != null) && (_user.getAuthenticated()) ) { _preBodyBuffer.append(" <a ").append(getClass("replyLink")); - _preBodyBuffer.append(" href=\"").append(getPostURL(_user.getBlog(), true)).append("\">Reply</a>\n"); + String subject = (String)_headers.get(HEADER_SUBJECT); + if (subject != null) { + if (!subject.startsWith("re:")) + subject = "re: " + subject; + } else { + subject = "re: "; + } + StringBuffer tagStr = new StringBuffer(32); + if ( (tags != null) && (tags.length > 0) ) + for (int i = 0; i < tags.length; i++) + tagStr.append(tags[i]).append('\t'); + String replyURL = getPostURL(_user.getBlog(), true, subject, tagStr.toString()); + _preBodyBuffer.append(" href=\"").append(replyURL).append("\">Reply</a>\n"); } _preBodyBuffer.append("\n</td>"); _preBodyBuffer.append("</tr>\n"); @@ -984,11 +1000,18 @@ public class HTMLRenderer extends EventReceiverImpl { public static String getPostURL(Hash blog) { return "post.jsp?" + ArchiveViewerBean.PARAM_BLOG + "=" + Base64.encode(blog.getData()); } - public String getPostURL(Hash blog, boolean asReply) { + public String getPostURL(Hash blog, boolean asReply, String subject, String tags) { if (asReply && _entry != null) { - return "post.jsp?" + ArchiveViewerBean.PARAM_BLOG + "=" + Base64.encode(blog.getData()) - + "&" + ArchiveViewerBean.PARAM_IN_REPLY_TO + '=' - + Base64.encode("entry://" + _entry.getURI().getKeyHash().toBase64() + "/" + _entry.getURI().getEntryId()); + StringBuffer rv = new StringBuffer(128); + rv.append("post.jsp?").append(ArchiveViewerBean.PARAM_BLOG).append("=").append(Base64.encode(blog.getData())); + rv.append('&').append(ArchiveViewerBean.PARAM_IN_REPLY_TO).append('='); + rv.append(Base64.encode("entry://" + _entry.getURI().getKeyHash().toBase64() + "/" + _entry.getURI().getEntryId())); + if (subject != null) + rv.append('&').append(ArchiveViewerBean.PARAM_SUBJECT).append('=').append(Base64.encode(subject)); + if (tags != null) + rv.append('&').append(ArchiveViewerBean.PARAM_TAGS).append('=').append(Base64.encode(tags)); + rv.append('&').append(ArchiveViewerBean.PARAM_PARENT).append('=').append(Base64.encode(_entry.getURI().toString())); + return rv.toString(); } else { return getPostURL(blog); } diff --git a/apps/syndie/java/src/net/i2p/syndie/web/ArchiveViewerBean.java b/apps/syndie/java/src/net/i2p/syndie/web/ArchiveViewerBean.java index 9fc5112715..a724933c27 100644 --- a/apps/syndie/java/src/net/i2p/syndie/web/ArchiveViewerBean.java +++ b/apps/syndie/java/src/net/i2p/syndie/web/ArchiveViewerBean.java @@ -46,6 +46,13 @@ public class ArchiveViewerBean { /** we are replying to a particular blog/tag/entry/whatever (value == base64 encoded selector) */ public static final String PARAM_IN_REPLY_TO = "inReplyTo"; + /** prepopulate the subject field with the given value */ + public static final String PARAM_SUBJECT = "replySubject"; + /** prepopulate the tags with the given value */ + public static final String PARAM_TAGS = "replyTags"; + /** prepopulate the body with the given value */ + public static final String PARAM_PARENT = "parentURI"; + /** * Drop down multichooser: * blog://base64(key) diff --git a/apps/syndie/java/src/net/i2p/syndie/web/PostBean.java b/apps/syndie/java/src/net/i2p/syndie/web/PostBean.java index c274715b18..7506820c13 100644 --- a/apps/syndie/java/src/net/i2p/syndie/web/PostBean.java +++ b/apps/syndie/java/src/net/i2p/syndie/web/PostBean.java @@ -6,7 +6,9 @@ import net.i2p.I2PAppContext; import net.i2p.client.naming.PetName; import net.i2p.syndie.*; import net.i2p.syndie.data.BlogURI; +import net.i2p.syndie.data.EntryContainer; import net.i2p.syndie.sml.HTMLPreviewRenderer; +import net.i2p.syndie.sml.HTMLRenderer; import net.i2p.util.Log; /** @@ -137,6 +139,16 @@ public class PostBean { _previewed = true; } + public void renderReplyPreview(Writer out, String parentURI) throws IOException { + HTMLRenderer r = new HTMLRenderer(_context); + Archive a = BlogManager.instance().getArchive(); + BlogURI uri = new BlogURI(parentURI); + if (uri.getEntryId() > 0) { + EntryContainer entry = a.getEntry(uri); + r.render(_user, a, entry, out, false, true); + } + } + private String renderSMLContent() { StringBuffer raw = new StringBuffer(); raw.append("Subject: ").append(_subject).append('\n'); diff --git a/apps/syndie/jsp/post.jsp b/apps/syndie/jsp/post.jsp index 86c19d92a7..94cae9cca9 100644 --- a/apps/syndie/jsp/post.jsp +++ b/apps/syndie/jsp/post.jsp @@ -121,6 +121,21 @@ for (Iterator iter = names.iterator(); iter.hasNext(); ) { } else { // logged in and not confirmed because they didn't send us anything! // give 'em a new form + String entrySubject = request.getParameter("replySubject"); + String entryTags = request.getParameter("replyTags"); + String parentURI = request.getParameter("parentURI"); + if (entrySubject != null) + post.setSubject(new String(Base64.decode(entrySubject), "UTF-8")); + if (entryTags != null) + post.setTags(new String(Base64.decode(entryTags), "UTF-8")); + + if (parentURI != null) { + parentURI = new String(Base64.decode(parentURI), "UTF-8"); + %><span class="b_postField">Replying to + <a href="<%=HTMLRenderer.getPageURL(user, parentURI)%>">parent</a> + (text <a href="#parentText">below</a>).</span><br /> + <% + } %><form action="post.jsp" method="POST" enctype="multipart/form-data"> <span class="b_postField">Post subject:</span> <input class="b_postSubject" type="text" size="80" name="entrysubject" value="<%=post.getSubject()%>" /><br /> <span class="b_postField">Post tags:</span> <input class="b_postTags" type="text" size="20" name="entrytags" value="<%=post.getTags()%>" /><br /> @@ -164,6 +179,12 @@ if ( (s != null) && (s.trim().length() > 0) ) {%> <hr /> <input class="b_postPreview" type="submit" name="Post" value="Preview..." /> <input class="b_postReset" type="reset" value="Cancel" /> <% + if (parentURI != null) { + %><hr /><span id="parentText" class="b_postParent"><% + post.renderReplyPreview(out, parentURI); + %></span><hr /><% + } + } // end of the 'logged in, not confirmed, nothing posted' section } // end of the 'logged in, not confirmed' section } // end of the 'logged in' section diff --git a/history.txt b/history.txt index 6bcb51153e..3805714edb 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,11 @@ -$Id: history.txt,v 1.305 2005/10/22 13:06:03 jrandom Exp $ +$Id: history.txt,v 1.306 2005/10/25 14:13:54 jrandom Exp $ + +2005-10-26 jrandom + * In Syndie, propogate the subject and tags in a reply, and show the parent + post on the edit page for easy quoting. (thanks identiguy and CofE!) + * Streamline some netDb query handling to run outside the jobqueue - + which means they'll run on the particular SSU thread that handles the + message. This should help out heavily loaded netDb peers. 2005-10-25 jrandom * Defer netDb searches for newly referenced peers until we actually want diff --git a/router/java/src/net/i2p/router/InNetMessagePool.java b/router/java/src/net/i2p/router/InNetMessagePool.java index 63e1a01350..9962ae3a0e 100644 --- a/router/java/src/net/i2p/router/InNetMessagePool.java +++ b/router/java/src/net/i2p/router/InNetMessagePool.java @@ -168,6 +168,10 @@ public class InNetMessagePool implements Service { if (job != null) { _context.jobQueue().addJob(job); jobFound = true; + } else { + // ok, we may not have *found* a job, per se, but we could have, the + // job may have just executed inline + jobFound = true; } } } diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 7cf0ccd561..db0d48ecb0 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -15,9 +15,9 @@ import net.i2p.CoreVersion; * */ public class RouterVersion { - public final static String ID = "$Revision: 1.276 $ $Date: 2005/10/22 13:06:03 $"; + public final static String ID = "$Revision: 1.277 $ $Date: 2005/10/25 14:13:53 $"; public final static String VERSION = "0.6.1.3"; - public final static long BUILD = 7; + public final static long BUILD = 8; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID); diff --git a/router/java/src/net/i2p/router/message/GarlicMessageBuilder.java b/router/java/src/net/i2p/router/message/GarlicMessageBuilder.java index 76b109049b..74112481d9 100644 --- a/router/java/src/net/i2p/router/message/GarlicMessageBuilder.java +++ b/router/java/src/net/i2p/router/message/GarlicMessageBuilder.java @@ -34,7 +34,7 @@ public class GarlicMessageBuilder { return buildMessage(ctx, config, new SessionKey(), new HashSet()); } public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set wrappedTags) { - return buildMessage(ctx, config, wrappedKey, wrappedTags, 20); + return buildMessage(ctx, config, wrappedKey, wrappedTags, 50); } public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set wrappedTags, int numTagsToDeliver) { Log log = ctx.logManager().getLog(GarlicMessageBuilder.class); @@ -68,7 +68,7 @@ public class GarlicMessageBuilder { wrappedTags.add(new SessionTag(true)); if (log.shouldLog(Log.INFO)) log.info("Less than 10 tags are available (" + availTags + "), so we're including more"); - } else if (ctx.sessionKeyManager().getAvailableTimeLeft(key, curKey) < 30*1000) { + } else if (ctx.sessionKeyManager().getAvailableTimeLeft(key, curKey) < 60*1000) { // if we have > 10 tags, but they expire in under 30 seconds, we want more for (int i = 0; i < numTagsToDeliver; i++) wrappedTags.add(new SessionTag(true)); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java index 6ae7c9921c..888449953f 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java @@ -35,7 +35,14 @@ public class FloodfillDatabaseLookupMessageHandler implements HandlerJobBuilder _context.statManager().addRateData("netDb.lookupsReceived", 1, 0); if (true || _context.throttle().acceptNetDbLookupRequest(((DatabaseLookupMessage)receivedMessage).getSearchKey())) { - return new HandleFloodfillDatabaseLookupMessageJob(_context, (DatabaseLookupMessage)receivedMessage, from, fromHash); + Job j = new HandleFloodfillDatabaseLookupMessageJob(_context, (DatabaseLookupMessage)receivedMessage, from, fromHash); + if (true) { + // might as well inline it, all the heavy lifting is queued up in later jobs, if necessary + j.runJob(); + return null; + } else { + return j; + } } else { if (_log.shouldLog(Log.INFO)) _log.info("Dropping lookup request as throttled"); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseStoreMessageHandler.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseStoreMessageHandler.java index f0f1cc24a7..9250f93dbc 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseStoreMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseStoreMessageHandler.java @@ -29,6 +29,12 @@ public class FloodfillDatabaseStoreMessageHandler implements HandlerJobBuilder { _facade = facade; } public Job createJob(I2NPMessage receivedMessage, RouterIdentity from, Hash fromHash) { - return new HandleFloodfillDatabaseStoreMessageJob(_context, (DatabaseStoreMessage)receivedMessage, from, fromHash, _facade); + Job j = new HandleFloodfillDatabaseStoreMessageJob(_context, (DatabaseStoreMessage)receivedMessage, from, fromHash, _facade); + if (true) { + j.runJob(); + return null; + } else { + return j; + } } } -- GitLab