You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@qpid.apache.org by Dmitriy Kargapolov <dm...@gmail.com> on 2009/03/19 17:57:48 UTC

message accept confirmation

Hi,
I'm playing with C++ Qpid broker M4 and .NET client (Win32).
Test scenario looks this way:
1) open connection
2) create a session (timeout = 0 sec)
3) declare a queue (durable, exclusive)
4) subscribe to the queue
5) transfer test message to the exchange
6) wait until message arrives from the queue
7) accept the message
8) close session
9) close connection

When I run this test, it works just fine. But the message left in the queue
after test completed! Second pass returns 2 messages - new and old one, 3rd
pass - 3 messages etc.

I was able to "fix" this in various ways:
1) If I add short delay (100ms) between steps 7) and 8), accepted message
successfully deleted from the queue.
Obviously this way is ugly.
2) If session is created with some expiration timeout, 1st try works fine.
But second try got locked due to exclusive subscription of the 1st session
which still exists in the broker (until timeout expired). Definitely this is
not what I want.

What I do not understand - why message didn't get deleted when session
closed? I'm sure, accept command reached broker _before_ session ends.
Is it bug or normal behavior per AMQP 0-10 spec?
Is there any elegant way to make sure accepted message was actually deleted
from the queue before leaving session?

Thank you.

Re: message accept confirmation

Posted by Gordon Sim <gs...@redhat.com>.
Dmitriy Kargapolov wrote:
> Further investigation shown that the reason was not "incorrect" tcp option.
> Being not familiar with .NET I placed session.close() and client.close()
> calls into Destructor of the Object responsible for the communication with
> Broker. And this object's Destructor was called when Program.Main() ended.
> I was just shocked realizing that session.close() call never returns. Once
> it invoked Monitor.Wait(), situation gets out of control - program just
> silently terminated!
> Moving cleanup code out of the destructor and its explicit invocation fixed
> the problem.

Thanks for the info!



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:users-subscribe@qpid.apache.org


Re: message accept confirmation

Posted by Dmitriy Kargapolov <dm...@gmail.com>.
On Thu, Mar 19, 2009 at 6:31 PM, Dmitriy Kargapolov <
dmitriy.kargapolov@gmail.com> wrote:

> On Thu, Mar 19, 2009 at 5:42 PM, Dmitriy Kargapolov <
> dmitriy.kargapolov@gmail.com> wrote:
>
>> On Thu, Mar 19, 2009 at 4:00 PM, Gordon Sim <gs...@redhat.com> wrote:
>>
>>> Dmitriy Kargapolov wrote:
>>>
>>>> Hi,
>>>> I'm playing with C++ Qpid broker M4 and .NET client (Win32).
>>>> Test scenario looks this way:
>>>> 1) open connection
>>>> 2) create a session (timeout = 0 sec)
>>>> 3) declare a queue (durable, exclusive)
>>>> 4) subscribe to the queue
>>>> 5) transfer test message to the exchange
>>>> 6) wait until message arrives from the queue
>>>> 7) accept the message
>>>> 8) close session
>>>> 9) close connection
>>>>
>>>> When I run this test, it works just fine. But the message left in the
>>>> queue
>>>> after test completed! Second pass returns 2 messages - new and old one,
>>>> 3rd
>>>> pass - 3 messages etc.
>>>>
>>>> I was able to "fix" this in various ways:
>>>> 1) If I add short delay (100ms) between steps 7) and 8), accepted
>>>> message
>>>> successfully deleted from the queue.
>>>> Obviously this way is ugly.
>>>>
>>>
>>> I'm not very familiar with the .Net client but what I suspect you want to
>>> do is sync with the server on or after step 7 to ensure that the server has
>>> processed your accept before you exit.
>>>
>>> I believe session.sync() should do that, or alternatively setting
>>> session.setAutoSync(true). As mentioned though, I'm no expert on the .Net
>>> client but hopefully Arnaud or others will correct me if thats wrong.
>>>
>>
>> Added sync():
>>             session.sync();
>>             session.close();
>>             client.close();
>>
>> This didn't hepl actually.
>> Still, if no delay provided before closing session, no 'Accepted' message
>> received by broker (checked traces)...
>> Looks like some race condition between client threads...
>>
>
> No explicit sync() is required.
> What actually solved the problem - setting TCP_NODELAY option in
> environment:
>
> set qpid.tcpNoDelay=true
>
> This could impact network exchange performance though, in that case the
> only solution I see for the moment - pause before closing connection... May
> be Devs have an opinion?
>
>
Further investigation shown that the reason was not "incorrect" tcp option.
Being not familiar with .NET I placed session.close() and client.close()
calls into Destructor of the Object responsible for the communication with
Broker. And this object's Destructor was called when Program.Main() ended.
I was just shocked realizing that session.close() call never returns. Once
it invoked Monitor.Wait(), situation gets out of control - program just
silently terminated!
Moving cleanup code out of the destructor and its explicit invocation fixed
the problem.

