[
https://jira.jboss.org/jira/browse/JBSEAM-3652?page=com.atlassian.jira.pl...
]
Dan Allen commented on JBSEAM-3652:
-----------------------------------
I thoroughly studied the attached cases as well as the existing unit tests and have
answers/responses to all of your questions.
You were correct that there was a bug in the counter logic. Both finally blocks were
decrementing the counter for the same invocation. I have changed it so that the first
finally block consults the value of the counter without changing the value. I also changed
the field name from "counter" to "client" to make it more apparent
that we are counting client threads.
Fixing the counter bug brings the other observations into focus. Let's take each test
scenario in turn.
Case 1: An instance of the page-scoped component exists at the time the user clicks on the
button to activate one of its methods. No long-running conversation exists.
If the page-scoped component is not synchronized, then each concurrent click will invoke
the same page-scoped component, but the conversation-scoped component will only be
injected on the first invocation since injection does not happen again until the component
has no more clients (invoking threads). That is why you only see one instance of the
conversation-scoped component and not one per click. If you add @Synchronized to the
page-scoped component, then each click is processed in turn, and then you have one
conversation-scoped component created and injected per click. Page-scoped components are
now synchronized by default.
Case 2: The page-scoped component is created when the user clicks on the link. No
long-running conversation exists.
In this case, a new page-scoped component created (and in turn a new conversation-scoped
component created and injected) per click. The reason is that Seam only flushes the page
context held in a thread local at the end of the request. Thus, even though you are
invoking a command button from the same view, the newly created page-scoped component is
not yet associated with that UI component tree. In this case, it's really like 6
different requests because none of the requests know that the other requests have also
created a page-scoped component.
Case 3: An instance of the page-scoped component exists at the time the user clicks on the
button to activate on of its methods. A long-running conversation is active.
In this case, a long-running conversation is active and Seam is serializing access to that
conversation. Therefore, the page-scoped component is naturally protected against
concurrent access. Essentially, access to the entire UI component tree is being serialized
by the conversation.
Case 4: The page-scoped component is created when the user clicks on the link, also
creating a long-running conversation.
Exactly the same explanation as Case #2.
Major reentrancy problem with "Page Scope" components and
injection/disinjection
--------------------------------------------------------------------------------
Key: JBSEAM-3652
URL:
https://jira.jboss.org/jira/browse/JBSEAM-3652
Project: Seam
Issue Type: Bug
Affects Versions: 2.0.2.SP1, 2.0.3.CR1, 2.1.0.GA
Environment: WebSphere v6.1.0.17 in POJO Mode
Reporter: Denis Forveille
Assignee: Dan Allen
Priority: Blocker
Fix For: 2.1.1.CR1
Attachments: Test3652.java, Test3652Conv.java, testJBSEAM3652.xhtml, traces.txt
This bug is very similar to the JBSEAM-3295 bug, but for "Page Scope"
components this time
Under stress, we have random NPE, "conversation expired" and other strange
eroors from time to time in production
This is due to a flaw in the "BijectionInterceptor" class and it is quite easy
to reproduce
On a facelets page, we have a datatable with a list of h:commadLink, teh first page of a
classic "list entities/showDetail" scheme. The controleur that manages the list
is in "Page Scope"
When the user clics on one of the link, then quickly clic on another link, another one
etc... without waiting for the detail view to show up, we have two concurrent request
addressed to the same Page Scope component (Verified by putting traces in the
BijectionInterceptor class)
In BijectionInterceptor, in that case, counter == 2 after line 77 meaning there is two
concurrent thread running: the current thread + another one currently "using"
the component
The counter will be decrease for the first time on line 82, then a second time on line
129 and so, disinjection will occur on line 134. This occurs while there is another thread
"using" the component, causing random NPE and other errors!!!!
In fact this will happen each time counter >1, ie there is more than one
"concurrent" request on the same component
This alleviate some questions:-
- is this normal that 2 (or more) concurrent request from the same user/conversation/page
acces the same page scope component concurrently (I thought seam was taking care of this
and was serializing such requests...
- is this normal that on line 88, components are outjected, only when the last concurrent
"user" of the component exits the interceptor and not when each request
"eixts" the interceptor?
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira