Re: Unexpected idle timeout behaviours

2024-03-15 Thread Ciaran
On Fri, Mar 15, 2024 at 8:03 PM Timothy Bish  wrote:

> > I'm glad you got to the bottom of it, thank you for bearing with me. I
> can
> > run a parallel compile for
> > my purposes, but I was wondering if there is a planned release date for
> M20
> > ?
> >
> > Thank you.
> >
> No planned date as someone keeps reporting issues. Was planning to
> release something in a few weeks for protonj2 and proton-dotnet
>
>  Sorry about that. You'll be glad to know I'm almost at the end of
writing
my test suite that covers the non application layer logic!

Thank you for solving the underlying issue, it was a touch problematic!


Re: ProtonJ2 client handling of null message bodies

2024-03-15 Thread Timothy Bish

On 3/15/24 15:42, Ciaran wrote:

On Fri, Mar 15, 2024 at 6:14 PM Timothy Bish  wrote:


On 3/15/24 11:50, Ciaran wrote:

Hi,

I'm attempting to build a resilient client using the protonj2 client and

as

part of my testing I was checking that it would handle messages with null
bodies (specifically my client is only willing to work with strings or

byte

arrays so it rejects any other AMQP message body type). However, when I

put

a null body on the message (i.e. body length of 0), when I de-reference

the

delivery's message's body property (e.g. delivery.message().body) I

receive

an error from the proton engine:

Can you capture a frame trace, I need enough information to try and
create an exact reproducer which can be aided with traces of the
incoming frames to reverse engineer a test. I wouldn't expect and
exception here and its likely something that was missed in the current
test suite.

Code snippets of the sender and receiver bits can help as well.


Hi,

Please find below everything I think you've asked for, the real code is
somewhat distributed
across several different classes, but this should be pretty equivalent:

RECEIVER CODE
-
ConnectionOptions options = constructBasicConnectionOptions();
options.reconnectOptions()
.reconnectEnabled(true)
.useReconnectBackOff(true)
.reconnectDelay(5000)
.maxReconnectDelay(10240001)
.maxReconnectAttempts(12)
.warnAfterReconnectAttempts(1);

