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

Joerg Hoh closed SLING-5261.
----------------------------

> 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: Joerg Hoh
>            Assignee: Bertrand Delacretaz
>            Priority: Major
>             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
(v8.20.1#820001)

Reply via email to