[jira] [Commented] (AMQ-5712) Broker can deadlock when using queues while producers wait on disk space

2015-04-13 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-5712?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14492768#comment-14492768
 ] 

Paul Gale commented on AMQ-5712:


Perhaps I've missed something but if you're working with non-persistent 
messages then why not configure a policyEntry for the queue to use a vmCursor 
rather than the default storeCursor? 

Regardless, I agree that the temp store's implementation needs some work. 
Ideally it should honor the sendFailIfNoSpaceAfterTimeout when configured on 
the systemUsage element.

 Broker can deadlock when using queues while producers wait on disk space
 

 Key: AMQ-5712
 URL: https://issues.apache.org/jira/browse/AMQ-5712
 Project: ActiveMQ
  Issue Type: Bug
  Components: Broker
Affects Versions: 5.11.1
Reporter: Christopher L. Shannon

 I am experiencing a deadlock when using a Queue with non-persistent messages. 
  The queue has a cursor high memory water mark set (right now at 70%).  When 
 a producer is producing messages quickly to the queue and that limit gets 
 hit, the broker can deadlock.   I have tried setting producerWindowSize and 
 alwaysSyncSend which did not seem to help. When the broker hits that limit, I 
 am unable to do things like purge the queue.  Consumers can also deadlock as 
 well. 
 Note that this appears to be the same issue as described in this ticket here: 
 AMQ-2475 .  The difference is that I am using a Queue and not a Topic and the 
 fix for this appears to only have been for Topics.
 The problem appears to be in the Queue class on line 1852 inside the 
 {{cursorAdd}} method.  The method being called is {{return 
 messages.addMessageLast(msg);}} which will block indefinitely if there is no 
 space available, which in turn ties up the {{messagesLock}} from being used 
 by any other threads.  We have seen a deadlock where consumers can't consume 
 because they are waiting on this lock.   It looks like in AMQ-2475 part of 
 the fix was to replace {{messages.addMessageLast(msg)}} with 
 {{messages.tryAddMessageLast(msg, 10)}}.  I also noticed that not all of the 
 message cursors support {{tryAddMessageLast}}, which could be a problem.  
 {{FilePendingMessageCursor}} implements it but the rest of the cursors 
 (notably {{StoreQueueCursor}}) simply delegate back to {{addMessageLast}} in 
 the parent class.  So part of this fix may require implementing 
 {{tryAddMessageLast}} across more cursors.
 Here is part of the thread dump showing the stuck producer:
 {code}
 ActiveMQ Transport: ssl:///192.168.3.142:38589 daemon prio=10 
 tid=0x7fb46c006000 nid=0x3b1a runnable [0x7fb4b8a0d000]
java.lang.Thread.State: TIMED_WAITING (parking)
 at sun.misc.Unsafe.park(Native Method)
 - parking to wait for  0xcfb13cd0 (a 
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
 at 
 java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
 at 
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2176)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:103)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:90)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:80)
 at 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.tryAddMessageLast(FilePendingMessageCursor.java:235)
 - locked 0xd2015ee0 (a 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor)
 at 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.addMessageLast(FilePendingMessageCursor.java:207)
 - locked 0xd2015ee0 (a 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor)
 at 
 org.apache.activemq.broker.region.cursors.StoreQueueCursor.addMessageLast(StoreQueueCursor.java:97)
 - locked 0xd1f20908 (a 
 org.apache.activemq.broker.region.cursors.StoreQueueCursor)
 {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (AMQ-5712) Broker can deadlock when using queues while producers wait on disk space

2015-04-13 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-5712?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14492866#comment-14492866
 ] 

Paul Gale commented on AMQ-5712:


I too have hit the same limitations of the temp store. In the interim you can 
always force the broker to treat all messages as persistent using the 
{{forcePersistencyModeBrokerPlugin}}. Alternatively use the broker component. 

Perhaps you might need to supplement it with (it's been a while) this to force 
the cursor to not use the temp store:

{code}
pendingQueuePolicy
  storeCursor/
/pendingQueuePolicy
{code}

Is PFC disabled for your queue? If so, why?

Regardless, even if the temp store worked correctly both memory and disk are 
limited resources so you're only delaying the inevitable as one of them will 
eventually fill up - that is, not unless the producer is flow controlled.


 Broker can deadlock when using queues while producers wait on disk space
 

 Key: AMQ-5712
 URL: https://issues.apache.org/jira/browse/AMQ-5712
 Project: ActiveMQ
  Issue Type: Bug
  Components: Broker
Affects Versions: 5.11.1
Reporter: Christopher L. Shannon

 I am experiencing a deadlock when using a Queue with non-persistent messages. 
  The queue has a cursor high memory water mark set (right now at 70%).  When 
 a producer is producing messages quickly to the queue and that limit gets 
 hit, the broker can deadlock.   I have tried setting producerWindowSize and 
 alwaysSyncSend which did not seem to help. When the broker hits that limit, I 
 am unable to do things like purge the queue.  Consumers can also deadlock as 
 well. 
 Note that this appears to be the same issue as described in this ticket here: 
 AMQ-2475 .  The difference is that I am using a Queue and not a Topic and the 
 fix for this appears to only have been for Topics.
 The problem appears to be in the Queue class on line 1852 inside the 
 {{cursorAdd}} method.  The method being called is {{return 
 messages.addMessageLast(msg);}} which will block indefinitely if there is no 
 space available, which in turn ties up the {{messagesLock}} from being used 
 by any other threads.  We have seen a deadlock where consumers can't consume 
 because they are waiting on this lock.   It looks like in AMQ-2475 part of 
 the fix was to replace {{messages.addMessageLast(msg)}} with 
 {{messages.tryAddMessageLast(msg, 10)}}.  I also noticed that not all of the 
 message cursors support {{tryAddMessageLast}}, which could be a problem.  
 {{FilePendingMessageCursor}} implements it but the rest of the cursors 
 (notably {{StoreQueueCursor}}) simply delegate back to {{addMessageLast}} in 
 the parent class.  So part of this fix may require implementing 
 {{tryAddMessageLast}} across more cursors.
 Here is part of the thread dump showing the stuck producer:
 {code}
 ActiveMQ Transport: ssl:///192.168.3.142:38589 daemon prio=10 
 tid=0x7fb46c006000 nid=0x3b1a runnable [0x7fb4b8a0d000]
java.lang.Thread.State: TIMED_WAITING (parking)
 at sun.misc.Unsafe.park(Native Method)
 - parking to wait for  0xcfb13cd0 (a 
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
 at 
 java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
 at 
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2176)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:103)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:90)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:80)
 at 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.tryAddMessageLast(FilePendingMessageCursor.java:235)
 - locked 0xd2015ee0 (a 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor)
 at 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.addMessageLast(FilePendingMessageCursor.java:207)
 - locked 0xd2015ee0 (a 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor)
 at 
 org.apache.activemq.broker.region.cursors.StoreQueueCursor.addMessageLast(StoreQueueCursor.java:97)
 - locked 0xd1f20908 (a 
 org.apache.activemq.broker.region.cursors.StoreQueueCursor)
 {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (AMQ-5712) Broker can deadlock when using queues while producers wait on disk space

2015-04-13 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-5712?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14493044#comment-14493044
 ] 

Paul Gale commented on AMQ-5712:


I don't see how this plugin puts a requirement on the producer. For example, 
setting {{forcePersistencyModeBrokerPlugin persistenceFlag=true/}} allows 
the producer to send either form. It simply makes all messages persistent (or 
non-persistent if {{false}}).


 Broker can deadlock when using queues while producers wait on disk space
 

 Key: AMQ-5712
 URL: https://issues.apache.org/jira/browse/AMQ-5712
 Project: ActiveMQ
  Issue Type: Bug
  Components: Broker
Affects Versions: 5.11.1
Reporter: Christopher L. Shannon

 I am experiencing a deadlock when using a Queue with non-persistent messages. 
  The queue has a cursor high memory water mark set (right now at 70%).  When 
 a producer is producing messages quickly to the queue and that limit gets 
 hit, the broker can deadlock.   I have tried setting producerWindowSize and 
 alwaysSyncSend which did not seem to help. When the broker hits that limit, I 
 am unable to do things like purge the queue.  Consumers can also deadlock as 
 well. 
 Note that this appears to be the same issue as described in this ticket here: 
 AMQ-2475 .  The difference is that I am using a Queue and not a Topic and the 
 fix for this appears to only have been for Topics.
 The problem appears to be in the Queue class on line 1852 inside the 
 {{cursorAdd}} method.  The method being called is {{return 
 messages.addMessageLast(msg);}} which will block indefinitely if there is no 
 space available, which in turn ties up the {{messagesLock}} from being used 
 by any other threads.  We have seen a deadlock where consumers can't consume 
 because they are waiting on this lock.   It looks like in AMQ-2475 part of 
 the fix was to replace {{messages.addMessageLast(msg)}} with 
 {{messages.tryAddMessageLast(msg, 10)}}.  I also noticed that not all of the 
 message cursors support {{tryAddMessageLast}}, which could be a problem.  
 {{FilePendingMessageCursor}} implements it but the rest of the cursors 
 (notably {{StoreQueueCursor}}) simply delegate back to {{addMessageLast}} in 
 the parent class.  So part of this fix may require implementing 
 {{tryAddMessageLast}} across more cursors.
 Here is part of the thread dump showing the stuck producer:
 {code}
 ActiveMQ Transport: ssl:///192.168.3.142:38589 daemon prio=10 
 tid=0x7fb46c006000 nid=0x3b1a runnable [0x7fb4b8a0d000]
