utils.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import asyncio
  2. import random
  3. import socket
  4. import string
  5. import time
  6. from collections import OrderedDict
  7. from contextlib import closing
  8. from os.path import abspath, dirname
  9. project_dir = dirname(abspath(__file__))
  10. STATIC_PATH = '%s/html' % project_dir
  11. async def wait_host_port(host, port, duration=10, delay=2):
  12. """Repeatedly try if a port on a host is open until duration seconds passed
  13. from: https://gist.github.com/betrcode/0248f0fda894013382d7#gistcomment-3161499
  14. :param str host: host ip address or hostname
  15. :param int port: port number
  16. :param int/float duration: Optional. Total duration in seconds to wait, by default 10
  17. :param int/float delay: Optional. Delay in seconds between each try, by default 2
  18. :return: awaitable bool
  19. """
  20. tmax = time.time() + duration
  21. while time.time() < tmax:
  22. try:
  23. _reader, writer = await asyncio.wait_for(asyncio.open_connection(host, port), timeout=5)
  24. writer.close()
  25. await writer.wait_closed()
  26. return True
  27. except:
  28. if delay:
  29. await asyncio.sleep(delay)
  30. return False
  31. def get_free_port():
  32. """
  33. pick a free port number
  34. :return int: port number
  35. """
  36. with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
  37. s.bind(('', 0))
  38. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  39. return s.getsockname()[1]
  40. def random_str(len=16):
  41. """生成小写字母和数组组成的随机字符串
  42. :param int len: 字符串长度
  43. """
  44. return ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(len))
  45. def run_as_function(gen):
  46. res = None
  47. while 1:
  48. try:
  49. res = gen.send(res)
  50. except StopIteration as e:
  51. if len(e.args) == 1:
  52. return e.args[0]
  53. return
  54. async def to_coroutine(gen):
  55. res = None
  56. while 1:
  57. try:
  58. c = gen.send(res)
  59. res = await c
  60. except StopIteration as e:
  61. if len(e.args) == 1:
  62. return e.args[0]
  63. return
  64. class LRUDict(OrderedDict):
  65. """
  66. Store items in the order the keys were last recent updated.
  67. The last recent updated item was in end.
  68. The last furthest updated item was in front.
  69. """
  70. def __setitem__(self, key, value):
  71. OrderedDict.__setitem__(self, key, value)
  72. self.move_to_end(key)