You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@qpid.apache.org by "Schaik, Jacco van" <Ja...@nlr.nl> on 2019/06/17 07:32:48 UTC

Connection driver and heartbeats

Hi,

I'm building an application using the Qpid Proton C API, version 0.28.0. I'm using a Connection Driver because my application has its own event loop.?

Everything seems to be working, but the application on the other side of the connection has an idle timeout, so if nothing comes over the line for (in my case) 30 seconds it times out and drops the connection. I know AMQP has heartbeat messages that can be used to keep the connection open, but obviously Proton doesn't get a chance to send them when I'm waiting in my own event loop.

Now I can have my event loop wake up every now and then, and call a Proton function to send a heartbeat. But I haven't been able to find a function that does that?. I've tried calling pn_transport_tick() but that doesn't seem to work. Is there some other function that will send a heartbeat for me?


Any info greatly appreciated.


Regards, Jacco

Re: Connection driver and heartbeats

Posted by Robbie Gemmell <ro...@gmail.com>.
I dont know much about Connection Driver, or C in general, but
'tick'ing is the route to provoke heartbeat generation (and also part
of enforcing lack of received traffic to satisfy any idle-timeout the
local transport has adverised) by the transport.

They will only be generated if actually requested by the other side,
i.e based on the peers advertised idle-timeout in the Open frame they
sent, and only when required (i.e lack of other live traffic flow
resulting in being idle long enough) at the point the method is being
run (indicated by the arg). The return from 'tick' indicates the next
point it needs to be run to decide what to do to ensure the local
and/or remote idle-timeout requirements are satisfied/enforced. If
heartbeat output is generated, you'll need to send the resulting
transport output as at other points.

Robbie

On Mon, 17 Jun 2019 at 08:33, Schaik, Jacco van <Ja...@nlr.nl> wrote:
>
> Hi,
>
> I'm building an application using the Qpid Proton C API, version 0.28.0. I'm using a Connection Driver because my application has its own event loop.?
>
> Everything seems to be working, but the application on the other side of the connection has an idle timeout, so if nothing comes over the line for (in my case) 30 seconds it times out and drops the connection. I know AMQP has heartbeat messages that can be used to keep the connection open, but obviously Proton doesn't get a chance to send them when I'm waiting in my own event loop.
>
> Now I can have my event loop wake up every now and then, and call a Proton function to send a heartbeat. But I haven't been able to find a function that does that?. I've tried calling pn_transport_tick() but that doesn't seem to work. Is there some other function that will send a heartbeat for me?
>
>
> Any info greatly appreciated.
>
>
> Regards, Jacco

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


Re: Connection driver and heartbeats

Posted by Alan Conway <ac...@redhat.com>.
On Mon, Jun 17, 2019 at 3:33 AM Schaik, Jacco van <Ja...@nlr.nl>
wrote:

> Hi,
>
> I'm building an application using the Qpid Proton C API, version 0.28.0.
> I'm using a Connection Driver because my application has its own event
> loop.?
>
> Everything seems to be working, but the application on the other side of
> the connection has an idle timeout, so if nothing comes over the line for
> (in my case) 30 seconds it times out and drops the connection. I know AMQP
> has heartbeat messages that can be used to keep the connection open, but
> obviously Proton doesn't get a chance to send them when I'm waiting in my
> own event loop.
>
> Now I can have my event loop wake up every now and then, and call a Proton
> function to send a heartbeat. But I haven't been able to find a function
> that does that?. I've tried calling pn_transport_tick() but that doesn't
> seem to work. Is there some other function that will send a heartbeat for
> me?
>
>
> Any info greatly appreciated.
>
>
> Regards, Jacco
>

Re: Connection driver and heartbeats