Client client= Client.create();
Connection connection = client.connect("host", 1234, options);
ReceiverOptions ro = new ReceiverOptions();
ro.autoAccept(false);
Receiver receiver = connection.openReceiver( "queue", ro )) {

Delivery delivery = receiver.tryReceive();
if( delivery != null ) {
Message message= delivery.message();
// Exception occurs here.
Object body= message.body();
}

SENDER CODE
---
final Client client = Client.create();
final ConnectionOptions options = new ConnectionOptions();
options.sslOptions().sslEnabled(true);
options.user("MY_USER");
options.password("MY_PASSWORD");

Connection connection = client.connect(serverHost, serverPort, options);
Sender sender = connection.openSender(address);
sender.send(Message.create((byte[])null));

FRAME TRACE

-> SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] SaslMechanisms{saslServerMechanisms=[MSSBCBS, PLAIN,
ANONYMOUS, EXTERNAL]}
19:36:21,633  WARN SaslMechanismSelector:130 - Caught exception while
trying to create SASL mechanism MSSBCBS: No Matching SASL Mechanism with
name: MSSBCBS
-> SASL:[269961536:0] SaslInit{mechanism=PLAIN,
initialResponse="\x00MY_USER\x00MY_PASSWORD"...(truncated), hostname='
MY_HOST.servicebus.windows.net'}
<- SASL:[269961536:0] SaslOutcome{code=OK, additionalData="Welcome!"}
-> AMQP:[269961536:0] AMQP,0,1,0,0
<- AMQP:[269961536:0] AMQP,0,1,0,0
-> AMQP:[269961536:0] Open{
containerId='ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2', hostname='
MY_HOST.servicebus.windows.net', maxFrameSize=65536, channelMax=65535,
idleTimeOut=6, outgoingLocales=null, incomingLocales=null,
offeredCapabilities=null, desiredCapabilities=[ANONYMOUS-RELAY],
properties=null}
-> AMQP:[269961536:0] Begin{remoteChannel=null, nextOutgoingId=0,
incomingWindow=1600, outgoingWindow=2147483647, handleMax=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',
handle=0, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='testq', durable=NONE, expiryPolicy=LINK_DETACH,
timeout=0, dynamic=false, dynamicNodeProperties=null,
distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='testq', durable=NONE, expiryPolicy=SESSION_END,
timeout=0, dynamic=false, dynamicNodeProperties=null, capabilities=null},
unsettled=null, incompleteUnsettled=null, initialDeliveryCount=null,
maxMessageSize=null, offeredCapabilities=null, desiredCapabilities=null,
properties=null}
-> AMQP:[269961536:0] Flow{nextIncomingId=null, incomingWindow=1600,
nextOutgoingId=0, outgoingWindow=2147483647, handle=0, deliveryCount=null,
linkCredit=10, available=null, drain=false, echo=null, properties=null}
<- AMQP:[269961536:0] Open{
containerId='af1bcb999146429ea0a245db6affd5e4_G60', hostname='null',
maxFrameSize=65536, channelMax=4999, idleTimeOut=12,
outgoingLocales=null, incomingLocales=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0] Begin{remoteChannel=0, nextOutgoingId=1,
incomingWindow=5000, outgoingWindow=1600, handleMax=255,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',
handle=0, 

Re: Unexpected idle timeout behaviours

2024-03-15 Thread Timothy Bish

On 3/15/24 15:44, Ciaran wrote:





This should be fixed no in:



https://issues.apache.org/jira/browse/PROTON-2807



This essentially occurred because the Proton buffers were rewritten to

allow zero copy semantics after the ingest code was written and the read

offset is no longer reflective of the read outcome as the buffer may

have handed off its underlying payload and have a size of zero which

means the read offset will still be zero.  This code was written in

early days and had some safety checks in it that are no longer needed

given other mechanics in place in the engine so has been updated to

treat an non-empty buffer as cause to update the input sequence value.

It's necessary to reproduce and explain the issues before making these

changes so I needed to find a test case for this which I now have.



I'm glad you got to the bottom of it, thank you for bearing with me. I can
run a parallel compile for
my purposes, but I was wondering if there is a planned release date for M20
?

Thank you.

No planned date as someone keeps reporting issues. Was planning to 
release something in a few weeks for protonj2 and proton-dotnet


--
Tim Bish


-
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org



Re: Unexpected idle timeout behaviours

2024-03-15 Thread Ciaran
>
>
>
>
>
> This should be fixed no in:
>
>
>
> https://issues.apache.org/jira/browse/PROTON-2807
>
>
>
> This essentially occurred because the Proton buffers were rewritten to
>
> allow zero copy semantics after the ingest code was written and the read
>
> offset is no longer reflective of the read outcome as the buffer may
>
> have handed off its underlying payload and have a size of zero which
>
> means the read offset will still be zero.  This code was written in
>
> early days and had some safety checks in it that are no longer needed
>
> given other mechanics in place in the engine so has been updated to
>
> treat an non-empty buffer as cause to update the input sequence value.
>
> It's necessary to reproduce and explain the issues before making these
>
> changes so I needed to find a test case for this which I now have.
>
>
I'm glad you got to the bottom of it, thank you for bearing with me. I can
run a parallel compile for
my purposes, but I was wondering if there is a planned release date for M20
?

Thank you.


Re: ProtonJ2 client handling of null message bodies

2024-03-15 Thread Ciaran
On Fri, Mar 15, 2024 at 6:14 PM Timothy Bish  wrote:

> On 3/15/24 11:50, Ciaran wrote:
> > Hi,
> >
> > I'm attempting to build a resilient client using the protonj2 client and
> as
> > part of my testing I was checking that it would handle messages with null
> > bodies (specifically my client is only willing to work with strings or
> byte
> > arrays so it rejects any other AMQP message body type). However, when I
> put
> > a null body on the message (i.e. body length of 0), when I de-reference
> the
> > delivery's message's body property (e.g. delivery.message().body) I
> receive
> > an error from the proton engine:
>
> Can you capture a frame trace, I need enough information to try and
> create an exact reproducer which can be aided with traces of the
> incoming frames to reverse engineer a test. I wouldn't expect and
> exception here and its likely something that was missed in the current
> test suite.
>
> Code snippets of the sender and receiver bits can help as well.
>
>
> Hi,
Please find below everything I think you've asked for, the real code is
somewhat distributed
across several different classes, but this should be pretty equivalent:

RECEIVER CODE
-
ConnectionOptions options = constructBasicConnectionOptions();
options.reconnectOptions()
   .reconnectEnabled(true)
   .useReconnectBackOff(true)
   .reconnectDelay(5000)
   .maxReconnectDelay(10240001)
.maxReconnectAttempts(12)
.warnAfterReconnectAttempts(1);

Client client= Client.create();
Connection connection = client.connect("host", 1234, options);
ReceiverOptions ro = new ReceiverOptions();
ro.autoAccept(false);
Receiver receiver = connection.openReceiver( "queue", ro )) {

Delivery delivery = receiver.tryReceive();
if( delivery != null ) {
Message message= delivery.message();
// Exception occurs here.
Object body= message.body();
}

SENDER CODE
---
final Client client = Client.create();
final ConnectionOptions options = new ConnectionOptions();
options.sslOptions().sslEnabled(true);
options.user("MY_USER");
options.password("MY_PASSWORD");

Connection connection = client.connect(serverHost, serverPort, options);
Sender sender = connection.openSender(address);
sender.send(Message.create((byte[])null));

FRAME TRACE

-> SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] AMQP,3,1,0,0
<- SASL:[269961536:0] SaslMechanisms{saslServerMechanisms=[MSSBCBS, PLAIN,
ANONYMOUS, EXTERNAL]}
19:36:21,633  WARN SaslMechanismSelector:130 - Caught exception while
trying to create SASL mechanism MSSBCBS: No Matching SASL Mechanism with
name: MSSBCBS
-> SASL:[269961536:0] SaslInit{mechanism=PLAIN,
initialResponse="\x00MY_USER\x00MY_PASSWORD"...(truncated), hostname='
MY_HOST.servicebus.windows.net'}
<- SASL:[269961536:0] SaslOutcome{code=OK, additionalData="Welcome!"}
-> AMQP:[269961536:0] AMQP,0,1,0,0
<- AMQP:[269961536:0] AMQP,0,1,0,0
-> AMQP:[269961536:0] Open{
containerId='ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2', hostname='
MY_HOST.servicebus.windows.net', maxFrameSize=65536, channelMax=65535,
idleTimeOut=6, outgoingLocales=null, incomingLocales=null,
offeredCapabilities=null, desiredCapabilities=[ANONYMOUS-RELAY],
properties=null}
-> AMQP:[269961536:0] Begin{remoteChannel=null, nextOutgoingId=0,
incomingWindow=1600, outgoingWindow=2147483647, handleMax=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',
handle=0, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='testq', durable=NONE, expiryPolicy=LINK_DETACH,
timeout=0, dynamic=false, dynamicNodeProperties=null,
distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='testq', durable=NONE, expiryPolicy=SESSION_END,
timeout=0, dynamic=false, dynamicNodeProperties=null, capabilities=null},
unsettled=null, incompleteUnsettled=null, initialDeliveryCount=null,
maxMessageSize=null, offeredCapabilities=null, desiredCapabilities=null,
properties=null}
-> AMQP:[269961536:0] Flow{nextIncomingId=null, incomingWindow=1600,
nextOutgoingId=0, outgoingWindow=2147483647, handle=0, deliveryCount=null,
linkCredit=10, available=null, drain=false, echo=null, properties=null}
<- AMQP:[269961536:0] Open{
containerId='af1bcb999146429ea0a245db6affd5e4_G60', hostname='null',
maxFrameSize=65536, channelMax=4999, idleTimeOut=12,
outgoingLocales=null, incomingLocales=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0] Begin{remoteChannel=0, nextOutgoingId=1,
incomingWindow=5000, outgoingWindow=1600, handleMax=255,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
<- AMQP:[269961536:0]
Attach{name='receiver-ID:081fcabd-ac34-41b5-9bff-fe35d0cfbff1:1:2:1:1',

Re: ProtonJ2 client handling of null message bodies

2024-03-15 Thread Timothy Bish

On 3/15/24 11:50, Ciaran wrote:

Hi,

I'm attempting to build a resilient client using the protonj2 client and as
part of my testing I was checking that it would handle messages with null
bodies (specifically my client is only willing to work with strings or byte
arrays so it rejects any other AMQP message body type). However, when I put
a null body on the message (i.e. body length of 0), when I de-reference the
delivery's message's body property (e.g. delivery.message().body) I receive
an error from the proton engine:


Can you capture a frame trace, I need enough information to try and 
create an exact reproducer which can be aided with traces of the 
incoming frames to reverse engineer a test. I wouldn't expect and 
exception here and its likely something that was missed in the current 
test suite.


Code snippets of the sender and receiver bits can help as well.




Caused by: org.apache.qpid.protonj2.client.exceptions.ClientException:
Index 1 out of bounds for length 1

at
org.apache.qpid.protonj2.client.impl.ClientExceptionSupport.createNonFatalOrPassthrough(
ClientExceptionSupport.java:103)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:170)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:152)