java.lang.Thread.State: TIMED_WAITING (parking)
 at sun.misc.Unsafe.park(Native Method)
 - parking to wait for  0xcfb13cd0 (a 
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
 at 
 java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
 at 
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2176)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:103)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:90)
 at org.apache.activemq.usage.Usage.waitForSpace(Usage.java:80)
 at 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.tryAddMessageLast(FilePendingMessageCursor.java:235)
 - locked 0xd2015ee0 (a 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor)
 at 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.addMessageLast(FilePendingMessageCursor.java:207)
 - locked 0xd2015ee0 (a 
 org.apache.activemq.broker.region.cursors.FilePendingMessageCursor)
 at 
 org.apache.activemq.broker.region.cursors.StoreQueueCursor.addMessageLast(StoreQueueCursor.java:97)
 - locked 0xd1f20908 (a 
 org.apache.activemq.broker.region.cursors.StoreQueueCursor)
 {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Created] (AMQ-5636) Upgrade the bundled DBCP component. The current one is very old and buggy.

2015-03-04 Thread Paul Gale (JIRA)
Paul Gale created AMQ-5636:
--

 Summary: Upgrade the bundled DBCP component. The current one is 
very old and buggy.
 Key: AMQ-5636
 URL: https://issues.apache.org/jira/browse/AMQ-5636
 Project: ActiveMQ
  Issue Type: Improvement
  Components: JDBC, KahaDB
Affects Versions: 5.11.0, 5.10.0
Reporter: Paul Gale
Priority: Critical
 Fix For: 5.11.1, 5.12.0


The current DBCP component that ships with ActiveMQ is version 1.4. It dates 
from Feb 2010. 

After fours years of inactivity a number of releases were made in the last 
twelve months to the DBCP component. The most recent version, 2.1, was released 
on Feb 23rd 2015.

Personally, I am seeing weird behavior with the DBCP 1.4 component when using 
it as a lease locker with KahaDB. When a connection is dropped the DBCP 
component doesn't always handle it correctly which manifests itself as a lease 
lock failure from the broker's standpoint.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Created] (AMQ-5505) Add support for the BrokerView MBean to get the up-time in milliseconds

2015-01-05 Thread Paul Gale (JIRA)
Paul Gale created AMQ-5505:
--

 Summary: Add support for the BrokerView MBean to get the up-time 
in milliseconds
 Key: AMQ-5505
 URL: https://issues.apache.org/jira/browse/AMQ-5505
 Project: ActiveMQ
  Issue Type: Improvement
  Components: Broker, JMX
Affects Versions: 5.10.0
Reporter: Paul Gale
 Fix For: 5.11.0


Currently one can only get the broker's up-time as a formatted string via JMX. 

I need to be able to get the up-time in milliseconds as we're using DataDog as 
our monitoring tool (which doesn't understand the current up-time formatted 
string). 

The up-time formatted string will remain as-is.




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Updated] (AMQ-5174) Cannot use the JDBCIOExceptionHandler when kahadb is configured with lease-database-locker

2014-11-12 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-5174?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-5174:
---
Affects Version/s: 5.10.0

 Cannot use the JDBCIOExceptionHandler when kahadb is configured with 
 lease-database-locker
 --

 Key: AMQ-5174
 URL: https://issues.apache.org/jira/browse/AMQ-5174
 Project: ActiveMQ
  Issue Type: Bug
  Components: Message Store
Affects Versions: 5.9.0, 5.9.1, 5.10.0
Reporter: Paul Gale
Priority: Critical
 Fix For: 5.11.0


 The {{JDBCIOExceptionHandler}} is limited to operating with the 
 {{JDBCPersistenceAdapter}}. 
 It should be allowed to work in combination with the 
 {{KahaDBPersistenceAdapter}} if it's configured to use a 
 {{LeaseDatabaseLocker}} as a locker.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (AMQ-5030) Upgrade Camel to latest 2.12.x patch

2014-06-05 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-5030?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14018830#comment-14018830
 ] 

Paul Gale commented on AMQ-5030:


Is there any reason why Camel cannot be upgraded to 2.13.1 instead of 2.12x?

 Upgrade Camel to latest 2.12.x patch
 

 Key: AMQ-5030
 URL: https://issues.apache.org/jira/browse/AMQ-5030
 Project: ActiveMQ
  Issue Type: Task
  Components: activemq-camel
Reporter: Claus Ibsen
Assignee: Hadrian Zbarcea
Priority: Blocker
 Fix For: 5.10.0


 We need to upgrade to latest Camel 2.12.3 release to pickup some very 
 important fixes.



--
This message was sent by Atlassian JIRA
(v6.2#6252)


[jira] [Created] (AMQ-5174) Cannot use the JDBCIOExceptionHandler when kahadb is configured with lease-database-locker

2014-05-06 Thread Paul Gale (JIRA)
Paul Gale created AMQ-5174:
--

 Summary: Cannot use the JDBCIOExceptionHandler when kahadb is 
configured with lease-database-locker
 Key: AMQ-5174
 URL: https://issues.apache.org/jira/browse/AMQ-5174
 Project: ActiveMQ
  Issue Type: Bug
  Components: Message Store
Affects Versions: 5.9.1, 5.9.0
Reporter: Paul Gale
Priority: Critical
 Fix For: 5.10.0


The {{JDBCIOExceptionHandler}} is limited to operating with the 
{{JDBCPersistenceAdapter}}. 

It should be allowed to work in combination with the 
{{KahaDBPersistenceAdapter}} if it's configured to use a 
{{LeaseDatabaseLocker}} as a locker.



--
This message was sent by Atlassian JIRA
(v6.2#6252)


[jira] [Commented] (AMQ-5091) Upgrade to jolokia 1.2

2014-05-05 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-5091?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13989434#comment-13989434
 ] 

Paul Gale commented on AMQ-5091:


It appears that jolokia 1.2.1 is still being built with json-simple 1.1.1. 
Therefore we can either ask the maintainers to update Jolokia to use 
json-simple 1.1.1 or ship our own version of Jolokia built against json-simple 
1.1.1 instead? 

Version 1.1.1 of json-simple has been around for over two years and includes 
OSGI support which 1.1.0 does not. If that's too much of a headache then 
perhaps not. Just a thought. 

 Upgrade to jolokia 1.2
 --

 Key: AMQ-5091
 URL: https://issues.apache.org/jira/browse/AMQ-5091
 Project: ActiveMQ
  Issue Type: Improvement
  Components: Broker
Reporter: Claus Ibsen
Assignee: Claus Ibsen
 Fix For: 5.10.0


 Jolokia 1.2.0 has been released.



--
This message was sent by Atlassian JIRA
(v6.2#6252)


[jira] [Commented] (AMQ-4728) Develop a pluggable locker that can be shared broker-wide for both the persistence adapter as well as the redelivery plugin

2014-03-18 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4728?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13939746#comment-13939746
 ] 

Paul Gale commented on AMQ-4728:


Now that I've re-read this I was wondering if a better solution might be to 
have the redelivery scheduler store its messages in the main message store 
rather than create a separate locker for its separate message store. 

Thoughts?

If this is a lot of work then I think it would be best to move this out to the 
5.11+ release.

 Develop a pluggable locker that can be shared broker-wide for both the 
 persistence adapter as well as the redelivery plugin
 ---

 Key: AMQ-4728
 URL: https://issues.apache.org/jira/browse/AMQ-4728
 Project: ActiveMQ
  Issue Type: New Feature
  Components: Broker, Message Store
Affects Versions: 5.8.0
Reporter: Paul Gale
 Fix For: 5.10.0


 Modify the redelivery plugin so that it can be configured with a pluggable 
 storage locker.
 Allow the same locker to optionally be configured at the broker level so that 
 the same locker instance can be shared by all components that need it, e.g., 
 the persistence adapter (including multi kaha) and the redelivery plugin.



--
This message was sent by Atlassian JIRA
(v6.2#6252)


[jira] [Commented] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a kahadb lock

2014-01-13 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13870028#comment-13870028
 ] 

Paul Gale commented on AMQ-4365:


With this change in place does the broker handle the two scenarios where the 
database is either offline at start-up or goes offline at at some point after 
start-up? If so, how?

If not, what modifications are needed for the broker to cope with these 
scenarios? I am trying to get an idea for the nature and magnitude of any 
required changes. Ideally the broker should attempt to (re)connect indefinitely 
in both scenarios.

 Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it 
 can be a kahadb lock
 

 Key: AMQ-4365
 URL: https://issues.apache.org/jira/browse/AMQ-4365
 Project: ActiveMQ
  Issue Type: Improvement
Affects Versions: 5.8.0
Reporter: Gary Tully
Assignee: Gary Tully
 Fix For: 5.9.0


 The locker interface needs another configure option to provide a broker 
 service, or needs to be brokerService aware so that a locker can get identity 
 and access to the io exception handlers.
 The lease database locker is dependent on the jdbc pa to get statements and 
 data source. It should be possible to configure these independently such that 
 it can be used standalone as a broker lock. So setters for each.
 This will help sort out some of the dependencies between broker and lock 
 implementations. also making it possible to use a lease lock with kahadb for 
 example.
 some context: 
 http://mail-archives.apache.org/mod_mbox/activemq-users/201303.mbox/%3ccaj5znhuruz+aewsaabajtwbbpkwn06ryyyt6nqsdg_su7vm...@mail.gmail.com%3E



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)


