6 Replies Latest reply on Jan 2, 2009 6:54 PM by Clebert Suconic

    Non atomic issue with paging

    Tim Fox Master

      The way paging currently works, the isPaging() check is done first before the message is routed, then later the pagingStore.addSize() method is called.

      Since isPaging() and addSize() are not done together as an atomic operation, it is possible that many threads could call isPaging() at the same time and return false to all of them.

      Then later they all call addSize() and the system runs out of memory. To guarantee we don't run out of memory isPaging() and addSize() would have to be combined in a single atomic operation.

        • 1. Re: Non atomic issue with paging
          Clebert Suconic Master

          isPaging is used only on TransactionImpl. And we are not actually page if isPaging. We are just holding the message until commit is called, when we will actually call addSize and route the message again.

          This is because I can't page a message for a pending transaction. We don't have control when the commit will come (it could be waiting an user action).

          Later when commit is called, addSize is used, and the message will only go towards paging, if is in page mode.

          When we have the HugeTransactionSupport in place, that will be done in another thread.


          So, when the HugeTransaction is in place, when isPaging = true, we will delay the messages on another file, when commit is called we will transfer the temporary repository towards routing what could lead to paging.


          On the non-transactional use-case, we aways use addSize. Unless something was recently changed.

          • 2. Re: Non atomic issue with paging
            Clebert Suconic Master

            So, in summary, when we are actually paging, the only atomic operation you could use is addSize.

            isPaging will only give the current status of paging for the transaction use-case, but later when the commit is made, we need to verify routing & addSize again.

            • 3. Re: Non atomic issue with paging
              Clebert Suconic Master

               

              "timfox" wrote:

              Since isPaging() and addSize() are not done together as an atomic operation, it is possible that many threads could call isPaging() at the same time and return false to all of them.


              The way it works is...

              We aways call page(Message) before routing...

              if (!page(Message))
              {
              route();
              addSize(....);
              }

              addSize is what starts the page-mode, and addSize is only called after routing. Meaning that anything after that will be routed.

              You could eventually have simultaneous threads overlapping the maxSize... but I'm not sure if the cost of synchronizing this would be worth.

              We could maybe add another check on the last addSize. But i don't want to add any synchronization on this.


              I can double check this after Xmas.

              • 4. Re: Non atomic issue with paging
                Tim Fox Master

                 

                "clebert.suconic@jboss.com" wrote:

                You could eventually have simultaneous threads overlapping the maxSize... but I'm not sure if the cost of synchronizing this would be worth.


                Yes, that is what I was talking about, substitiute isPaging for page

                • 5. Re: Non atomic issue with paging
                  Clebert Suconic Master

                  With the previous route code that would be somewhat hard to do. I needed to start paging outside of routing.


                  But with the current routing code it would be simpler.


                  Paging will be done inside of routing after the refactoring I'm doing. That will only be possible with routing also treating transactions now.

                  • 6. Re: Non atomic issue with paging
                    Clebert Suconic Master

                    Actually.. this is a bit more complicated.

                    Paging happens before routing... not after.

                    We can't switch addSize by page, as that will happen at the queue level.

                    We would need to make PostOffice.route an atomic operation if you want that level of control over paging.

                    It will be easier to talk about this on IRC later.