at org.apache.qpid.protonj2.client.impl.ClientDelivery.message(
ClientDelivery.java:79)

at
com.thisisnumero.smartagent.gateway.inbound.sources.background.amqp.AMQPMessageConsumerImpl.internalConsumeMessages(
AMQPMessageConsumerImpl.java:53)

... 4 more

Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds
for length 1

at
org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl.findChunkWithIndex(
ProtonCompositeBufferImpl.java:1530)

at org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl.copyInto(
ProtonCompositeBufferImpl.java:387)

at
org.apache.qpid.protonj2.codec.decoders.messaging.DataTypeDecoder.readValue(
DataTypeDecoder.java:85)

at
org.apache.qpid.protonj2.codec.decoders.messaging.DataTypeDecoder.readValue(
DataTypeDecoder.java:40)

at org.apache.qpid.protonj2.codec.decoders.ProtonDecoder.readObject(
ProtonDecoder.java:192)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:168)

... 7 more

My expectation from the comments on the 'body()' method is that I should
expect it to return null in this scenario? Should I be trapping this
exception and rejecting the messages to avoid poisoning my queue? (I was
planning on rejecting them anyway, but it seems weird to have to catch the
exception first.)

For reference, I'm putting messages onto the queue with the following
protonj2 calls:
sender.send(Message.create((byte[])null));
sender.send(Message.create((*String*)null));