Re: message accept confirmation

Posted by Dmitriy Kargapolov <dm...@gmail.com>.
On Thu, Mar 19, 2009 at 6:31 PM, Dmitriy Kargapolov <
dmitriy.kargapolov@gmail.com> wrote:

> On Thu, Mar 19, 2009 at 5:42 PM, Dmitriy Kargapolov <
> dmitriy.kargapolov@gmail.com> wrote:
>
>> On Thu, Mar 19, 2009 at 4:00 PM, Gordon Sim <gs...@redhat.com> wrote:
>>
>>> Dmitriy Kargapolov wrote:
>>>
>>>> Hi,
>>>> I'm playing with C++ Qpid broker M4 and .NET client (Win32).
>>>> Test scenario looks this way:
>>>> 1) open connection
>>>> 2) create a session (timeout = 0 sec)
>>>> 3) declare a queue (durable, exclusive)
>>>> 4) subscribe to the queue
>>>> 5) transfer test message to the exchange
>>>> 6) wait until message arrives from the queue
>>>> 7) accept the message
>>>> 8) close session
>>>> 9) close connection
>>>>
>>>> When I run this test, it works just fine. But the message left in the
>>>> queue
>>>> after test completed! Second pass returns 2 messages - new and old one,
>>>> 3rd
>>>> pass - 3 messages etc.
>>>>
>>>> I was able to "fix" this in various ways:
>>>> 1) If I add short delay (100ms) between steps 7) and 8), accepted
>>>> message
>>>> successfully deleted from the queue.
>>>> Obviously this way is ugly.
>>>>
>>>
>>> I'm not very familiar with the .Net client but what I suspect you want to
>>> do is sync with the server on or after step 7 to ensure that the server has
>>> processed your accept before you exit.
>>>
>>> I believe session.sync() should do that, or alternatively setting
>>> session.setAutoSync(true). As mentioned though, I'm no expert on the .Net
>>> client but hopefully Arnaud or others will correct me if thats wrong.
>>>
>>
>> Added sync():
>>             session.sync();
>>             session.close();
>>             client.close();
>>
>> This didn't hepl actually.
>> Still, if no delay provided before closing session, no 'Accepted' message
>> received by broker (checked traces)...
>> Looks like some race condition between client threads...
>>
>
> No explicit sync() is required.
> What actually solved the problem - setting TCP_NODELAY option in
> environment:
>
> set qpid.tcpNoDelay=true
>
> This could impact network exchange performance though, in that case the
> only solution I see for the moment - pause before closing connection... May
> be Devs have an opinion?
>
>
Further investigation shown that the reason was not "incorrect" tcp option.
Being not familiar with .NET I placed session.close() and client.close()
calls into Destructor of the Object responsible for the communication with
Broker. And this object's Destructor was called when Program.Main() ended.
I was just shocked realizing that session.close() call never returns. Once
it invoked Monitor.Wait(), situation gets out of control - program just
silently terminated!
Moving cleanup code out of the destructor and its explicit invocation fixed
the problem.

