You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
2.3 KiB

4 years ago
  1. """The client and server for a basic ping-pong style heartbeat.
  2. """
  3. #-----------------------------------------------------------------------------
  4. # Copyright (C) 2008-2011 The IPython Development Team
  5. #
  6. # Distributed under the terms of the BSD License. The full license is in
  7. # the file COPYING, distributed as part of this software.
  8. #-----------------------------------------------------------------------------
  9. #-----------------------------------------------------------------------------
  10. # Imports
  11. #-----------------------------------------------------------------------------
  12. import errno
  13. import os
  14. import socket
  15. from threading import Thread
  16. import zmq
  17. from jupyter_client.localinterfaces import localhost
  18. #-----------------------------------------------------------------------------
  19. # Code
  20. #-----------------------------------------------------------------------------
  21. class Heartbeat(Thread):
  22. "A simple ping-pong style heartbeat that runs in a thread."
  23. def __init__(self, context, addr=None):
  24. if addr is None:
  25. addr = ('tcp', localhost(), 0)
  26. Thread.__init__(self)
  27. self.context = context
  28. self.transport, self.ip, self.port = addr
  29. if self.port == 0:
  30. if addr[0] == 'tcp':
  31. s = socket.socket()
  32. # '*' means all interfaces to 0MQ, which is '' to socket.socket
  33. s.bind(('' if self.ip == '*' else self.ip, 0))
  34. self.port = s.getsockname()[1]
  35. s.close()
  36. elif addr[0] == 'ipc':
  37. self.port = 1
  38. while os.path.exists("%s-%s" % (self.ip, self.port)):
  39. self.port = self.port + 1
  40. else:
  41. raise ValueError("Unrecognized zmq transport: %s" % addr[0])
  42. self.addr = (self.ip, self.port)
  43. self.daemon = True
  44. def run(self):
  45. self.socket = self.context.socket(zmq.ROUTER)
  46. self.socket.linger = 1000
  47. c = ':' if self.transport == 'tcp' else '-'
  48. self.socket.bind('%s://%s' % (self.transport, self.ip) + c + str(self.port))
  49. while True:
  50. try:
  51. zmq.device(zmq.QUEUE, self.socket, self.socket)
  52. except zmq.ZMQError as e:
  53. if e.errno == errno.EINTR:
  54. continue
  55. else:
  56. raise
  57. else:
  58. break