You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by "Bertrand Delacretaz (JIRA)" <ji...@apache.org> on 2015/11/19 22:02:10 UTC

[jira] [Resolved] (SLING-5261) Background servlets: use a separate session for captured output

     [ https://issues.apache.org/jira/browse/SLING-5261?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bertrand Delacretaz resolved SLING-5261.
----------------------------------------
    Resolution: Fixed

> Background servlets: use a separate session for captured output
> ---------------------------------------------------------------
>
>                 Key: SLING-5261
>                 URL: https://issues.apache.org/jira/browse/SLING-5261
>             Project: Sling
>          Issue Type: Bug
>          Components: Extensions
>    Affects Versions: Background Servlets 1.0.0
>            Reporter: Jörg Hoh
>            Assignee: Bertrand Delacretaz
>             Fix For: Background Servlets 1.0.2
>
>
> We use the bgservlet to perform batch actions on content in the background, decoupling it from the user request. We saw a case where these batch actions failed and also no log was written. We have lots of exceptions like this in the log:
> {noformat}
> 02.11.2015 23:50:32.264 *ERROR* [pool-5743-thread-3] com.day.cq.wcm.msm.impl.commands.RolloutCommand Trying to commit status change: {}
> java.io.IOException: RepositoryException in flush()
>         at org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream.flush(NodeOutputStream.java:103)
>         at org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream.flushIfNeeded(NodeOutputStream.java:110)
>         at org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream.write(NodeOutputStream.java:129)
>         at java.io.FilterOutputStream.write(FilterOutputStream.java:71)
>         at org.apache.sling.bgservlets.impl.SuspendableOutputStream.write(SuspendableOutputStream.java:65)
>         at org.apache.sling.bgservlets.BackgroundHttpServletResponse$ServletOutputStreamWrapper.write(BackgroundHttpServletResponse.java:47)
>         at javax.servlet.ServletOutputStream.print(ServletOutputStream.java:101)
>         at javax.servlet.ServletOutputStream.println(ServletOutputStream.java:252)
>      ...
> Caused by: javax.jcr.InvalidItemStateException: OakState0001: Unresolved conflicts in /content/foo/bar/jcr:content
>         at org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:237)
>         at org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:212)
>         at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.newRepositoryException(SessionDelegate.java:664)
>         at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegate.java:489)
>         at org.apache.jackrabbit.oak.jcr.session.SessionImpl$8.performVoid(SessionImpl.java:406)
>         at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.performVoid(SessionDelegate.java:268)
>         at org.apache.jackrabbit.oak.jcr.session.SessionImpl.save(SessionImpl.java:403)
>         at org.apache.sling.bgservlets.impl.DeepNodeCreator.deepCreateNode(DeepNodeCreator.java:60)
>         at org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream.flush(NodeOutputStream.java:92)
>         ... 134 common frames omitted
> Caused by: org.apache.jackrabbit.oak.api.CommitFailedException: OakState0001: Unresolved conflicts in /content/foo/bar/jcr:content
>         at org.apache.jackrabbit.oak.plugins.commit.ConflictValidator.failOnMergeConflict(ConflictValidator.java:115)
>         at org.apache.jackrabbit.oak.plugins.commit.ConflictValidator.propertyChanged(ConflictValidator.java:90)
>         at org.apache.jackrabbit.oak.spi.commit.CompositeEditor.propertyChanged(CompositeEditor.java:91)
>         at org.apache.jackrabbit.oak.spi.commit.EditorDiff.propertyChanged(EditorDiff.java:93)
>         at org.apache.jackrabbit.oak.spi.state.AbstractNodeState.comparePropertiesAgainstBaseState(AbstractNodeState.java:181)
>         at org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore.compare(DocumentNodeStore.java:1394)
>         at org.apache.jackrabbit.oak.plugins.document.DocumentNodeState.compareAgainstBaseState(DocumentNodeState.java:344)
>         at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)
>         at org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore.dispatch(DocumentNodeStore.java:2108)
>      ...
> {noformat}
> The exception happens when writing to the output stream (which is redirected to write to the repo somewhere below /var/bg), but it logs a conflict in /content.
> For me it looks like that the session which is attached to the user request is used for 2 different aspects:
> * processing the actions on the content
> * logging the output to the repository
> check the BackgroundRequestExecutionJob class, where the „resource resolver“ is used for both constructing the „response“ object and as parameter into the slingRequestProcessor.processRequest() call.
> For me it looks like if an repository exception happens on on the processing side, this effectively prevents the writing to the output stream as well (as seen by the path where this OakState0001 exception is being reported). I think, that the action doesn’t clear the JCR transient space after an exception which will cause any subsequent session.save() to fail as well.
> While we could consider this as a problematic case in the handling of the request itself, the bgservlets should at least be capable to store any issue written to the output stream successfully in the repository. So a dedicated session to write the output would be very good to have.
> But there is also a different problem with the current implementation: When the request fills the transient space and does call session.save() yet, but rather writes to the outpustream, it might be case that the bgservlets do the session.save(), thus saving the transient space created by the regular execution as well.
> So I suggest this patch:
> {noformat}
> Index: BackgroundRequestExecutionJob.java
> ===================================================================
> --- BackgroundRequestExecutionJob.java    (revision 1710381)
> +++ BackgroundRequestExecutionJob.java    (working copy)
> @@ -50,6 +50,7 @@
>      private final BackgroundHttpServletResponse response;
>      private final SuspendableOutputStream stream;
>      private final ResourceResolver resourceResolver;
> +    private final ResourceResolver bgResponseResolver;
>      private final SlingRequestProcessor slingRequestProcessor;
>      private final String path;
>      private final String streamPath;
> @@ -72,8 +73,11 @@
>          // current request, for the background request.
>          resourceResolver = request.getResourceResolver().clone(null);
> +    // create a dedicated session for the response object
> +    bgResponseResolver = request.getResourceResolver().clone(null);
> +
>          // Get JobData, defines path and used to save servlet output to the repository
> -        final Session s = resourceResolver.adaptTo(Session.class);
> +        final Session s = bgResponseResolver.adaptTo(Session.class);
>          if(s == null) {
>              throw new IOException("Unable to get Session from ResourceResolver " + resourceResolver);
>          }
> @@ -110,6 +114,8 @@
>              // cleanup the resource resolver
>              resourceResolver.close();
> +        bgResponseResolver.close();
> +
>          }
>      }
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)