Posted by Jacco van Schaik <ja...@nlr.nl>.
So then Alan Conway says:
>On Mon, Jun 17, 2019 at 3:33 AM Schaik, Jacco van <Ja...@nlr.nl>
>wrote:
>
>> Hi,
>>
>> I'm building an application using the Qpid Proton C API, version 0.28.0.
>> I'm using a Connection Driver because my application has its own event
>> loop.?
>>
>> Everything seems to be working, but the application on the other side of
>> the connection has an idle timeout, so if nothing comes over the line for
>> (in my case) 30 seconds it times out and drops the connection. I know AMQP
>> has heartbeat messages that can be used to keep the connection open, but
>> obviously Proton doesn't get a chance to send them when I'm waiting in my
>> own event loop.
>>
>> Now I can have my event loop wake up every now and then, and call a Proton
>> function to send a heartbeat. But I haven't been able to find a function
>> that does that?. I've tried calling pn_transport_tick() but that doesn't
>> seem to work. Is there some other function that will send a heartbeat for
>> me?
>>
>
>pn_transport_tick() takes a timestamp and checks if a heartbeat is needed.
>If it is, it adds that to the "to-do" list for the next outgoing write and
>marks the transport as writable. The heartbeat actually will be sent on the
>next write. Note that heart beats are *only* sent if the connection is idle
>for longer than the idle-timeout, as if there is normal traffic then no
>heart beats are needed.
>
>It is safe and recommended to call pn_transport_tick() every time you wake
>for IO. It will queue up a heartbeat frame for writing if needed, and
>return the next time at which it should be called. You should set a timer
>on your event loop in case there is no IO before then. You can reset the
>timer on each call to pn_transport_tick to avoid un-necessary wakeups, but
>it's always safe to make  extra calls to tick(). The timestamp you use
>doesn't have to represent any particular time, it should be a monotonically
>increasing count of milliseconds, for exmaple libuv's uv_time() or the
>POSIX CLOCK_MONOTONIC.

Right, that was the missing link. I was using a counter that went up by
one on every call (that also rises monotonically, after all). I've
changed it to go up by 1000 on every call, and now Proton is giving me
heartbeats to send out.

Thank you!

Groeten,					- Jacco

-- 
+--------------------------+ It's 15:32 CEST on Monday June 17 2019.
|     Jacco van Schaik     | Outside it's 24°C with a light breeze from
| jacco@jaccovanschaik.net | the southwest.
|  www.jaccovanschaik.net  | 
+--------------------------+ 

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


Re: Connection driver and heartbeats

Posted by Alan Conway <ac...@redhat.com>.
On Mon, Jun 17, 2019 at 3:33 AM Schaik, Jacco van <Ja...@nlr.nl>
wrote:

> Hi,
>
> I'm building an application using the Qpid Proton C API, version 0.28.0.
> I'm using a Connection Driver because my application has its own event
> loop.?
>
> Everything seems to be working, but the application on the other side of
> the connection has an idle timeout, so if nothing comes over the line for
> (in my case) 30 seconds it times out and drops the connection. I know AMQP
> has heartbeat messages that can be used to keep the connection open, but
> obviously Proton doesn't get a chance to send them when I'm waiting in my
> own event loop.
>
> Now I can have my event loop wake up every now and then, and call a Proton
> function to send a heartbeat. But I haven't been able to find a function
> that does that?. I've tried calling pn_transport_tick() but that doesn't
> seem to work. Is there some other function that will send a heartbeat for
> me?
>

pn_transport_tick() takes a timestamp and checks if a heartbeat is needed.
If it is, it adds that to the "to-do" list for the next outgoing write and
marks the transport as writable. The heartbeat actually will be sent on the
next write. Note that heart beats are *only* sent if the connection is idle
for longer than the idle-timeout, as if there is normal traffic then no
heart beats are needed.

It is safe and recommended to call pn_transport_tick() every time you wake
for IO. It will queue up a heartbeat frame for writing if needed, and
return the next time at which it should be called. You should set a timer
on your event loop in case there is no IO before then. You can reset the
timer on each call to pn_transport_tick to avoid un-necessary wakeups, but
it's always safe to make  extra calls to tick(). The timestamp you use
doesn't have to represent any particular time, it should be a monotonically
increasing count of milliseconds, for exmaple libuv's uv_time() or the
POSIX CLOCK_MONOTONIC.

You can see examples in the proton proactor event-loop code, for example:
https://github.com/apache/qpid-proton/blob/master/c/src/proactor/epoll.c#L1425
I don't think we have any surviving examples of transport-based integration
but there are 3 proactors (epoll, iocp and libuv) that should provide
pretty good examples.



>
>
> Any info greatly appreciated.
>
>
> Regards, Jacco
>