Uploaded image for project: 'Weld'
  1. Weld
  2. WELD-865

Weld allows for concurrent call to conversation

    Details

      Description

      Concurrent calls to a @ConversationScoped component:

      Thread 1:

      AbstractConversationContext.activate(String cid)
      ConversationImpl.lock(long timeout) <-- returns true

      correctly proceed inside method

      Thread 2:

      AbstractConversationContext.activate(String cid)
      ConversationImpl.lock(long timeout) <-- returns false but activate() does not check result !!!

      incorrectly proceed inside method


      I think AbstractConversationContext.activate(String cid) should check the result of ConversationImpl.lock(long timeout) and not allow the second thread to proceed.

        Gliffy Diagrams

        1. untested-2.patch
          13 kB
          George Sapountzis
        2. untested-3.patch
          8 kB
          George Sapountzis
        3. untested-test-failure-condition-first.patch
          8 kB
          George Sapountzis

          Activity

          Hide
          gsapountzis George Sapountzis added a comment -

          From BusyConversationException javadoc:

          Indicates that the container has rejected a request because a concurrent request is associated with the same conversation context.

          The container ensures that a long-running conversation may be associated with at most one request at a time, by blocking or rejecting concurrent requests. If the container rejects a request, it must associate the request with a new transient conversation and throw an exception of type BusyConversationException from the restore view phase of the JSF lifecycle.

          So I think that AbstractConversationContext.activate() should throw BusyConversationException which should caught, handled and re-thrown in WeldPhaseListener. Something like:

          try
          {
          conversationContext.activate(cid);
          }
          catch(BusyConversationException bce)
          {
          conversationContext.deactivate(); // XXX what else here ?
          throw bce;
          }
          }

          Show
          gsapountzis George Sapountzis added a comment - From BusyConversationException javadoc: Indicates that the container has rejected a request because a concurrent request is associated with the same conversation context. The container ensures that a long-running conversation may be associated with at most one request at a time, by blocking or rejecting concurrent requests. If the container rejects a request, it must associate the request with a new transient conversation and throw an exception of type BusyConversationException from the restore view phase of the JSF lifecycle. So I think that AbstractConversationContext.activate() should throw BusyConversationException which should caught, handled and re-thrown in WeldPhaseListener. Something like: try { conversationContext.activate(cid); } catch(BusyConversationException bce) { conversationContext.deactivate(); // XXX what else here ? throw bce; } }
          Hide
          alesj Ales Justin added a comment -

          I'm now throwing BusyConversationException.
          I'll think about the XXX and other things we need to handle.

          Show
          alesj Ales Justin added a comment - I'm now throwing BusyConversationException. I'll think about the XXX and other things we need to handle.
          Hide
          alesj Ales Justin added a comment -

          The lock check is in place,
          but per-spec behavior will be implemented later.

          Show
          alesj Ales Justin added a comment - The lock check is in place, but per-spec behavior will be implemented later.
          Hide
          gsapountzis George Sapountzis added a comment -

          What about locking first (i.e. testing the failure condition) and then deciding which conversation to activate ?

          The attached patch does this but is untested, the naming could be better or we could call activateRequest() from WeldPhaseListener ...

          Show
          gsapountzis George Sapountzis added a comment - What about locking first (i.e. testing the failure condition) and then deciding which conversation to activate ? The attached patch does this but is untested, the naming could be better or we could call activateRequest() from WeldPhaseListener ...
          Hide
          gsapountzis George Sapountzis added a comment -
          • slightly better naming
          • move the non-existent conversation check within conversationContext.activate(cid) where it seems to fit better with the flow
          Show
          gsapountzis George Sapountzis added a comment - slightly better naming move the non-existent conversation check within conversationContext.activate(cid) where it seems to fit better with the flow
          Hide
          gsapountzis George Sapountzis added a comment -

          rebase & reformat

          Show
          gsapountzis George Sapountzis added a comment - rebase & reformat
          Hide
          alesj Ales Justin added a comment -

          Patch #3 applied.

          Show
          alesj Ales Justin added a comment - Patch #3 applied.

            People

            • Assignee:
              alesj Ales Justin
              Reporter:
              gsapountzis George Sapountzis
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development