[jira] [Commented] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-12 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13765545#comment-13765545
 ] 

Paul Gale commented on AMQ-4710:


Any movement on this? I'd like to know whether this patch is going to be 
accepted or if other feedback is available.

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq-4710.diff


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-10 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4710:
---

Attachment: (was: amq-4710.diff)

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson

 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-10 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4710:
---

Attachment: amq-4710.diff

Latest greatest, and hopefully final, version of test and fix.

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq-4710.diff


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Issue Comment Deleted] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-09 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4710:
---

Comment: was deleted

(was: Updated patch containing fix for Jira AMQ-4710. Improved the checking for 
when to recreate the write checker timer task. Previous patch attachment has 
been deleted.)

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq-4710.diff


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-09 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4710:
---

Attachment: (was: amq_4710_2.patch)

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq-4710.diff


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-09 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4710:
---

Attachment: amq-4710.diff

Unit test and patch to fix this issue.

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq-4710.diff


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Commented] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-09 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13761912#comment-13761912
 ] 

Paul Gale commented on AMQ-4710:


Just realized I should have used a StompConnection object in the test. Trying 
again.

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq-4710.diff


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Issue Comment Deleted] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-05 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4710:
---

Comment: was deleted

(was: I have modified my last patch. The latest has been attached as 
amq_4710_2.patch)

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq_4710_2.patch


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-05 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4710:
---

Attachment: amq_4710_2.patch

Patch containing fix for Jira AMQ-4710. Improved the checking for when to 
recreate the write checker timer task.

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq_4710_2.patch, amq_4710.patch


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Commented] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-04 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13758353#comment-13758353
 ] 

Paul Gale commented on AMQ-4710:


Sending a frame is sending data on the wire so the send of the RECEIPT frame 
prempts any need to send a KEEPALIVE frame. 

Agreed. However, once data has been sent in lieu of a KEEPALIVE frame the write 
checker timer should be adjusted accordingly, otherwise it will sleep for twice 
its configured interval. 

I have attached a patch file containing a failing unit test (of sorts) and a 
fix. The test is not the prettiest so adjust as necessary.

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq_4710.patch


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-04 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4710:
---

Attachment: amq_4710.patch

Patch file containing test and fix for this issue.

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson
 Attachments: amq_4710.patch


 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Commented] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-03 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13757072#comment-13757072
 ] 

Paul Gale commented on AMQ-4710:


This problem doesn't just happen on startup. 

I've been able to induce this behavior in the broker. I modified the test to 
periodically send a frame to the broker containing a receipt header. This 
forces the broker to respond with a RECEIPT frame. After sending the RECEIPT 
frame the broker waits another 1ms (in this case) before issuing another 
write check.

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson

 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Commented] (AMQ-4710) The first heart-beat after a connection becomes idle isn't sent as quickly as it should be

2013-09-03 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4710?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13757189#comment-13757189
 ] 

Paul Gale commented on AMQ-4710:


I believe the fix for this condition is as follows. I've tested it and it 
appears to work. However, feedback is welcome if there's a better way to handle 
this.

{code}
private final Runnable writeChecker = new Runnable() {
long lastRunTime;

@Override
public void run() {
long now = System.currentTimeMillis();
long sleepTime = now - lastRunTime;

if (lastRunTime != 0  LOG.isDebugEnabled()) {
LOG.debug(this +   + sleepTime +  ms elapsed since last 
write check.);
}

if (commandSent.get()  sleepTime = getWriteCheckTime()) {
  LOG.trace(Resetting to prevent double sleep !!);
  commandSent.set(false);
}

lastRunTime = now;
writeCheck();
}

@Override
public String toString() {
return WriteChecker;
}
};
{code}

 The first heart-beat after a connection becomes idle isn't sent as quickly as 
 it should be
 --

 Key: AMQ-4710
 URL: https://issues.apache.org/jira/browse/AMQ-4710
 Project: ActiveMQ
  Issue Type: Bug
  Components: stomp
Affects Versions: 5.8.0
Reporter: Andy Wilkinson

 After ActiveMQ sends a stomp frame, it may not send a heart-beat for up to 
 almost 2x the negotiated interval.
 The following test should illustrate the problem:
 {code}
 import org.junit.Test;
 import static org.junit.Assert.*;
 public class ActiveMqHeartbeatTests {
   @Test
   public void heartbeats() throws Exception {
   BrokerService broker = createAndStartBroker();
   Socket socket = null;
   try {
   socket = new Socket(localhost, 61613);
   byte[] connectFrame = 
 CONNECT\nheart-beat:0,1\naccept-version:1.2\n\n\0.getBytes();
   socket.getOutputStream().write(connectFrame);
   byte[] buffer = new byte[4096];
   long lastReadTime = System.currentTimeMillis();
   while (true) {
   int read = socket.getInputStream().read(buffer);
   byte[] frame = Arrays.copyOf(buffer, read);
   long now = System.currentTimeMillis();
   long timeSinceLastRead = now - lastReadTime;
   lastReadTime = now;
   System.out.println(new String(frame));
   System.out.println(Time since last read:  + 
 timeSinceLastRead + ms);
   if (timeSinceLastRead  15000) {
   fail(Data not received for  + 
 timeSinceLastRead + ms);
   }
   }
   } finally {
   if (socket != null) {
   socket.close();
   }
   broker.stop();
   }
   }
   private BrokerService createAndStartBroker() throws Exception {
   BrokerService broker = new BrokerService();
   broker.addConnector(stomp://localhost:61613);
   broker.setStartAsync(false);
   broker.setDeleteAllMessagesOnStartup(true);
   broker.start();
   return broker;
   }
 }
 {code}
 For the initial read of the CONNECTED frame I see:
 {noformat}
 Time since last read: 49ms
 {noformat}
 However, it's then almost 20 seconds before a heart-beat's sent:
 {noformat}
 Time since last read: 19994ms
 {noformat}
 If I comment out the fail(…) line in the test, after the first heartbeat 
 taking almost 2ms to be sent, things settle down and a heartbeat's 
 received every 1ms.
 It looks like the write checker wakes up every 1ms. The first time it 
 wakes up, it notices that the CONNECTED frame was sent and does nothing. It 
 then sleeps for a further 1ms before checking again. As the CONNECTED 
 frame was sent very early in the first 1ms window, this leads to it 
 taking almost 2ms for the first heart-beat to be sent. From this point, 
 as no further data frames are sent, the write checker wakes up and sends a 
 heart-beat every 1ms.
 In short, I don't think ActiveMQ is adhering to the requirement that the 
 sender MUST send new data over the network connection at least every n 
 milliseconds.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more 

[jira] [Commented] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a broker lock

2013-08-30 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13754986#comment-13754986
 ] 

Paul Gale commented on AMQ-4365:


See here: https://github.com/ppaul/amq-db-lease-locker

I warn you, it's a hack but it does work.

 Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it 
 can be a broker lock
 

 Key: AMQ-4365
 URL: https://issues.apache.org/jira/browse/AMQ-4365
 Project: ActiveMQ
  Issue Type: Improvement
Affects Versions: 5.8.0
Reporter: Gary Tully
Assignee: Gary Tully
 Fix For: 5.9.0


 The locker interface needs another configure option to provide a broker 
 service, or needs to be brokerService aware so that a locker can get identity 
 and access to the io exception handlers.
 The lease database locker is dependent on the jdbc pa to get statements and 
 data source. It should be possible to configure these independently such that 
 it can be used standalone as a broker lock. So setters for each.
 This will help sort out some of the dependencies between broker and lock 
 implementations. also making it possible to use a lease lock with kahadb for 
 example.
 some context: 
 http://mail-archives.apache.org/mod_mbox/activemq-users/201303.mbox/%3ccaj5znhuruz+aewsaabajtwbbpkwn06ryyyt6nqsdg_su7vm...@mail.gmail.com%3E

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Commented] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a broker lock

2013-08-28 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13752512#comment-13752512
 ] 

Paul Gale commented on AMQ-4365:


Since making this initial request back in March I have completed the locker 
implementation. Therefore my earlier comment about needing a SQL script is no 
longer relevant. The locker auto-creates the table if it's missing in the same 
manner as the JDBCPersistenceAdapter. 

Note that my implementation is a total hack, e.g., no tests. It was designed to 
see me through until I can upgrade to ActiveMQ 5.9.0 at which point I plan to 
switch storage strategy to Replicated LevelDB. 

