Shared session usage in AEM 6.3 (oh no, not again!) | Community
Skip to main content
etugarev
Level 2
March 1, 2018

Shared session usage in AEM 6.3 (oh no, not again!)

  • March 1, 2018
  • 2 replies
  • 8160 views

For our client we are developing a specific health check which analyses a page output traversing the tree of child pages.

I am aware that a shared session usage is a well known anti-pattern (https://cqdump.wordpress.com/2015/03/02/aem-scaling-patterns-avoid-shared-sessions/ and https://github.com/joerghoh/cqdump/blob/master/examples/bundle/src/main/java/de/joerghoh/cq5/examples/oak/services/impl/GoodConfigurationServiceImpl.java) in AEM and keeping this in mind I created this code:

Assuming that I have a list of nodes to check:

for (Node node : nodes) {

  Future f = completionService.submit(testResultFunction(node.getPath()));
  futures.add(f);
}

...

private Callable<String> testResultFunction(final String nodePath) {

   return () -> Templates.serviceResourceResolverFunction(Constants.ServiceUsers.READ_SERVICE,
   resourceResolverFactory, resourceResolver -> {

     String result = requestService.doGet(checkedPageUrl, resourceResolver).getContent();
     ...

     return result;
   });
}

Templates.serviceResourceResolverFunction() looks like this:

public static <R> R serviceResourceResolverFunction(String serviceName, @Nonnull ResourceResolverFactory resourceResolverFactory,
   @Nonnull Function<ResourceResolver, R> function) {

  Map<String, Object> map = Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, serviceName);
  ResourceResolver resolver = null;
 

  try {

   resolver = resourceResolverFactory.getServiceResourceResolver(map);
     return function.apply(resolver);
  } catch (LoginException e) {

    LOG.error("Access denied", e);
    return null;
  } finally {

    if (resolver != null && resolver.isLive()) {

     resolver.close();
    }

  }

}

I am receiving an output which forces me to scratch my head over and over again:

01.03.2018 15:51:00.880 *WARN* [ForkJoinPool-2-worker-1] org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate Attempted to perform hasProperty while thread ForkJoinPool-2-worker-2 was concurrently writing to this session. Blocked until the other thread finished using this session. Please review your code to avoid concurrent use of a session. ...and so on...

In debugger i see that I receive  a new resourceResolver per every request made, and I am not writing anything to the session (?!), so I can only wonder what's the problem here.

Any help will be much appreciated!

Edited 09.03.2018 by Evgeny Tugarev

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

2 replies

kautuk_sahni
Community Manager
Community Manager
April 9, 2018

Jörg Hoh​ can you help this memebr?

Kautuk Sahni
joerghoh
Adobe Employee
Adobe Employee
April 9, 2018

It is indeed not obvious from this code, what code is actually writing to these sessions. Can you enable write logging /[1]) and post the results? From the details what is written it should be possible to deduce the location of the code.

[1] What is writing to my Oak repository? | Things on a content management system

Jörg

etugarev
etugarevAuthor
Level 2
April 9, 2018

Thanks for looking onto this issue. Here's the debug info:

error.log:

09.04.2018 12:00:09.818 *WARN* [ForkJoinPool-1-worker-5] org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate Attempted to perform hasProperty while thread ForkJoinPool-1-worker-0 was concurrently writing to this session. Blocked until the other thread finished using this session. Please review your code to avoid concurrent use of a session.

trace.log:

09.04.2018 12:00:09.818 *TRACE* [ForkJoinPool-1-worker-0] org.apache.jackrabbit.oak.jcr.operations.writes [session-2713] refresh

09.04.2018 12:00:09.818 *TRACE* [ForkJoinPool-1-worker-0] org.apache.jackrabbit.oak.jcr.operations.writes [session-96801] refresh

09.04.2018 12:00:09.818 *TRACE* [ForkJoinPool-1-worker-0] org.apache.jackrabbit.oak.jcr.operations.writes [session-96802] refresh

09.04.2018 12:00:09.818 *TRACE* [ForkJoinPool-1-worker-5] org.apache.jackrabbit.oak.jcr.operations.writes [session-2713] refresh

09.04.2018 12:00:09.818 *TRACE* [ForkJoinPool-1-worker-5] org.apache.jackrabbit.oak.jcr.operations.writes [session-96801] refresh

09.04.2018 12:00:09.818 *TRACE* [ForkJoinPool-1-worker-5] org.apache.jackrabbit.oak.jcr.operations.writes [session-96802] refresh

09.04.2018 12:00:09.818 *TRACE* [ForkJoinPool-1-worker-3] org.apache.jackrabbit.oak.jcr.operations.writes [session-2713] refresh

09.04.2018 12:00:09.818 *TRACE* [ForkJoinPool-1-worker-3] org.apache.jackrabbit.oak.jcr.operations.writes [session-96801] refresh

09.04.2018 12:00:09.819 *TRACE* [ForkJoinPool-1-worker-3] org.apache.jackrabbit.oak.jcr.operations.writes [session-96802] refresh

Now this is a total mystery, a thread is refreshing several (?!) sessions... also, I expected that every thread to have a unique session after calling to resourceResolverFactory.getServiceResourceResolver().

etugarev
etugarevAuthor
Level 2
April 11, 2018

I have never attempted to loop through many nodes and opening a session for each node. Therefore i am not sure if these log messages are normal. I recommend following Joerg's suggestion of placing a bundle on Google drive so community can test.


Thank you both for a quick feedback. I will start preparing a bundle and will update the thread as soon as I am done (in a next few days).