Re: message accept confirmation

Posted by Dmitriy Kargapolov <dm...@gmail.com>.
On Thu, Mar 19, 2009 at 5:42 PM, Dmitriy Kargapolov <
dmitriy.kargapolov@gmail.com> wrote:

> On Thu, Mar 19, 2009 at 4:00 PM, Gordon Sim <gs...@redhat.com> wrote:
>
>> Dmitriy Kargapolov wrote:
>>
>>> Hi,
>>> I'm playing with C++ Qpid broker M4 and .NET client (Win32).
>>> Test scenario looks this way:
>>> 1) open connection
>>> 2) create a session (timeout = 0 sec)
>>> 3) declare a queue (durable, exclusive)
>>> 4) subscribe to the queue
>>> 5) transfer test message to the exchange
>>> 6) wait until message arrives from the queue
>>> 7) accept the message
>>> 8) close session
>>> 9) close connection
>>>
>>> When I run this test, it works just fine. But the message left in the
>>> queue
>>> after test completed! Second pass returns 2 messages - new and old one,
>>> 3rd
>>> pass - 3 messages etc.
>>>
>>> I was able to "fix" this in various ways:
>>> 1) If I add short delay (100ms) between steps 7) and 8), accepted message
>>> successfully deleted from the queue.
>>> Obviously this way is ugly.
>>>
>>
>> I'm not very familiar with the .Net client but what I suspect you want to
>> do is sync with the server on or after step 7 to ensure that the server has
>> processed your accept before you exit.
>>
>> I believe session.sync() should do that, or alternatively setting
>> session.setAutoSync(true). As mentioned though, I'm no expert on the .Net
>> client but hopefully Arnaud or others will correct me if thats wrong.
>>
>
> Added sync():
>             session.sync();
>             session.close();
>             client.close();
>
> This didn't hepl actually.
> Still, if no delay provided before closing session, no 'Accepted' message
> received by broker (checked traces)...
> Looks like some race condition between client threads...
>

No explicit sync() is required.
What actually solved the problem - setting TCP_NODELAY option in
environment:

set qpid.tcpNoDelay=true

This could impact network exchange performance though, in that case the only
solution I see for the moment - pause before closing connection... May be
Devs have an opinion?

Re: message accept confirmation

Posted by Dmitriy Kargapolov <dm...@gmail.com>.
On Thu, Mar 19, 2009 at 5:42 PM, Dmitriy Kargapolov <
dmitriy.kargapolov@gmail.com> wrote:

> On Thu, Mar 19, 2009 at 4:00 PM, Gordon Sim <gs...@redhat.com> wrote:
>
>> Dmitriy Kargapolov wrote:
>>
>>> Hi,
>>> I'm playing with C++ Qpid broker M4 and .NET client (Win32).
>>> Test scenario looks this way:
>>> 1) open connection
>>> 2) create a session (timeout = 0 sec)
>>> 3) declare a queue (durable, exclusive)
>>> 4) subscribe to the queue
>>> 5) transfer test message to the exchange
>>> 6) wait until message arrives from the queue
>>> 7) accept the message
>>> 8) close session
>>> 9) close connection
>>>
>>> When I run this test, it works just fine. But the message left in the
>>> queue
>>> after test completed! Second pass returns 2 messages - new and old one,
>>> 3rd
>>> pass - 3 messages etc.
>>>
>>> I was able to "fix" this in various ways:
>>> 1) If I add short delay (100ms) between steps 7) and 8), accepted message
>>> successfully deleted from the queue.
>>> Obviously this way is ugly.
>>>
>>
>> I'm not very familiar with the .Net client but what I suspect you want to
>> do is sync with the server on or after step 7 to ensure that the server has
>> processed your accept before you exit.
>>
>> I believe session.sync() should do that, or alternatively setting
>> session.setAutoSync(true). As mentioned though, I'm no expert on the .Net
>> client but hopefully Arnaud or others will correct me if thats wrong.
>>
>
> Added sync():
>             session.sync();
>             session.close();
>             client.close();
>
> This didn't hepl actually.
> Still, if no delay provided before closing session, no 'Accepted' message
> received by broker (checked traces)...
> Looks like some race condition between client threads...
>