If there's any interest in seeing my implementation, let me know and I'll put 
it up on Github.

 Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it 
 can be a broker lock
 

 Key: AMQ-4365
 URL: https://issues.apache.org/jira/browse/AMQ-4365
 Project: ActiveMQ
  Issue Type: Improvement
Affects Versions: 5.8.0
Reporter: Gary Tully
Assignee: Gary Tully
 Fix For: 5.9.0


 The locker interface needs another configure option to provide a broker 
 service, or needs to be brokerService aware so that a locker can get identity 
 and access to the io exception handlers.
 The lease database locker is dependent on the jdbc pa to get statements and 
 data source. It should be possible to configure these independently such that 
 it can be used standalone as a broker lock. So setters for each.
 This will help sort out some of the dependencies between broker and lock 
 implementations. also making it possible to use a lease lock with kahadb for 
 example.
 some context: 
 http://mail-archives.apache.org/mod_mbox/activemq-users/201303.mbox/%3ccaj5znhuruz+aewsaabajtwbbpkwn06ryyyt6nqsdg_su7vm...@mail.gmail.com%3E

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Commented] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-20 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4674?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13745128#comment-13745128
 ] 

Paul Gale commented on AMQ-4674:


I think something has gone awry here. This implementation of a 'grace period' 
doesn't really help. 

What I am observing, after configuring the grace period with a value of 1.5, is 
that when a client connects (simplified):

CONNECT
heart-beat:5000,0

the broker responds with:

CONNECTED
heart-beat:0,7500

which is incorrect. The grace period multiplier should NOT affect the broker's 
response. The broker should have responded with 5000. 

The client therefore honors the broker's inflated interval (per the STOMP spec) 
and sends a read check every 7500ms. 

The broker, meanwhile, applies the grace period multiplier, a second time, to 
its inflated read check interval. In this case, it now performs a read check 
every 11250ms (as shown in the DEBUG logging of the AbstractInactivityMonitor).

With the client idle the broker's activemq.log contains TRACE log entries that 
read A receive is in progress every 11250ms. I presume this is the 
ReadCheckTimer handling the read check sent from the client? If so, the log 
output could be a little more descriptive.





 ActiveMQ 5.x does not support the notion of a grace-period for heart beats as 
 supported by the STOMP protocol
 -

 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: Bug
Affects Versions: 5.8.0
Reporter: Paul Gale
Assignee: Timothy Bish
  Labels: easyfix
 Fix For: 5.9.0


 Regarding the configuration of heart beating the STOMP protocol spec states:
 - because of timing inaccuracies, the receiver SHOULD be tolerant and 
 take into account an error margin
 However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 
 Despite the fact that the spec says SHOULD rather than MUST it would make the 
 implementation of STOMP clients easier if the error margin was published.
 As the broker aggressively enforces the heart beat timeouts false failover 
 attempts can result.
 Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
 If it could be made configurable that would be even better! 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Commented] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-20 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4674?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13745438#comment-13745438
 ] 

Paul Gale commented on AMQ-4674:


I have no idea how to write unit tests for ActiveMQ and this section of code in 
particular. 

Unfortunately I could not find any unit tests for this feature which is 
surprising given that it was added just the other day. How was it tested? It's 
a tad galling to be asked for some tests now.

I don't mind modifying existing tests though. However, my personal experience 
with the unit test codebase is that they're rather flaky; they almost never 
pass whenever I've tried to run them which doesn't exactly entice me into 
wanting to try now.

Nonetheless, from a quick analysis of the code it would appear that the 
offending code is in 
activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/ProtocolConverter.java
 at line 929:

hbReadInterval = (long) (Long.parseLong(keepAliveOpts[0]) * 
hbGracePeriodMultiplier); // Wrong!

should be:

hbReadInterval = (long) Long.parseLong(keepAliveOpts[0]); //  Honor the 
client's read interval

where keepAliveOpts[0] is the client specified heartbeat read-interval.

When the inactivity monitor's read check time is calculated it's done correctly:

StompInactivityMonitor monitor = this.stompTransport.getInactivityMonitor();
monitor.setReadCheckTime((long) (hbReadInterval * hbGracePeriodMultiplier));  
// Correct
monitor.setInitialDelayTime(Math.min(hbReadInterval, hbWriteInterval));
monitor.setWriteCheckTime(hbWriteInterval);
monitor.startMonitoring();



Setup:keepAliveOpts[0] = 5000, hbGracePeriodMultiplier = 1.5

Expected: hbReadInterval == 5000, monitor.getReadCheckTime() == 7500
Actual:   hbReadInterval == 7500, monitor.getReadCheckTime() == 11250



 ActiveMQ 5.x does not support the notion of a grace-period for heart beats as 
 supported by the STOMP protocol
 -

 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: Bug
Affects Versions: 5.8.0
Reporter: Paul Gale
Assignee: Timothy Bish
  Labels: easyfix
 Fix For: 5.9.0


 Regarding the configuration of heart beating the STOMP protocol spec states:
 - because of timing inaccuracies, the receiver SHOULD be tolerant and 
 take into account an error margin
 However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 
 Despite the fact that the spec says SHOULD rather than MUST it would make the 
 implementation of STOMP clients easier if the error margin was published.
 As the broker aggressively enforces the heart beat timeouts false failover 
 attempts can result.
 Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
 If it could be made configurable that would be even better! 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Comment Edited] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-20 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4674?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13745438#comment-13745438
 ] 

Paul Gale edited comment on AMQ-4674 at 8/20/13 9:21 PM:
-

I have no idea how to write unit tests for ActiveMQ and this section of code in 
particular. 

Unfortunately I could not find any unit tests for this feature which is 
surprising given that it was added just the other day. How was it tested? It's 
a tad galling to be asked for some tests now.

I don't mind modifying existing tests though. However, my personal experience 
with the unit test codebase is that they're rather flaky; they almost never 
pass whenever I've tried to run them which doesn't exactly entice me into 
wanting to try now.

Nonetheless, from a quick analysis of the code it would appear that the 
offending code is in 
activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/ProtocolConverter.java
 at line 929:

{code:java|borderStyle=solid}
hbReadInterval = (long) (Long.parseLong(keepAliveOpts[0]) * 
hbGracePeriodMultiplier); // Wrong!
{code}

should be:

{code:java|borderStyle=solid}
hbReadInterval = (long) Long.parseLong(keepAliveOpts[0]); //  Honor the 
client's read interval
{code}

where keepAliveOpts[0] is the client specified heartbeat read-interval.

When the inactivity monitor's read check time is calculated it's done correctly:

{code:java|borderStyle=solid}
StompInactivityMonitor monitor = this.stompTransport.getInactivityMonitor();
monitor.setReadCheckTime((long) (hbReadInterval * hbGracePeriodMultiplier));  
// Correct
monitor.setInitialDelayTime(Math.min(hbReadInterval, hbWriteInterval));
monitor.setWriteCheckTime(hbWriteInterval);
monitor.startMonitoring();
{code}


Setup:keepAliveOpts[0] = 5000, hbGracePeriodMultiplier = 1.5

Expected: hbReadInterval == 5000, monitor.getReadCheckTime() == 7500
Actual:   hbReadInterval == 7500, monitor.getReadCheckTime() == 11250



  was (Author: paulgale):
I have no idea how to write unit tests for ActiveMQ and this section of 
code in particular. 

Unfortunately I could not find any unit tests for this feature which is 
surprising given that it was added just the other day. How was it tested? It's 
a tad galling to be asked for some tests now.

I don't mind modifying existing tests though. However, my personal experience 
with the unit test codebase is that they're rather flaky; they almost never 
pass whenever I've tried to run them which doesn't exactly entice me into 
wanting to try now.

Nonetheless, from a quick analysis of the code it would appear that the 
offending code is in 
activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/ProtocolConverter.java
 at line 929:

hbReadInterval = (long) (Long.parseLong(keepAliveOpts[0]) * 
hbGracePeriodMultiplier); // Wrong!

should be:

hbReadInterval = (long) Long.parseLong(keepAliveOpts[0]); //  Honor the 
client's read interval

where keepAliveOpts[0] is the client specified heartbeat read-interval.

When the inactivity monitor's read check time is calculated it's done correctly:

StompInactivityMonitor monitor = this.stompTransport.getInactivityMonitor();
monitor.setReadCheckTime((long) (hbReadInterval * hbGracePeriodMultiplier));  
// Correct
monitor.setInitialDelayTime(Math.min(hbReadInterval, hbWriteInterval));
monitor.setWriteCheckTime(hbWriteInterval);
monitor.startMonitoring();



Setup:keepAliveOpts[0] = 5000, hbGracePeriodMultiplier = 1.5

Expected: hbReadInterval == 5000, monitor.getReadCheckTime() == 7500
Actual:   hbReadInterval == 7500, monitor.getReadCheckTime() == 11250


  
 ActiveMQ 5.x does not support the notion of a grace-period for heart beats as 
 supported by the STOMP protocol
 -

 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: Bug
