Details

      Description

      Assorted performance improvements for the Java Broker and Client based on profiling and a bit of common sense:

      Persistence:

      Store message in same transaction as enqueue if possible

      Memory:

      Remove unnecessary (un)boxing
      Reduce unnecessary copying of message data
      Cache short strings
      Cache queues for a given routing key on an Exchange
      (0-9) Use a fixed size buffer for preparing frames to write out

      Other:

      Reduce calls to System.currentTimeMillis
      Cache publishing access control queries

      (0-10) Special case immutable RangeSets, in particular RangeSets of a single range/point
      (0-10) Special case delivery properties and message properties in headers
      (0-9) send commit-ok as soon as data committed to store
      (0-9) Optimised long and int typed values for FieldTables
      (0-9) Retain FieldTable encoded form
      (0-9) Cache queue and topic destinations

        Activity

        Hide
        Keith Wall added a comment -

        It appears there is an issue with the new publish access control cache being exposed by the failing Python tests.

        These have started to fail since this commit (build#66):

        • qpid_tests.broker_0_10.broker.BrokerTests.test_simple_delivery_immediate
        • qpid_tests.broker_0_10.broker.BrokerTests.test_simple_delivery_queued
        • qpid_tests.broker_0_10.message.MessageTests.test_no_local
        • qpid_tests.broker_0_10.message.MessageTests.test_no_local_exclusive_subscribe
        • qpid.tests.messaging.endpoints.AddressTests.testCreateExchange
        • qpid.tests.messaging.endpoints.AddressTests.testCreateExchangeDirect
        • qpid.tests.messaging.endpoints.AddressTests.testCreateExchangeTopic
        • qpid.tests.messaging.endpoints.AddressTests.testLinkName
        • qpid.tests.messaging.endpoints.AddressTests.testNodeBindingsTopic
        • qpid.tests.messaging.endpoints.AddressTests.testReliabilityAtLeastOnce
        • qpid.tests.messaging.endpoints.AddressTests.testReliabilityUnreliable
        • qpid.tests.messaging.endpoints.ReceiverTests.testDoubleClose
        • qpid.tests.messaging.message.MessageEchoTests.testContentTypeUnknown
        • qpid.tests.messaging.message.MessageEchoTests.testReplyTo
        • qpid.tests.messaging.message.MessageEchoTests.testReplyToQueue
        • qpid.tests.messaging.message.MessageEchoTests.testReplyToQueueSubject
        • qpid.tests.messaging.message.MessageEchoTests.testReplyToTopic
        • qpid.tests.messaging.message.MessageEchoTests.testReplyToTopicSubject
        • qpid.tests.messaging.message.MessageEchoTests.testTextPlainEmpty

        e.g.

        https://builds.apache.org/view/M-R/view/Qpid/job/Qpid-Python-Java-Test/66/testReport/junit/qpid_tests.broker_0_10.broker/BrokerTests/test_simple_delivery_immediate/

        On the Broker side, we see a NPE:

        
        2012-01-04 11:00:52,444 INFO  [IoReceiver - /127.0.0.1:34900] (Log4jMessageLogger.java:72) - [con:12(null@/127.0.0.1:34900/test)/ch:0] EXH-1001 : Create : Type: topic Name: test-create-exchange
        2012-01-04 11:00:52,451 ERROR [IoReceiver - /127.0.0.1:34900] (ServerSessionDelegate.java:93) - Exception processing command
        java.lang.NullPointerException
                at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768)
                at org.apache.qpid.server.security.SecurityManager.authorisePublish(SecurityManager.java:405)
                at org.apache.qpid.server.transport.ServerSessionDelegate.messageTransfer(ServerSessionDelegate.java:268)
                at org.apache.qpid.server.transport.ServerSessionDelegate.messageTransfer(ServerSessionDelegate.java:61)
                at org.apache.qpid.transport.MessageTransfer.dispatch(MessageTransfer.java:108)
                at org.apache.qpid.transport.SessionDelegate.command(SessionDelegate.java:50)
                at org.apache.qpid.server.transport.ServerSessionDelegate.command(ServerSessionDelegate.java:84)
                at org.apache.qpid.server.transport.ServerSessionDelegate.command(ServerSessionDelegate.java:61)
                at org.apache.qpid.transport.Method.delegate(Method.java:159)
                at org.apache.qpid.transport.Session.received(Session.java:558)
                at org.apache.qpid.transport.Connection.dispatch(Connection.java:435)
                at org.apache.qpid.transport.ConnectionDelegate.handle(ConnectionDelegate.java:64)
                at org.apache.qpid.transport.ConnectionDelegate.handle(ConnectionDelegate.java:40)
                at org.apache.qpid.transport.MethodDelegate.messageTransfer(MethodDelegate.java:113)
                at org.apache.qpid.transport.MessageTransfer.dispatch(MessageTransfer.java:108)
                at org.apache.qpid.transport.ConnectionDelegate.command(ConnectionDelegate.java:54)
                at org.apache.qpid.transport.ConnectionDelegate.command(ConnectionDelegate.java:40)
                at org.apache.qpid.transport.Method.delegate(Method.java:159)
                at org.apache.qpid.transport.Connection.received(Connection.java:390)
                at org.apache.qpid.server.transport.ServerConnection.received(ServerConnection.java:237)
                at org.apache.qpid.server.transport.ServerConnection.received(ServerConnection.java:66)
                at org.apache.qpid.transport.network.Assembler.emit(Assembler.java:89)
                at org.apache.qpid.transport.network.Assembler.assemble(Assembler.java:232)
                at org.apache.qpid.transport.network.Assembler.frame(Assembler.java:123)
                at org.apache.qpid.transport.network.Frame.delegate(Frame.java:133)
                at org.apache.qpid.transport.network.Assembler.received(Assembler.java:94)
                at org.apache.qpid.transport.network.Assembler.received(Assembler.java:36)
                at org.apache.qpid.transport.network.InputHandler.next(InputHandler.java:187)
                at org.apache.qpid.transport.network.InputHandler.received(InputHandler.java:103)
                at org.apache.qpid.server.protocol.ProtocolEngine_0_10.received(ProtocolEngine_0_10.java:105)
                at org.apache.qpid.server.protocol.ProtocolEngine_0_10.received(ProtocolEngine_0_10.java:38)
                at org.apache.qpid.server.protocol.MultiVersionProtocolEngine.received(MultiVersionProtocolEngine.java:111)
                at org.apache.qpid.server.protocol.MultiVersionProtocolEngine.received(MultiVersionProtocolEngine.java:36)
                at org.apache.qpid.transport.network.io.IoReceiver.run(IoReceiver.java:153)
                at java.lang.Thread.run(Thread.java:662)
        
        
        
        Show
        Keith Wall added a comment - It appears there is an issue with the new publish access control cache being exposed by the failing Python tests. These have started to fail since this commit (build#66): qpid_tests.broker_0_10.broker.BrokerTests.test_simple_delivery_immediate qpid_tests.broker_0_10.broker.BrokerTests.test_simple_delivery_queued qpid_tests.broker_0_10.message.MessageTests.test_no_local qpid_tests.broker_0_10.message.MessageTests.test_no_local_exclusive_subscribe qpid.tests.messaging.endpoints.AddressTests.testCreateExchange qpid.tests.messaging.endpoints.AddressTests.testCreateExchangeDirect qpid.tests.messaging.endpoints.AddressTests.testCreateExchangeTopic qpid.tests.messaging.endpoints.AddressTests.testLinkName qpid.tests.messaging.endpoints.AddressTests.testNodeBindingsTopic qpid.tests.messaging.endpoints.AddressTests.testReliabilityAtLeastOnce qpid.tests.messaging.endpoints.AddressTests.testReliabilityUnreliable qpid.tests.messaging.endpoints.ReceiverTests.testDoubleClose qpid.tests.messaging.message.MessageEchoTests.testContentTypeUnknown qpid.tests.messaging.message.MessageEchoTests.testReplyTo qpid.tests.messaging.message.MessageEchoTests.testReplyToQueue qpid.tests.messaging.message.MessageEchoTests.testReplyToQueueSubject qpid.tests.messaging.message.MessageEchoTests.testReplyToTopic qpid.tests.messaging.message.MessageEchoTests.testReplyToTopicSubject qpid.tests.messaging.message.MessageEchoTests.testTextPlainEmpty e.g. https://builds.apache.org/view/M-R/view/Qpid/job/Qpid-Python-Java-Test/66/testReport/junit/qpid_tests.broker_0_10.broker/BrokerTests/test_simple_delivery_immediate/ On the Broker side, we see a NPE: 2012-01-04 11:00:52,444 INFO [IoReceiver - /127.0.0.1:34900] (Log4jMessageLogger.java:72) - [con:12( null @/127.0.0.1:34900/test)/ch:0] EXH-1001 : Create : Type: topic Name: test-create-exchange 2012-01-04 11:00:52,451 ERROR [IoReceiver - /127.0.0.1:34900] (ServerSessionDelegate.java:93) - Exception processing command java.lang.NullPointerException at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768) at org.apache.qpid.server.security. SecurityManager .authorisePublish( SecurityManager .java:405) at org.apache.qpid.server.transport.ServerSessionDelegate.messageTransfer(ServerSessionDelegate.java:268) at org.apache.qpid.server.transport.ServerSessionDelegate.messageTransfer(ServerSessionDelegate.java:61) at org.apache.qpid.transport.MessageTransfer.dispatch(MessageTransfer.java:108) at org.apache.qpid.transport.SessionDelegate.command(SessionDelegate.java:50) at org.apache.qpid.server.transport.ServerSessionDelegate.command(ServerSessionDelegate.java:84) at org.apache.qpid.server.transport.ServerSessionDelegate.command(ServerSessionDelegate.java:61) at org.apache.qpid.transport.Method.delegate(Method.java:159) at org.apache.qpid.transport.Session.received(Session.java:558) at org.apache.qpid.transport.Connection.dispatch(Connection.java:435) at org.apache.qpid.transport.ConnectionDelegate.handle(ConnectionDelegate.java:64) at org.apache.qpid.transport.ConnectionDelegate.handle(ConnectionDelegate.java:40) at org.apache.qpid.transport.MethodDelegate.messageTransfer(MethodDelegate.java:113) at org.apache.qpid.transport.MessageTransfer.dispatch(MessageTransfer.java:108) at org.apache.qpid.transport.ConnectionDelegate.command(ConnectionDelegate.java:54) at org.apache.qpid.transport.ConnectionDelegate.command(ConnectionDelegate.java:40) at org.apache.qpid.transport.Method.delegate(Method.java:159) at org.apache.qpid.transport.Connection.received(Connection.java:390) at org.apache.qpid.server.transport.ServerConnection.received(ServerConnection.java:237) at org.apache.qpid.server.transport.ServerConnection.received(ServerConnection.java:66) at org.apache.qpid.transport.network.Assembler.emit(Assembler.java:89) at org.apache.qpid.transport.network.Assembler.assemble(Assembler.java:232) at org.apache.qpid.transport.network.Assembler.frame(Assembler.java:123) at org.apache.qpid.transport.network.Frame.delegate(Frame.java:133) at org.apache.qpid.transport.network.Assembler.received(Assembler.java:94) at org.apache.qpid.transport.network.Assembler.received(Assembler.java:36) at org.apache.qpid.transport.network.InputHandler.next(InputHandler.java:187) at org.apache.qpid.transport.network.InputHandler.received(InputHandler.java:103) at org.apache.qpid.server.protocol.ProtocolEngine_0_10.received(ProtocolEngine_0_10.java:105) at org.apache.qpid.server.protocol.ProtocolEngine_0_10.received(ProtocolEngine_0_10.java:38) at org.apache.qpid.server.protocol.MultiVersionProtocolEngine.received(MultiVersionProtocolEngine.java:111) at org.apache.qpid.server.protocol.MultiVersionProtocolEngine.received(MultiVersionProtocolEngine.java:36) at org.apache.qpid.transport.network.io.IoReceiver.run(IoReceiver.java:153) at java.lang. Thread .run( Thread .java:662)
        Hide
        Keith Wall added a comment -

        The MessageEchoTests are provoking a different NPE:

        java.lang.NullPointerException
                at org.apache.qpid.server.store.StoredMemoryMessage.getContent(StoredMemoryMessage.java:105)
                at org.apache.qpid.server.message.MessageTransferMessage.getContent(MessageTransferMessage.java:115)
                at org.apache.qpid.server.message.MessageTransferMessage.getBody(MessageTransferMessage.java:126)
                at org.apache.qpid.server.subscription.Subscription_0_10.send(Subscription_0_10.java:424)
                at org.apache.qpid.server.queue.SimpleAMQQueue.deliverMessage(SimpleAMQQueue.java:800)
                at org.apache.qpid.server.queue.SimpleAMQQueue.attemptDelivery(SimpleAMQQueue.java:1781)
                at org.apache.qpid.server.queue.SimpleAMQQueue.processQueue(SimpleAMQQueue.java:1935)
                at org.apache.qpid.server.queue.QueueRunner.run(QueueRunner.java:77)
                at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                at java.lang.Thread.run(Thread.java:662)
        
        Show
        Keith Wall added a comment - The MessageEchoTests are provoking a different NPE: java.lang.NullPointerException at org.apache.qpid.server.store.StoredMemoryMessage.getContent(StoredMemoryMessage.java:105) at org.apache.qpid.server.message.MessageTransferMessage.getContent(MessageTransferMessage.java:115) at org.apache.qpid.server.message.MessageTransferMessage.getBody(MessageTransferMessage.java:126) at org.apache.qpid.server.subscription.Subscription_0_10.send(Subscription_0_10.java:424) at org.apache.qpid.server.queue.SimpleAMQQueue.deliverMessage(SimpleAMQQueue.java:800) at org.apache.qpid.server.queue.SimpleAMQQueue.attemptDelivery(SimpleAMQQueue.java:1781) at org.apache.qpid.server.queue.SimpleAMQQueue.processQueue(SimpleAMQQueue.java:1935) at org.apache.qpid.server.queue.QueueRunner.run(QueueRunner.java:77) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang. Thread .run( Thread .java:662)
        Hide
        Rob Godfrey added a comment -

        Both these NPEs have now been resolved.

        One observation is that the Python test in the second case is sending no body segment and asserts that it is a failure if the broker sends back a message with an empty body segment. While the MemoryMessageStore can retain this difference, the Derby and BDB stores will always treat a null body as equivalent to an empty body.

        Show
        Rob Godfrey added a comment - Both these NPEs have now been resolved. One observation is that the Python test in the second case is sending no body segment and asserts that it is a failure if the broker sends back a message with an empty body segment. While the MemoryMessageStore can retain this difference, the Derby and BDB stores will always treat a null body as equivalent to an empty body.
        Hide
        Robbie Gemmell added a comment -

        Closing out, changes look good to me.

        Show
        Robbie Gemmell added a comment - Closing out, changes look good to me.
        Hide
        Keith Wall added a comment -

        Fixed defect in caching logic in BasicContentHeaderProperties.

        Expression was only using the cached version when determining the length of the properties and not when writing the payload to the buffer.

        This problem was noticed by way of the interop test suite when testing with the old 0-8 .NET client.

        Show
        Keith Wall added a comment - Fixed defect in caching logic in BasicContentHeaderProperties. Expression was only using the cached version when determining the length of the properties and not when writing the payload to the buffer. This problem was noticed by way of the interop test suite when testing with the old 0-8 .NET client.
        Hide
        Robbie Gemmell added a comment -

        Looks good to me...again, erm...

        Show
        Robbie Gemmell added a comment - Looks good to me...again, erm...

          People

          • Assignee:
            Robbie Gemmell
            Reporter:
            Rob Godfrey
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development