Thank you (and sorry for the bombardment of things)



--
Tim Bish


-
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org



Re: Unexpected idle timeout behaviours

2024-03-15 Thread Timothy Bish

On 3/14/24 19:28, Ciaran wrote:




I've provided the full set of frames below, but if I'm interpreting
correctly the inputSequence property is not being incremented on receipt

of

data which means that the deadline for hearing from the peer again is not
being suitably increased. (I can see the sequence increments and the
localdeadline is recalculated for the empty frames the peer sends, but

not

for when there's actual data.)

I've gone back through the client and engine code and did some testing
and cannot reproduce any issue where the sequence tracking is not
updated when incoming frames are read regardless of which frame they are.

I fixed a minor issue where the Client is not configuring the idle
timeout to half the set value as it says it will.

Hi Tim,

Thank you for taking a look, but I'm still seeing the issue :( I've
cherry-picked the idle timeout commit
on top of M19 and it /may/ be a little better, but that still feels like
it's covering up an issue.

Forgive me, but I'm not deeply familiar with the protonj2 codebase, but it
seems logical to
me that the inputSequence is incremented whenever some data is received
from the peer.


This should be fixed no in:

https://issues.apache.org/jira/browse/PROTON-2807

This essentially occurred because the Proton buffers were rewritten to 
allow zero copy semantics after the ingest code was written and the read 
offset is no longer reflective of the read outcome as the buffer may 
have handed off its underlying payload and have a size of zero which 
means the read offset will still be zero.  This code was written in 
early days and had some safety checks in it that are no longer needed 
given other mechanics in place in the engine so has been updated to 
treat an non-empty buffer as cause to update the input sequence value.  
It's necessary to reproduce and explain the issues before making these 
changes so I needed to find a test case for this which I now have.




I've attached another trace with additional logging to show the state of
ProtonEngine#ingest()
function. As I mentioned earlier, for Transfer frames the readOffset of the
input buffer
after fireRead has completed is 0, which the logic treats as a 'no
sequence' operation.

The interesting part, you may see below is that for each transfer there are
multiple (two)
calls to ingest, both returning 0 as the post fireRead value of the
readOffset. I presume this
is due to buffering and needing to fetch more data for this particular
frame type, so I can get my
head around the first of these reads being ignored as a sequence increment,
but it still feels to me that
the second (or presumably the very last one in the case of larger payloads)
should return a non-zero
value to trigger the sequence increment?

I'm not quite sure what the value of enforcing this logical sequence is as
it only appears to
be used as a 'liveness' indicator for the remote connection, does it matter
if it was a valid frame
returned?

Trace with additional logging of the variable state below:

<- AMQP:[1619358550:0] Open{
containerId='91791f32464449109b4136667ccaa3f7_G52', hostname='null',
maxFrameSize=65536, channelMax=4999, idleTimeOut=12,
outgoingLocales=null, incomingLocales=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
startIndex:0, input.getReadOffset():71
inputSequence++
<- AMQP:[1619358550:0] Begin{remoteChannel=0, nextOutgoingId=1,
incomingWindow=5000, outgoingWindow=1600, handleMax=255,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
startIndex:0, input.getReadOffset():34
inputSequence++
<- AMQP:[1619358550:0]
Attach{name='receiver-ID:ecec0184-d4d3-4fe8-b8ec-0b132b249368:1:2:1:1',
handle=0, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='testq', durable=NONE, expiryPolicy=LINK_DETACH,
timeout=0, dynamic=false, dynamicNodeProperties=null,
distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='testq', durable=NONE, expiryPolicy=SESSION_END,
timeout=0, dynamic=false, dynamicNodeProperties=null, capabilities=null},
unsettled=null, incompleteUnsettled=null, initialDeliveryCount=0,
maxMessageSize=18446744073709551615, offeredCapabilities=[SHARED-SUBS],
desiredCapabilities=null, properties=null}
startIndex:0, input.getReadOffset():258
inputSequence++
startIndex:0, input.getReadOffset():0
<- AMQP:[1619358550:0] Transfer{handle=0, deliveryId=0,
deliveryTag=DeliveryTag: {[56, 109, 70, 77, -127, -59, 8, 72, -120, 61, 85,
-116, 30, -125, -121, -112]}, messageFormat=0, settled=null, more=false,
rcvSettleMode=null, state=null, resume=null, aborted=null, batchable=true}
- "\x00Sp\xc0\x0a\x05@@pH\x19\x08\x00@C
\x00Sq\xc1$\x02\xa3\x10x-opt"...(truncated)
startIndex:0, input.getReadOffset():0
-> AMQP:[1619358550:0] Disposition{role=RECEIVER, 

ProtonJ2 client handling of null message bodies

2024-03-15 Thread Ciaran
Hi,

I'm attempting to build a resilient client using the protonj2 client and as
part of my testing I was checking that it would handle messages with null
bodies (specifically my client is only willing to work with strings or byte
arrays so it rejects any other AMQP message body type). However, when I put
a null body on the message (i.e. body length of 0), when I de-reference the
delivery's message's body property (e.g. delivery.message().body) I receive
an error from the proton engine:

Caused by: org.apache.qpid.protonj2.client.exceptions.ClientException:
Index 1 out of bounds for length 1

at
org.apache.qpid.protonj2.client.impl.ClientExceptionSupport.createNonFatalOrPassthrough(
ClientExceptionSupport.java:103)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:170)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:152)

at org.apache.qpid.protonj2.client.impl.ClientDelivery.message(
ClientDelivery.java:79)

at
com.thisisnumero.smartagent.gateway.inbound.sources.background.amqp.AMQPMessageConsumerImpl.internalConsumeMessages(
AMQPMessageConsumerImpl.java:53)

... 4 more

Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds
for length 1

at
org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl.findChunkWithIndex(
ProtonCompositeBufferImpl.java:1530)

at org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl.copyInto(
ProtonCompositeBufferImpl.java:387)

at
org.apache.qpid.protonj2.codec.decoders.messaging.DataTypeDecoder.readValue(
DataTypeDecoder.java:85)

at
org.apache.qpid.protonj2.codec.decoders.messaging.DataTypeDecoder.readValue(
DataTypeDecoder.java:40)

at org.apache.qpid.protonj2.codec.decoders.ProtonDecoder.readObject(
ProtonDecoder.java:192)

at org.apache.qpid.protonj2.client.impl.ClientMessageSupport.decodeMessage(
ClientMessageSupport.java:168)

... 7 more

My expectation from the comments on the 'body()' method is that I should
expect it to return null in this scenario? Should I be trapping this
exception and rejecting the messages to avoid poisoning my queue? (I was
planning on rejecting them anyway, but it seems weird to have to catch the
exception first.)

For reference, I'm putting messages onto the queue with the following
protonj2 calls:
sender.send(Message.create((byte[])null));
sender.send(Message.create((*String*)null));

Thank you (and sorry for the bombardment of things)


RE: [QPID PROTON PYTHON] How to send messages in loop within the same link or connection.

2024-03-15 Thread Richard Sylvain
Hi Ted.

Thank you so much!

It's working fine with this timer.

Sylvain
-Original Message-
From: Ted Ross  
Sent: Thursday, March 14, 2024 4:41 PM
To: users@qpid.apache.org
Subject: Re: [QPID PROTON PYTHON] How to send messages in loop within the same 
link or connection.

Richard,

If you look in the Python examples directory, you'll find an example called 
recurring_timer.py.  This shows how you can set up a recurring timer that fires 
every 4 seconds.  When the timer fires, you can send your 30 messages in a 
loop.  I would recommend checking the available credit on the sender 
(sender.credit I think) and to not send any more messages than you have credit 
for.

You should never write an infinite loop, nor should you ever call a blocking 
"sleep" function.

HTH
-Ted

On Thu, Mar 14, 2024 at 10:48 AM Richard Sylvain < sylvain.rich...@skyguide.ch> 
wrote:

> Hi all.
> I would like to know how to send messages in an infinite loop within 
> the same producer (link). Or at least the same connection.
>
> I would like to send 30 messages then sleep 4 seconds in loop.
>
> I am not specialist of event programming. Could you share a sample please.
>
> As in the QPID proton python example.
> I start my proton container with a sender MessagingHandler.
> I create my AMQP1.0 connection and my sender (link) on the on_start method.
> Then I send all the messages in the  on_sendable method.
>
> I observe that the events on_accepted or on_rejected are not called 
> until the on_sendable method is completed.
>
> So I don't know how to do an infinite loop!
>
> Thank you for helping me.
>