Affects Versions: 5.8.0
Reporter: Paul Gale
Assignee: Timothy Bish
  Labels: easyfix
 Fix For: 5.9.0


 Regarding the configuration of heart beating the STOMP protocol spec states:
 - because of timing inaccuracies, the receiver SHOULD be tolerant and 
 take into account an error margin
 However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 
 Despite the fact that the spec says SHOULD rather than MUST it would make the 
 implementation of STOMP clients easier if the error margin was published.
 As the broker aggressively enforces the heart beat timeouts false failover 
 attempts can result.
 Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
 If it could be made configurable that would be even better! 

--
This message is automatically generated by JIRA.
If you 

[jira] [Comment Edited] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-20 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4674?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13745438#comment-13745438
 ] 

Paul Gale edited comment on AMQ-4674 at 8/20/13 9:22 PM:
-

I have no idea how to write unit tests for ActiveMQ and this section of code in 
particular. 

Unfortunately I could not find any unit tests for this feature which is 
surprising given that it was added just the other day. How was it tested? It's 
a tad galling to be asked for some tests now.

I don't mind modifying existing tests though. However, my personal experience 
with the unit test codebase is that they're rather flaky; they almost never 
pass whenever I've tried to run them which doesn't exactly entice me into 
wanting to try now.

Nonetheless, from a quick analysis of the code it would appear that the 
offending code is in 
activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/ProtocolConverter.java
 at line 929:

{code:java|borderStyle=solid}
hbReadInterval = (long) (Long.parseLong(keepAliveOpts[0]) * 
hbGracePeriodMultiplier); // Wrong!
{code}

should be:


{code:java|borderStyle=solid}
hbReadInterval = (long) Long.parseLong(keepAliveOpts[0]); //  Honor the 
client's read interval
{code}

where keepAliveOpts[0] is the client specified heartbeat read-interval.

When the inactivity monitor's read check time is calculated it's done correctly:


{code:java|borderStyle=solid}
StompInactivityMonitor monitor = this.stompTransport.getInactivityMonitor();
monitor.setReadCheckTime((long) (hbReadInterval * hbGracePeriodMultiplier));  
// Correct
monitor.setInitialDelayTime(Math.min(hbReadInterval, hbWriteInterval));
monitor.setWriteCheckTime(hbWriteInterval);
monitor.startMonitoring();
{code}

Setup:keepAliveOpts[0] = 5000, hbGracePeriodMultiplier = 1.5

Expected: hbReadInterval == 5000, monitor.getReadCheckTime() == 7500
Actual:   hbReadInterval == 7500, monitor.getReadCheckTime() == 11250



  was (Author: paulgale):
I have no idea how to write unit tests for ActiveMQ and this section of 
code in particular. 

Unfortunately I could not find any unit tests for this feature which is 
surprising given that it was added just the other day. How was it tested? It's 
a tad galling to be asked for some tests now.

I don't mind modifying existing tests though. However, my personal experience 
with the unit test codebase is that they're rather flaky; they almost never 
pass whenever I've tried to run them which doesn't exactly entice me into 
wanting to try now.

Nonetheless, from a quick analysis of the code it would appear that the 
offending code is in 
activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/ProtocolConverter.java
 at line 929:

{code:java|borderStyle=solid}
hbReadInterval = (long) (Long.parseLong(keepAliveOpts[0]) * 
hbGracePeriodMultiplier); // Wrong!
{code}

should be:

{code:java|borderStyle=solid}
hbReadInterval = (long) Long.parseLong(keepAliveOpts[0]); //  Honor the 
client's read interval
{code}

where keepAliveOpts[0] is the client specified heartbeat read-interval.

When the inactivity monitor's read check time is calculated it's done correctly:

{code:java|borderStyle=solid}
StompInactivityMonitor monitor = this.stompTransport.getInactivityMonitor();
monitor.setReadCheckTime((long) (hbReadInterval * hbGracePeriodMultiplier));  
// Correct
monitor.setInitialDelayTime(Math.min(hbReadInterval, hbWriteInterval));
monitor.setWriteCheckTime(hbWriteInterval);
monitor.startMonitoring();
{code}


Setup:keepAliveOpts[0] = 5000, hbGracePeriodMultiplier = 1.5

Expected: hbReadInterval == 5000, monitor.getReadCheckTime() == 7500
Actual:   hbReadInterval == 7500, monitor.getReadCheckTime() == 11250


  
 ActiveMQ 5.x does not support the notion of a grace-period for heart beats as 
 supported by the STOMP protocol
 -

 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: Bug
Affects Versions: 5.8.0
Reporter: Paul Gale
Assignee: Timothy Bish
  Labels: easyfix
 Fix For: 5.9.0


 Regarding the configuration of heart beating the STOMP protocol spec states:
 - because of timing inaccuracies, the receiver SHOULD be tolerant and 
 take into account an error margin
 However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 
 Despite the fact that the spec says SHOULD rather than MUST it would make the 
 implementation of STOMP clients easier if the error margin was published.
 As the broker aggressively enforces the heart beat timeouts false failover 
 attempts can result.
 Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
 If it could 

[jira] [Comment Edited] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-20 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4674?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13745438#comment-13745438
 ] 

Paul Gale edited comment on AMQ-4674 at 8/20/13 9:24 PM:
-

I have no idea how to write unit tests for ActiveMQ and this section of code in 
particular. 

Unfortunately I could not find any unit tests for this feature which is 
surprising given that it was added just the other day. How was it tested? It's 
a tad galling to be asked for some tests now.

I don't mind modifying existing tests though. However, my personal experience 
with the unit test codebase is that they're rather flaky; they almost never 
pass whenever I've tried to run them which doesn't exactly entice me into 
wanting to try now.

Nonetheless, from a quick analysis of the code it would appear that the 
offending code is in 
activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/ProtocolConverter.java
 at line 929:
\\
{code:java|borderStyle=solid}
hbReadInterval = (long) (Long.parseLong(keepAliveOpts[0]) * 
hbGracePeriodMultiplier); // Wrong!
{code}

should be:
\\
{code:java|borderStyle=solid}
hbReadInterval = (long) Long.parseLong(keepAliveOpts[0]); //  Honor the 
client's read interval
{code}

where keepAliveOpts[0] is the client specified heartbeat read-interval.

When the inactivity monitor's read check time is calculated it's done correctly:
\\
{code:java|borderStyle=solid}
StompInactivityMonitor monitor = this.stompTransport.getInactivityMonitor();
monitor.setReadCheckTime((long) (hbReadInterval * hbGracePeriodMultiplier));  
// Correct
monitor.setInitialDelayTime(Math.min(hbReadInterval, hbWriteInterval));
monitor.setWriteCheckTime(hbWriteInterval);
monitor.startMonitoring();
{code}

{noformat}
Setup:keepAliveOpts[0] = 5000, hbGracePeriodMultiplier = 1.5

Expected: hbReadInterval == 5000, monitor.getReadCheckTime() == 7500
Actual:   hbReadInterval == 7500, monitor.getReadCheckTime() == 11250
{noformat}


  was (Author: paulgale):
I have no idea how to write unit tests for ActiveMQ and this section of 
code in particular. 

Unfortunately I could not find any unit tests for this feature which is 
surprising given that it was added just the other day. How was it tested? It's 
a tad galling to be asked for some tests now.

I don't mind modifying existing tests though. However, my personal experience 
with the unit test codebase is that they're rather flaky; they almost never 
pass whenever I've tried to run them which doesn't exactly entice me into 
wanting to try now.

Nonetheless, from a quick analysis of the code it would appear that the 
offending code is in 
activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/ProtocolConverter.java
 at line 929:

{code:java|borderStyle=solid}
hbReadInterval = (long) (Long.parseLong(keepAliveOpts[0]) * 
hbGracePeriodMultiplier); // Wrong!
{code}

should be:


{code:java|borderStyle=solid}
hbReadInterval = (long) Long.parseLong(keepAliveOpts[0]); //  Honor the 
client's read interval
{code}

where keepAliveOpts[0] is the client specified heartbeat read-interval.

When the inactivity monitor's read check time is calculated it's done correctly:


{code:java|borderStyle=solid}
StompInactivityMonitor monitor = this.stompTransport.getInactivityMonitor();
monitor.setReadCheckTime((long) (hbReadInterval * hbGracePeriodMultiplier));  
// Correct
monitor.setInitialDelayTime(Math.min(hbReadInterval, hbWriteInterval));
monitor.setWriteCheckTime(hbWriteInterval);
monitor.startMonitoring();
{code}

Setup:keepAliveOpts[0] = 5000, hbGracePeriodMultiplier = 1.5

Expected: hbReadInterval == 5000, monitor.getReadCheckTime() == 7500
Actual:   hbReadInterval == 7500, monitor.getReadCheckTime() == 11250


  
 ActiveMQ 5.x does not support the notion of a grace-period for heart beats as 
 supported by the STOMP protocol
 -

 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: Bug