No explicit sync() is required.
What actually solved the problem - setting TCP_NODELAY option in
environment:

set qpid.tcpNoDelay=true

This could impact network exchange performance though, in that case the only
solution I see for the moment - pause before closing connection... May be
Devs have an opinion?

Re: message accept confirmation

Posted by Dmitriy Kargapolov <dm...@gmail.com>.
On Thu, Mar 19, 2009 at 4:00 PM, Gordon Sim <gs...@redhat.com> wrote:

> Dmitriy Kargapolov wrote:
>
>> Hi,
>> I'm playing with C++ Qpid broker M4 and .NET client (Win32).
>> Test scenario looks this way:
>> 1) open connection
>> 2) create a session (timeout = 0 sec)
>> 3) declare a queue (durable, exclusive)
>> 4) subscribe to the queue
>> 5) transfer test message to the exchange
>> 6) wait until message arrives from the queue
>> 7) accept the message
>> 8) close session
>> 9) close connection
>>
>> When I run this test, it works just fine. But the message left in the
>> queue
>> after test completed! Second pass returns 2 messages - new and old one,
>> 3rd
>> pass - 3 messages etc.
>>
>> I was able to "fix" this in various ways:
>> 1) If I add short delay (100ms) between steps 7) and 8), accepted message
>> successfully deleted from the queue.
>> Obviously this way is ugly.
>>
>
> I'm not very familiar with the .Net client but what I suspect you want to
> do is sync with the server on or after step 7 to ensure that the server has
> processed your accept before you exit.
>
> I believe session.sync() should do that, or alternatively setting
> session.setAutoSync(true). As mentioned though, I'm no expert on the .Net
> client but hopefully Arnaud or others will correct me if thats wrong.
>

Added sync():
            session.sync();
            session.close();
            client.close();

This didn't hepl actually.
Still, if no delay provided before closing session, no 'Accepted' message
received by broker (checked traces)...
Looks like some race condition between client threads...

Re: message accept confirmation

Posted by Gordon Sim <gs...@redhat.com>.
Dmitriy Kargapolov wrote:
> Hi,
> I'm playing with C++ Qpid broker M4 and .NET client (Win32).
> Test scenario looks this way:
> 1) open connection
> 2) create a session (timeout = 0 sec)
> 3) declare a queue (durable, exclusive)
> 4) subscribe to the queue
> 5) transfer test message to the exchange
> 6) wait until message arrives from the queue
> 7) accept the message
> 8) close session
> 9) close connection
> 
> When I run this test, it works just fine. But the message left in the queue
> after test completed! Second pass returns 2 messages - new and old one, 3rd
> pass - 3 messages etc.
> 
> I was able to "fix" this in various ways:
> 1) If I add short delay (100ms) between steps 7) and 8), accepted message
> successfully deleted from the queue.
> Obviously this way is ugly.

I'm not very familiar with the .Net client but what I suspect you want 
to do is sync with the server on or after step 7 to ensure that the 
server has processed your accept before you exit.

I believe session.sync() should do that, or alternatively setting 
session.setAutoSync(true). As mentioned though, I'm no expert on the 
.Net client but hopefully Arnaud or others will correct me if thats wrong.

> 2) If session is created with some expiration timeout, 1st try works fine.
> But second try got locked due to exclusive subscription of the 1st session
> which still exists in the broker (until timeout expired). Definitely this is
> not what I want.

I would not specify any timeout. The session resume feature is not fully 
implemented I believe.


---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:users-subscribe@qpid.apache.org