# Path: coolamqp/utils.py
# IMPORT_ERRORS = (ModuleNotFoundError, ImportError)
# IMPORT_ERRORS = (ImportError, )
# def prctl_set_name(name):
# 
# Path: coolamqp/framing/frames.py
# class AMQPHeartbeatFrame(AMQPFrame):
#     FRAME_TYPE = FRAME_HEARTBEAT
#     LENGTH = 8
#     DATA = STRUCT_BHLB.pack(FRAME_HEARTBEAT, 0, 0, FRAME_END)
#     __slots__ = ()
# 
#     def __init__(self):
#         AMQPFrame.__init__(self, 0)
# 
#     def write_to(self, buf):
#         buf.write(AMQPHeartbeatFrame.DATA)
# 
#     def get_size(self):
#         return AMQPHeartbeatFrame.LENGTH
# 
#     def __str__(self):
#         return 'AMQPHeartbeatFrame()'
# 
# Path: coolamqp/uplink/connection/watches.py
# class AnyWatch(Watch):
#     """
#     Watch that listens for any frame.
# 
#     It does not listen for failures.
# 
#     Used because heartbeating is implemented improperly EVERYWHERE
#     (ie. you might not get a heartbeat when connection is so loaded it just can't get it in time,
#     due to loads and loads of message exchanging).
# 
#     Eg. RabbitMQ will happily disconnect you if you don't, but it can get lax with heartbeats
#     as it wants.
#     """
# 
#     def __init__(self, callable):
#         super(AnyWatch, self).__init__(None, False)
#         self.callable = callable
# 
#     def is_triggered_by(self, frame):
#         try:
#             self.callable(frame)
#         except Watch.CancelMe:
#             self.cancel()
#         return True


import typing as tp
from coolamqp.utils import monotonic
from coolamqp.framing.frames import AMQPHeartbeatFrame
from coolamqp.uplink.connection.watches import AnyWatch
# coding=UTF-8
from __future__ import absolute_import, division, print_function





class Heartbeater(object):
    """
    An object that handles heartbeats
    """

    def __init__(self, connection,  # type: coolamqp.uplink.connection.Connection
                 heartbeat_interval=0  # type: tp.Union[int, float]
                 ):
        self.connection = connection
        self.heartbeat_interval = heartbeat_interval

        self.last_heartbeat_on = monotonic()  # last heartbeat from server

        self.connection.watchdog(self.heartbeat_interval, self.on_timer)
        self.connection.watch(AnyWatch(self.on_heartbeat))

    def on_heartbeat(self, frame):

# Path: coolamqp/utils.py
# IMPORT_ERRORS = (ModuleNotFoundError, ImportError)
# IMPORT_ERRORS = (ImportError, )
# def prctl_set_name(name):
# 
# Path: coolamqp/framing/frames.py
# class AMQPHeartbeatFrame(AMQPFrame):
#     FRAME_TYPE = FRAME_HEARTBEAT
#     LENGTH = 8
#     DATA = STRUCT_BHLB.pack(FRAME_HEARTBEAT, 0, 0, FRAME_END)
#     __slots__ = ()
# 
#     def __init__(self):
#         AMQPFrame.__init__(self, 0)
# 
#     def write_to(self, buf):
#         buf.write(AMQPHeartbeatFrame.DATA)
# 
#     def get_size(self):
#         return AMQPHeartbeatFrame.LENGTH
# 
#     def __str__(self):
#         return 'AMQPHeartbeatFrame()'
# 
# Path: coolamqp/uplink/connection/watches.py
# class AnyWatch(Watch):
#     """
#     Watch that listens for any frame.
# 
#     It does not listen for failures.
# 
#     Used because heartbeating is implemented improperly EVERYWHERE
#     (ie. you might not get a heartbeat when connection is so loaded it just can't get it in time,
#     due to loads and loads of message exchanging).
# 
#     Eg. RabbitMQ will happily disconnect you if you don't, but it can get lax with heartbeats
#     as it wants.
#     """
# 
#     def __init__(self, callable):
#         super(AnyWatch, self).__init__(None, False)
#         self.callable = callable
# 
#     def is_triggered_by(self, frame):
#         try:
#             self.callable(frame)
#         except Watch.CancelMe:
#             self.cancel()
#         return True


# Path: coolamqp/uplink/heartbeat.py
import typing as tp
from coolamqp.utils import monotonic
from coolamqp.framing.frames import AMQPHeartbeatFrame
from coolamqp.uplink.connection.watches import AnyWatch

# coding=UTF-8
from __future__ import absolute_import, division, print_function





class Heartbeater(object):
    """
    An object that handles heartbeats
    """

    def __init__(self, connection,  # type: coolamqp.uplink.connection.Connection
                 heartbeat_interval=0  # type: tp.Union[int, float]
                 ):
        self.connection = connection
        self.heartbeat_interval = heartbeat_interval

        self.last_heartbeat_on = monotonic()  # last heartbeat from server

        self.connection.watchdog(self.heartbeat_interval, self.on_timer)
        self.connection.watch(AnyWatch(self.on_heartbeat))

    def on_heartbeat(self, frame):

        self.last_heartbeat_on = monotonic()