Affects Versions: 5.8.0
Reporter: Paul Gale
Assignee: Timothy Bish
  Labels: easyfix
 Fix For: 5.9.0


 Regarding the configuration of heart beating the STOMP protocol spec states:
 - because of timing inaccuracies, the receiver SHOULD be tolerant and 
 take into account an error margin
 However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 
 Despite the fact that the spec says SHOULD rather than MUST it would make the 
 implementation of STOMP clients easier if the error margin was published.
 As the broker aggressively enforces the heart beat timeouts false failover 
 attempts can result.
 Apparently Apollo supports an error margin of 1.5x the configured 

[jira] [Created] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-07 Thread Paul Gale (JIRA)
Paul Gale created AMQ-4674:
--

 Summary: ActiveMQ 5.x does not support the notion of a 
grace-period for heart beats as supported by the STOMP protocol
 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: New Feature
Affects Versions: 5.8.0
Reporter: Paul Gale
 Fix For: NEEDS_REVIEWED


Regarding the configuration of heart beating the STOMP protocol spec states:

- because of timing inaccuracies, the receiver SHOULD be tolerant and take 
into account an error margin

However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 

Despite the fact that the spec says SHOULD rather than MUST it would make the 
implementation of STOMP clients easier if the error margin was published.

Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
If it could be made configurable that would be even better! 


--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-07 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4674?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4674:
---

Fix Version/s: (was: NEEDS_REVIEWED)
   5.9.0

 ActiveMQ 5.x does not support the notion of a grace-period for heart beats as 
 supported by the STOMP protocol
 -

 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: Bug
Affects Versions: 5.8.0
Reporter: Paul Gale
  Labels: easyfix
 Fix For: 5.9.0


 Regarding the configuration of heart beating the STOMP protocol spec states:
 - because of timing inaccuracies, the receiver SHOULD be tolerant and 
 take into account an error margin
 However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 
 Despite the fact that the spec says SHOULD rather than MUST it would make the 
 implementation of STOMP clients easier if the error margin was published.
 Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
 If it could be made configurable that would be even better! 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-07 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4674?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4674:
---

Issue Type: Bug  (was: New Feature)

 ActiveMQ 5.x does not support the notion of a grace-period for heart beats as 
 supported by the STOMP protocol
 -

 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: Bug
Affects Versions: 5.8.0
Reporter: Paul Gale
  Labels: easyfix
 Fix For: NEEDS_REVIEWED


 Regarding the configuration of heart beating the STOMP protocol spec states:
 - because of timing inaccuracies, the receiver SHOULD be tolerant and 
 take into account an error margin
 However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 
 Despite the fact that the spec says SHOULD rather than MUST it would make the 
 implementation of STOMP clients easier if the error margin was published.
 Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
 If it could be made configurable that would be even better! 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Updated] (AMQ-4674) ActiveMQ 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol

2013-08-07 Thread Paul Gale (JIRA)

 [ 
https://issues.apache.org/jira/browse/AMQ-4674?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Gale updated AMQ-4674:
---

Description: 
Regarding the configuration of heart beating the STOMP protocol spec states:

- because of timing inaccuracies, the receiver SHOULD be tolerant and take 
into account an error margin

However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 

Despite the fact that the spec says SHOULD rather than MUST it would make the 
implementation of STOMP clients easier if the error margin was published.

As the broker aggressively enforces the heart beat timeouts false failover 
attempts can result.

Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
If it could be made configurable that would be even better! 


  was:
Regarding the configuration of heart beating the STOMP protocol spec states:

- because of timing inaccuracies, the receiver SHOULD be tolerant and take 
into account an error margin

However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 

Despite the fact that the spec says SHOULD rather than MUST it would make the 
implementation of STOMP clients easier if the error margin was published.

Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
If it could be made configurable that would be even better! 



 ActiveMQ 5.x does not support the notion of a grace-period for heart beats as 
 supported by the STOMP protocol
 -

 Key: AMQ-4674
 URL: https://issues.apache.org/jira/browse/AMQ-4674
 Project: ActiveMQ
  Issue Type: Bug
Affects Versions: 5.8.0
Reporter: Paul Gale
  Labels: easyfix
 Fix For: 5.9.0


 Regarding the configuration of heart beating the STOMP protocol spec states:
 - because of timing inaccuracies, the receiver SHOULD be tolerant and 
 take into account an error margin
 However, it appears that ActiveMQ 5.x is not tolerant of any error margin. 
 Despite the fact that the spec says SHOULD rather than MUST it would make the 
 implementation of STOMP clients easier if the error margin was published.
 As the broker aggressively enforces the heart beat timeouts false failover 
 attempts can result.
 Apparently Apollo supports an error margin of 1.5x the configured heart beat. 
 If it could be made configurable that would be even better! 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Commented] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a broker lock

2013-03-08 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13597342#comment-13597342
 ] 

Paul Gale commented on AMQ-4365:


So I've been able to get a first cut at a lease database locker that works with 
the KahaDBPersistenceAdapter, as shown below. This is by no means the ideal 
solution but it works. Feedback welcome.

Longer term, the signature of the configure method should be changed; there is 
no reason that I can see why it should be coupled to a PersistenceAdapter - 
that's too broad. Either provide a few overloaded versions of configure() with 
various arguments that a locker might require or create an interface to be 
implemented by a persistence provider that makes the contract between the two 
more explicit.


public class MyLeaseDatabaseLocker extends LeaseDatabaseLocker implements 
BrokerServiceAware, LockDataSourceCapable {
  private static final Logger LOG = 
LoggerFactory.getLogger(MyLeaseDatabaseLocker.class);
  protected BrokerService brokerService;

  @Override
  public void configure(PersistenceAdapter ignore) throws IOException {
this.statements = new Statements();
  }

  @Override
  public boolean keepAlive() throws IOException {
boolean result = false;
final String sql = statements.getLeaseUpdateStatement();

LOG.debug(getLeaseHolderId() + , lease keepAlive Query is  + sql);

Connection connection = null;
PreparedStatement statement = null;

try {
  connection = getConnection();

  initTimeDiff(connection);
  statement = connection.prepareStatement(sql);
  setQueryTimeout(statement);

  final long now = System.currentTimeMillis() + diffFromCurrentTime;
  statement.setString(1, getLeaseHolderId());
  statement.setLong(2, now + lockAcquireSleepInterval);
  statement.setString(3, getLeaseHolderId());

  result = (statement.executeUpdate() == 1);
}
catch(Exception e) {
  LOG.warn(getLeaseHolderId() + , failed to update lease:  + e, e);
  IOException ioe = IOExceptionSupport.create(e);
  brokerService.handleIOException(ioe);
  throw ioe;
}
finally {
  close(statement);
  close(connection);
}

return result;
  }

  @Override
  public void setBrokerService(BrokerService brokerService) {
this.brokerService = brokerService;
  }

  @Override
  public String getLeaseHolderId() {
if(leaseHolderId == null  brokerService != null) {
  leaseHolderId = brokerService.getBrokerName();
}

return leaseHolderId;
  }

  @Override
  public void setLockDataSource(DataSource lockDataSource) {
this.dataSource = lockDataSource;
  }

  @Override
  public DataSource getLockDataSource() {
return this.dataSource;
  }

  private void setQueryTimeout(PreparedStatement statement) throws SQLException 
{
if(queryTimeout  0) {
  statement.setQueryTimeout(queryTimeout);
}
  }

  private Connection getConnection() throws SQLException {
return dataSource.getConnection();
  }

  private void close(Connection connection) {
if(null == connection) return;

try {
  connection.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() +  caught exception while closing 
connection:  + e1, e1);
}
  }

  private void close(PreparedStatement statement) {
if(null == statement) return;

try {
  statement.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() + , caught while closing statement:  + e1, 
e1);
}
  }
}


public interface LockDataSourceCapable {
  public void setLockDataSource(DataSource lockDataSource);
  public DataSource getLockDataSource();
}

The activemq.xml (with parts removed) is as follows:

beans
xmlns=http://www.springframework.org/schema/beans;
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance;
xsi:schemaLocation=http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core

http://activemq.apache.org/schema/core/activemq-core.xsd;

  broker xmlns=http://activemq.apache.org/schema/core;
  id=theBroker

persistenceAdapter
  kahaDB directory=${activemq.data}/kahadb
  lockKeepAlivePeriod=2500
  useLock=true
locker
  bean xmlns=http://www.springframework.org/schema/beans;
class=com.example.activemq.MyLeaseDatabaseLocker
property name=lockDataSource ref=mysql-ds/
property name=brokerService ref=theBroker/
property name=failIfLocked value=false/
property name=lockAcquireSleepInterval value=5000/
  /bean
/locker
  /kahaDB
/persistenceAdapter

  /broker

  bean id=mysql-ds
class=org.apache.commons.dbcp.BasicDataSource
destroy-method=close
property 

[jira] [Comment Edited] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a broker lock

2013-03-08 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13597342#comment-13597342
 ] 

Paul Gale edited comment on AMQ-4365 at 3/8/13 6:03 PM:


So I've been able to get a first cut at a lease database locker that works with 
the KahaDBPersistenceAdapter, as shown below. This is by no means the ideal 
solution but it works. Feedback welcome.

