1 2 Previous Next 25 Replies Latest reply on Dec 8, 2005 12:15 AM by ovidiu.feodorov Go to original post
      • 15. Re: Context of MessageStore design task

         

        "adrian@jboss.org" wrote:

        Mulitple repositories/persistent stores, e.g. message bridging
        (JTA)Transaction tx = (JTA)TransactionManager.begin();
        tx.enlistResource(fromRepository);
        // receive
        tx.enlistResource(toRepository);
        // add
        tx.commit(); --> does 2PC via JTA
        


        This is a "nice to have". Since it avoids the MessageCore having to drop
        into the JMS api to get at the XAResource.

        • 16. Re: Context of MessageStore design task
          timfox

          Guys.

          I think there is a certain amount of confusion here as to the scope of the task.

          What Adrian is describing is mainly the responsibility of the persistence manager (similar to the persistence manager in jbossmq).

          This is already almost completely done with the exception of the some of the recovery stuff, which is handled in a separate JIRA task. It's actually quite similar to the JBossMQ version.

          My understanding is that Alex's task is to finish off the last part of the message store which is missing - how messages are evicted and re-instated to the store when memory is low/high.

          Currently we're not evicting them at all when memory gets low.

          This shouldn't require any knowledge of transactions. These are handled elsewhere.

          PersistenceManager, MessageStore, Lazy Loading queues are all currently treated as separate, separable tasks.


          • 17. Re: Context of MessageStore design task
            alexfu.novell

             

            Transaction tx = repository.begin(XID);
            // do the work
            // return our vote
            return tx.prepare();
            

            So I need to implement Transaction, right? And since we call commit/prepare/rollback on tx, we no longer need the following API
            void rollback(Transaction tx);
            commit(Transaction tx);
            

            in TransactionRepository.


            • 18. Re: Context of MessageStore design task

               

              "timfox" wrote:

              My understanding is that Alex's task is to finish off the last part of the message store which is missing - how messages are evicted and re-instated to the store when memory is low/high.


              And like I said before. This can/should be done with the persistence manager
              which is best placed to do it.

              Indeed. In JBossMQ the implementation (interface CacheStore) is merged
              with the PersistenceManager

              public class PersistenceManager extends ServiceMBeanSupport
               implements PersistenceManagerMBean, org.jboss.mq.pm.PersistenceManager, CacheStore
              


              • 19. Re: Context of MessageStore design task
                ovidiu.feodorov

                I am trying to summarize the discussion one more time, as I see it diverging again.

                First of all let's get rid of lazy loading queues discussions from this thread. It has nothing to do with the MessageStore, or at least not more than discussing an unoptimized queue has to do with it. It is nothing more than an optimization which is nice to have (and for some very specific use cases is critical to have) but lets not mix concerns. If you want, we can start another thread and discuss it there ad nauseam.

                We want to discuss the MessageStore, interface and implementation.

                The way I originally designed it, the MessageStore has pretty much one functionality: to reference and dereference messages. A MessageStore gets a Message and returns a MessageReference and vice-versa: it gets a MessageReference and returns the associated Message. This is all. The rationale is the necessity of relieving the channels from dealing with message bodies, which have a large memory footprint and are irrelevant for routing. The MessageReferences created by the MessageStore is further handed over to the channels and they either synchronously forward them to other receivers or keep them in their state. A channel doesn't care about how a MessageStore works.

                Of course, a particular MessageStore implementation could employ optimizations, such as spill-over, to prevent the VM from throwing OutOfMemory when too many undelivered messages accumulate, but this shouldn't affect the interface at all. Is an implementation issue and we can dream up a hundred different implementations for that.


                The primary purpose of the message store (ignore all the other features) is to be a recoverable transaction log.


                Adrian, it seems that you're mixing the concept of MessageStore with the one of channel state. In the current implementation, each channel has a state (see org.jboss.messaging.core.State, org.jboss.messaging.core.NonRecoverableState, org.jboss.messaging.core.RecoverableState) that 1) only stores MessageReferences and 2) does this transactionally or non-transactionally, depending on how the add() call is made. 3) can be recovered in case of failure. The channel state provide a recoverable transactional log (by the way, this is where the lazy loading queue support should be implemented). The transaction repository you were previously talking about in the thread is org.jboss.messaging.core.tx.TransactionRepository. We can probably modify the State interface to getTransactionRepository() but again, let's not mix concerns.


                Current issues do discuss about the MessageStore:

                1. We have an interface for it (org.jboss.messaging.core.MessageStore), we need to decide if it's good enough.

                2. We need to come up with a new default implementation (which should include spillover, since the current default implementation org.jboss.messaging.core.message.InMemoryMessageStore / org.jboss.messaging.core.message.PersistentMessageStore doesn't and that's why we are not happy with it)

                3. In doing so, we have to consider using the old JBossMQ spilover algorithm, using TreeCache or doing something completely new, or a combination of all of these.

                4. We need to define and implement configuration hooks required to declaratively swap a MessageStore implementation.

                5. While we're at it, we also have to consider replication, since it's far more effective to send references over the network than full messages if the messages are already stored in a shared database

                Let's see if all agree up to here, and then we'll go forward with discussion each point one by one. I'll make this thread my highest priority and I will manage it until everybody agrees on all issues.


                • 20. Re: Context of MessageStore design task

                  Ok, it sounds like we are at cross purposes.
                  But let me finish the argument before I explain why that is not necessarily so.

                  The "transaction log" is the core of the system.

                  If you don't get this correct, you might as well not bother and implement JMS with arraylists and threads :-)

                  It exists as a server wide object you can't have two transaction logs and get reliablity
                  without doing external 2PC with an additional recovery log

                  There is no such thing as a subscription local transaction.

                  There are such a things as
                  subscriptions (temporary destinations/non durable subscriptions) and
                  messages (non-persistent)
                  that don't have transaction reliablity.

                  i.e. they don't survive crashes and you don't need to extra work for them.

                  But if they handled in a transaction they still have transaction semantics. i.e. they don't magically appear/disappear until any transaction commits.

                  This transaction log should be (that is usually the best way) write ahead.
                  i.e. It should say.

                  * Write to disk - this is what I am going to do (prepare)
                  * Commit the changes - i.e. ensure the info will survive a crash
                  * Then actually do it (commit)

                  This prepare/commit is regardless of any external 2PC.
                  For local jms tx it can be optimized and there are all sorts of other tricks
                  I want to discuss down the road, but it must behave like the protocol above.

                  • 21. Re: Context of MessageStore design task

                    So the question is about messages references and avoiding OutOfMemoryError.
                    Which you call the MessageStore.

                    In JBossMQ this is called the MessageCache which delegates to the CacheStore
                    (in practice also the PersistenceManager).

                    I said before that this is a stupid idea. Stupid as in dumb. Having a global
                    cache doesn't allow you do any finegrained optimization based on usecase, subscription,
                    etc.

                    Instead, it is better to have an internal more targetted implementation
                    which I called Subscription (just because that is the name for topics).

                    This is linked by a private protocol to the PersistenceManager
                    (which is probably also a bad name for it).
                    You then configure the PM with policies and implementation to do what you want
                    with more fine grained control.

                    Why is PersistenceManager a bad name?
                    Because it is really a "subscription factory" which is backed by the transaction log.

                    Calling it the persistence manager and having an implementation that runs queries
                    over a database gives the impression that it is a live source of data.
                    It isn't.
                    Unless it has knowledge of the in memory state of the "subscription"
                    as well, it is just a write ahead log.

                    The fact that you can query the database tables for the "current state" is an
                    illusion and misleading. :-)

                    Finally, the other reason why the PM/Subscription to replace the MessageStore
                    is because it should be the factory for the MessageReferences.
                    Only it knows that when the channel does
                    subscription.getFirst()
                    that it actually moved the entire subscription onto disk and needs to go find it again. :-)

                    • 22. Re: Context of MessageStore design task

                      Since it is the third time I've given this opinion, I won't beat a dead horse.

                      You are free to ignore me, and I won't even say "I told you so" a few months down the line :-)

                      • 23. Re: Context of MessageStore design task
                        ovidiu.feodorov

                        I would never ignore you, Adrian :) That would be stupid (as in dumb). I am trying to translate what you're saying in something I can picture, and I am a little bit confused now, because I remember you saying that MessageCache is probably one of the things that are well implemented in JBossMQ.

                        But then I probably not remember correctly.

                        • 24. Re: Context of MessageStore design task

                           

                          "ovidiu.feodorov@jboss.com" wrote:
                          that MessageCache is probably one of the things that are well implemented in JBossMQ.

                          But then I probably not remember correctly.


                          ????

                          I said TxManager was one of the few things that was done well. :-)

                          MessageCache is a horrible practically unoverridable class.
                          It mixes:
                          * Configuration
                          * Management (JMX and stats)
                          * Implementation (LRU cache and soft reference thread/policy)
                          * Factory (the source of the MessageReference implementation)

                          Not to mention that when I got hold of it, it was a massively global point of contention
                          that would cause the whole system to go through run/stall cycles:
                          http://anoncvs.forge.jboss.com/changelog/JBoss?cs=MAIN:ejort:20021110225832
                          I "wasted" a whole month rewriting all the synchronization and testing. :-(

                          • 25. Re: Context of MessageStore design task
                            ovidiu.feodorov

                            OK, I will spawn a new thread and we'll concentrate on what you call "transactional behavior". After we are done with that thread, I'll return to this one and get to the bottom of it too.

                            Please go to http://www.jboss.org/index.html?module=bb&op=viewtopic&t=73650 and comment. Please don't post on this thread until we sort out the problems on that one.

                            1 2 Previous Next