Longer term, the signature of the configure method should be changed; there is 
no reason that I can see why it should be coupled to a PersistenceAdapter - 
that's too broad. Either provide a few overloaded versions of configure() with 
various arguments that a locker might require or create an interface to be 
implemented by a persistence provider that makes the contract between the two 
more explicit.

{code:title=MyLeaseDatabaseLocker.java|borderStyle=solid}
public class MyLeaseDatabaseLocker extends LeaseDatabaseLocker implements 
BrokerServiceAware, LockDataSourceCapable {
  private static final Logger LOG = 
LoggerFactory.getLogger(MyLeaseDatabaseLocker.class);
  protected BrokerService brokerService;

  @Override
  public void configure(PersistenceAdapter ignore) throws IOException {
this.statements = new Statements();
  }

  @Override
  public boolean keepAlive() throws IOException {
boolean result = false;
final String sql = statements.getLeaseUpdateStatement();

LOG.debug(getLeaseHolderId() + , lease keepAlive Query is  + sql);

Connection connection = null;
PreparedStatement statement = null;

try {
  connection = getConnection();

  initTimeDiff(connection);
  statement = connection.prepareStatement(sql);
  setQueryTimeout(statement);

  final long now = System.currentTimeMillis() + diffFromCurrentTime;
  statement.setString(1, getLeaseHolderId());
  statement.setLong(2, now + lockAcquireSleepInterval);
  statement.setString(3, getLeaseHolderId());

  result = (statement.executeUpdate() == 1);
}
catch(Exception e) {
  LOG.warn(getLeaseHolderId() + , failed to update lease:  + e, e);
  IOException ioe = IOExceptionSupport.create(e);
  brokerService.handleIOException(ioe);
  throw ioe;
}
finally {
  close(statement);
  close(connection);
}

return result;
  }

  @Override
  public void setBrokerService(BrokerService brokerService) {
this.brokerService = brokerService;
  }

  @Override
  public String getLeaseHolderId() {
if(leaseHolderId == null  brokerService != null) {
  leaseHolderId = brokerService.getBrokerName();
}

return leaseHolderId;
  }

  @Override
  public void setLockDataSource(DataSource lockDataSource) {
this.dataSource = lockDataSource;
  }

  @Override
  public DataSource getLockDataSource() {
return this.dataSource;
  }

  private void setQueryTimeout(PreparedStatement statement) throws SQLException 
{
if(queryTimeout  0) {
  statement.setQueryTimeout(queryTimeout);
}
  }

  private Connection getConnection() throws SQLException {
return dataSource.getConnection();
  }

  private void close(Connection connection) {
if(null == connection) return;

try {
  connection.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() +  caught exception while closing 
connection:  + e1, e1);
}
  }

  private void close(PreparedStatement statement) {
if(null == statement) return;

try {
  statement.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() + , caught while closing statement:  + e1, 
e1);
}
  }
}
{code}

{code:title=LockDataSourceCapable.java|borderStyle=solid}
public interface LockDataSourceCapable {
  public void setLockDataSource(DataSource lockDataSource);
  public DataSource getLockDataSource();
}
{code}

The activemq.xml (with parts removed) is as follows:

{code:xml}
beans
xmlns=http://www.springframework.org/schema/beans;
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance;
xsi:schemaLocation=http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core

http://activemq.apache.org/schema/core/activemq-core.xsd;

  broker xmlns=http://activemq.apache.org/schema/core;
  id=theBroker

persistenceAdapter
  kahaDB directory=${activemq.data}/kahadb
  lockKeepAlivePeriod=2500
  useLock=true
locker
  bean xmlns=http://www.springframework.org/schema/beans;
class=com.example.activemq.MyLeaseDatabaseLocker
property name=lockDataSource ref=mysql-ds/
property name=brokerService ref=theBroker/
property name=failIfLocked value=false/
property name=lockAcquireSleepInterval value=5000/
  

[jira] [Comment Edited] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a broker lock

2013-03-08 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13597342#comment-13597342
 ] 

Paul Gale edited comment on AMQ-4365 at 3/8/13 6:07 PM:


So I've been able to get a first cut at a lease database locker that works with 
the KahaDBPersistenceAdapter, as shown below. This is by no means the ideal 
solution but it works. Feedback welcome.

Longer term, the signature of the configure method should be changed; there is 
no reason that I can see why it should be coupled to a PersistenceAdapter - 
that's too broad. Either provide a few overloaded versions of configure() with 
various arguments that a locker might require or create an interface to be 
implemented by a persistence provider that makes the contract between the two 
more explicit.


{code:title=MyLeaseDatabaseLocker.java}
public class MyLeaseDatabaseLocker extends LeaseDatabaseLocker implements 
BrokerServiceAware, LockDataSourceCapable {
  private static final Logger LOG = 
LoggerFactory.getLogger(MyLeaseDatabaseLocker.class);
  protected BrokerService brokerService;

  @Override
  public void configure(PersistenceAdapter ignore) throws IOException {
this.statements = new Statements();
  }

  @Override
  public boolean keepAlive() throws IOException {
boolean result = false;
final String sql = statements.getLeaseUpdateStatement();

LOG.debug(getLeaseHolderId() + , lease keepAlive Query is  + sql);

Connection connection = null;
PreparedStatement statement = null;

try {
  connection = getConnection();

  initTimeDiff(connection);
  statement = connection.prepareStatement(sql);
  setQueryTimeout(statement);

  final long now = System.currentTimeMillis() + diffFromCurrentTime;
  statement.setString(1, getLeaseHolderId());
  statement.setLong(2, now + lockAcquireSleepInterval);
  statement.setString(3, getLeaseHolderId());

  result = (statement.executeUpdate() == 1);
}
catch(Exception e) {
  LOG.warn(getLeaseHolderId() + , failed to update lease:  + e, e);
  IOException ioe = IOExceptionSupport.create(e);
  brokerService.handleIOException(ioe);
  throw ioe;
}
finally {
  close(statement);
  close(connection);
}

return result;
  }

  @Override
  public void setBrokerService(BrokerService brokerService) {
this.brokerService = brokerService;
  }

  @Override
  public String getLeaseHolderId() {
if(leaseHolderId == null  brokerService != null) {
  leaseHolderId = brokerService.getBrokerName();
}

return leaseHolderId;
  }

  @Override
  public void setLockDataSource(DataSource lockDataSource) {
this.dataSource = lockDataSource;
  }

  @Override
  public DataSource getLockDataSource() {
return this.dataSource;
  }

  private void setQueryTimeout(PreparedStatement statement) throws SQLException 
{
if(queryTimeout  0) {
  statement.setQueryTimeout(queryTimeout);
}
  }

  private Connection getConnection() throws SQLException {
return dataSource.getConnection();
  }

  private void close(Connection connection) {
if(null == connection) return;

try {
  connection.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() +  caught exception while closing 
connection:  + e1, e1);
}
  }

  private void close(PreparedStatement statement) {
if(null == statement) return;

try {
  statement.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() + , caught while closing statement:  + e1, 
e1);
}
  }
}
{code}

{code:title=LockDataSourceCapable.java}
public interface LockDataSourceCapable {
  public void setLockDataSource(DataSource lockDataSource);
  public DataSource getLockDataSource();
}
{code}

{code:xml:title=activemq.xml (with parts removed)}
beans
xmlns=http://www.springframework.org/schema/beans;
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance;
xsi:schemaLocation=http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core

http://activemq.apache.org/schema/core/activemq-core.xsd;

  broker xmlns=http://activemq.apache.org/schema/core;
  id=theBroker

persistenceAdapter
  kahaDB directory=${activemq.data}/kahadb
  lockKeepAlivePeriod=2500
  useLock=true
locker
  bean xmlns=http://www.springframework.org/schema/beans;
class=com.example.activemq.MyLeaseDatabaseLocker
property name=lockDataSource ref=mysql-ds/
property name=brokerService ref=theBroker/
property name=failIfLocked value=false/
property name=lockAcquireSleepInterval value=5000/
  /bean
/locker
  /kahaDB

[jira] [Comment Edited] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a broker lock

2013-03-08 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13597342#comment-13597342
 ] 

Paul Gale edited comment on AMQ-4365 at 3/8/13 6:10 PM:


So I've been able to get a first cut at a lease database locker that works with 
the KahaDBPersistenceAdapter, as shown below. This is by no means the ideal 
solution but it works. Feedback welcome.

Longer term, the signature of the configure method should be changed; there is 
no reason that I can see why it should be coupled to a PersistenceAdapter - 
that's too broad. Either provide a few overloaded versions of configure() with 
various arguments that a locker might require or create an interface to be 
implemented by a persistence provider that makes the contract between the two 
more explicit.
\\
\\
{code:title=MyLeaseDatabaseLocker.java}
public class MyLeaseDatabaseLocker extends LeaseDatabaseLocker implements 
BrokerServiceAware, LockDataSourceCapable {
  private static final Logger LOG = 
LoggerFactory.getLogger(MyLeaseDatabaseLocker.class);
  protected BrokerService brokerService;

  @Override
  public void configure(PersistenceAdapter ignore) throws IOException {
this.statements = new Statements();
  }

  @Override
  public boolean keepAlive() throws IOException {
boolean result = false;
final String sql = statements.getLeaseUpdateStatement();

LOG.debug(getLeaseHolderId() + , lease keepAlive Query is  + sql);

Connection connection = null;
PreparedStatement statement = null;

try {
  connection = getConnection();

  initTimeDiff(connection);
  statement = connection.prepareStatement(sql);
  setQueryTimeout(statement);

  final long now = System.currentTimeMillis() + diffFromCurrentTime;
  statement.setString(1, getLeaseHolderId());
  statement.setLong(2, now + lockAcquireSleepInterval);
  statement.setString(3, getLeaseHolderId());

  result = (statement.executeUpdate() == 1);
}
catch(Exception e) {
  LOG.warn(getLeaseHolderId() + , failed to update lease:  + e, e);
  IOException ioe = IOExceptionSupport.create(e);
  brokerService.handleIOException(ioe);
  throw ioe;
}
finally {
  close(statement);
  close(connection);
}

return result;
  }

  @Override
  public void setBrokerService(BrokerService brokerService) {
this.brokerService = brokerService;
  }

  @Override
  public String getLeaseHolderId() {
if(leaseHolderId == null  brokerService != null) {
  leaseHolderId = brokerService.getBrokerName();
}

return leaseHolderId;
  }

  @Override
  public void setLockDataSource(DataSource lockDataSource) {
this.dataSource = lockDataSource;
  }

  @Override
  public DataSource getLockDataSource() {
return this.dataSource;
  }

  private void setQueryTimeout(PreparedStatement statement) throws SQLException 
{
if(queryTimeout  0) {
  statement.setQueryTimeout(queryTimeout);
}
  }

  private Connection getConnection() throws SQLException {
return dataSource.getConnection();
  }

  private void close(Connection connection) {
if(null == connection) return;

try {
  connection.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() +  caught exception while closing 
connection:  + e1, e1);
}
  }

  private void close(PreparedStatement statement) {
if(null == statement) return;

try {
  statement.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() + , caught while closing statement:  + e1, 
e1);
}
  }
}
{code}

{code:title=LockDataSourceCapable.java}
public interface LockDataSourceCapable {
  public void setLockDataSource(DataSource lockDataSource);
  public DataSource getLockDataSource();
}
{code}

{code:xml|title=activemq.xml (with parts removed)}
beans
xmlns=http://www.springframework.org/schema/beans;
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance;
xsi:schemaLocation=http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core

http://activemq.apache.org/schema/core/activemq-core.xsd;

  broker xmlns=http://activemq.apache.org/schema/core;
  id=theBroker

persistenceAdapter
  kahaDB directory=${activemq.data}/kahadb
  lockKeepAlivePeriod=2500
  useLock=true
locker
  bean xmlns=http://www.springframework.org/schema/beans;
class=com.example.activemq.MyLeaseDatabaseLocker
property name=lockDataSource ref=mysql-ds/
property name=brokerService ref=theBroker/
property name=failIfLocked value=false/
property name=lockAcquireSleepInterval value=5000/
  /bean
/locker
  /kahaDB

[jira] [Commented] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a broker lock

2013-03-08 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13597376#comment-13597376
 ] 

Paul Gale commented on AMQ-4365:


Another point worth noting is that the JDBCPersistenAdapter creates the lock 
table in the database during initialization. As I had previously used this 
adapter the tables were already in the database. Therefore testing my custom 
lease database locker went smoothly. However anyone that uses the above 
implementation as-is will get an error if the tables are not there.

Ideally the locker, not the persistence adapter, should be responsible for 
managing the creation of its own lock table. I have not addressed this and 
probably won't. For now I can live with a SQL script to create the schema.

 Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it 
 can be a broker lock
 

 Key: AMQ-4365
 URL: https://issues.apache.org/jira/browse/AMQ-4365
 Project: ActiveMQ
  Issue Type: Improvement
Affects Versions: 5.8.0
Reporter: Gary Tully
 Fix For: 5.9.0


 The locker interface needs another configure option to provide a broker 
 service, or needs to be brokerService aware so that a locker can get identity 
 and access to the io exception handlers.
 The lease database locker is dependent on the jdbc pa to get statements and 
 data source. It should be possible to configure these independently such that 
 it can be used standalone as a broker lock. So setters for each.
 This will help sort out some of the dependencies between broker and lock 
 implementations. also making it possible to use a lease lock with kahadb for 
 example.
 some context: 
 http://mail-archives.apache.org/mod_mbox/activemq-users/201303.mbox/%3ccaj5znhuruz+aewsaabajtwbbpkwn06ryyyt6nqsdg_su7vm...@mail.gmail.com%3E

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


[jira] [Comment Edited] (AMQ-4365) Allow the Lease Locker to be used with out a JDBCPersistenceAdapter - so it can be a broker lock

2013-03-08 Thread Paul Gale (JIRA)

[ 
https://issues.apache.org/jira/browse/AMQ-4365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13597342#comment-13597342
 ] 

Paul Gale edited comment on AMQ-4365 at 3/8/13 6:28 PM:


So I've been able to get a first cut at a lease database locker that works with 
the KahaDBPersistenceAdapter, as shown below. This is by no means the ideal 
solution but it works. Feedback welcome.

Longer term, the signature of the configure method should be changed; there is 
no reason that I can see why it should be coupled to a PersistenceAdapter - 
that's too broad. Either provide a few overloaded versions of configure() with 
various arguments that a locker might require or create an interface to be 
implemented by a persistence adapter that makes the contract between the two 
more explicit.
\\
\\
{code:title=MyLeaseDatabaseLocker.java}
public class MyLeaseDatabaseLocker extends LeaseDatabaseLocker implements 
BrokerServiceAware, LockDataSourceCapable {
  private static final Logger LOG = 
LoggerFactory.getLogger(MyLeaseDatabaseLocker.class);
  protected BrokerService brokerService;

  @Override
  public void configure(PersistenceAdapter ignore) throws IOException {
this.statements = new Statements();
  }

  @Override
  public boolean keepAlive() throws IOException {
boolean result = false;
final String sql = statements.getLeaseUpdateStatement();

LOG.debug(getLeaseHolderId() + , lease keepAlive Query is  + sql);

Connection connection = null;
PreparedStatement statement = null;

try {
  connection = getConnection();

  initTimeDiff(connection);
  statement = connection.prepareStatement(sql);
  setQueryTimeout(statement);

  final long now = System.currentTimeMillis() + diffFromCurrentTime;
  statement.setString(1, getLeaseHolderId());
  statement.setLong(2, now + lockAcquireSleepInterval);
  statement.setString(3, getLeaseHolderId());

  result = (statement.executeUpdate() == 1);
}
catch(Exception e) {
  LOG.warn(getLeaseHolderId() + , failed to update lease:  + e, e);
  IOException ioe = IOExceptionSupport.create(e);
  brokerService.handleIOException(ioe);
  throw ioe;
}
finally {
  close(statement);
  close(connection);
}

return result;
  }

  @Override
  public void setBrokerService(BrokerService brokerService) {
this.brokerService = brokerService;
  }

  @Override
  public String getLeaseHolderId() {
if(leaseHolderId == null  brokerService != null) {
  leaseHolderId = brokerService.getBrokerName();
}

return leaseHolderId;
  }

  @Override
  public void setLockDataSource(DataSource lockDataSource) {
this.dataSource = lockDataSource;
  }

  @Override
  public DataSource getLockDataSource() {
return this.dataSource;
  }

  private void setQueryTimeout(PreparedStatement statement) throws SQLException 
{
if(queryTimeout  0) {
  statement.setQueryTimeout(queryTimeout);
}
  }

  private Connection getConnection() throws SQLException {
return dataSource.getConnection();
  }

  private void close(Connection connection) {
if(null == connection) return;

try {
  connection.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() +  caught exception while closing 
connection:  + e1, e1);
}
  }

  private void close(PreparedStatement statement) {
if(null == statement) return;

try {
  statement.close();
}
catch(SQLException e1) {
  LOG.debug(getLeaseHolderId() + , caught while closing statement:  + e1, 
e1);
}
  }
}
{code}

{code:title=LockDataSourceCapable.java}
public interface LockDataSourceCapable {
  public void setLockDataSource(DataSource lockDataSource);
  public DataSource getLockDataSource();
}
{code}

{code:xml|title=activemq.xml (with parts removed)}
beans
xmlns=http://www.springframework.org/schema/beans;
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance;
xsi:schemaLocation=http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core

http://activemq.apache.org/schema/core/activemq-core.xsd;

  broker xmlns=http://activemq.apache.org/schema/core;
  id=theBroker

persistenceAdapter
  kahaDB directory=${activemq.data}/kahadb
  lockKeepAlivePeriod=2500
  useLock=true
locker
  bean xmlns=http://www.springframework.org/schema/beans;
class=com.example.activemq.MyLeaseDatabaseLocker
property name=lockDataSource ref=mysql-ds/
property name=brokerService ref=theBroker/
property name=failIfLocked value=false/
property name=lockAcquireSleepInterval value=5000/
  /bean
/locker
  /kahaDB