@cryptotaxi247 / netdata-1 / commits / b6cfb65b1

non-blocking `SocketService` draft 2

paulfantom committed Jul 19, 2016 at 01:56 UTC b6cfb65b111568d35a6fce2f0a4b4a96c64b8598
3 files changed +37 -30
python.d/python_modules/base.py
+7 -14
@@ -475,7 +475,7 @@ class UrlService(SimpleService):
475 class SocketService(SimpleService):
476 def __init__(self, configuration=None, name=None):
477 self._sock = None
478 - self._keep_alive = True
478 + self._keep_alive = False
479 self.host = "localhost"
480 self.port = None
481 self.unix_socket = None
@@ -485,7 +485,7 @@ class SocketService(SimpleService):
485
486 def _connect(self):
487 """
488 - Recreate socket and connect to it since they cannot be reused
488 + Recreate socket and connect to it since sockets cannot be reused after closing
489 Available configurations are IPv6, IPv4 or UNIX socket
490 :return:
491 """
@@ -565,7 +565,7 @@ class SocketService(SimpleService):
565 data = ""
566 while True:
567 try:
568 - ready_to_read, _, in_error = select.select([self._sock], [], [], 0.01)
568 + ready_to_read, _, in_error = select.select([self._sock], [], [], 60)
569 except Exception as e:
570 self.debug("SELECT", str(e))
571 self._disconnect()
@@ -575,8 +575,10 @@ class SocketService(SimpleService):
575 if len(buf) == 0 or buf is None:
576 break
577 data += buf.decode()
578 + if self._check_raw_data(data):
579 + break
580 else:
579 - self._disconnect()
581 + # self._disconnect()
582 break
583
584 return data
@@ -593,16 +595,7 @@ class SocketService(SimpleService):
595 if not self._send():
596 return None
597
596 - finished = False
597 - data = ""
598 - prevent_infinite_loop = 1000000
599 - while not finished:
600 - data += self._receive()
601 - finished = self._check_raw_data(data)
602 - prevent_infinite_loop -= 1
603 - if prevent_infinite_loop <= 0:
604 - self.debug("Almost got into infinite loop while grabbing data. Is _check_raw_data() ok?")
605 - break
598 + data = self._receive()
599
600 if not self._keep_alive:
601 self._disconnect()
python.d/redis.chart.py
+1
@@ -66,6 +66,7 @@ class Service(SocketService):
66 self.unix_socket = None
67 self.order = ORDER
68 self.definitions = CHARTS
69 + self._keep_alive = True
70
71 def _get_data(self):
72 """
python.d/squid.chart.py
+29 -16
@@ -46,7 +46,7 @@ CHARTS = {
46 class Service(SocketService):
47 def __init__(self, configuration=None, name=None):
48 SocketService.__init__(self, configuration=configuration, name=name)
49 - self._keep_alive = False
49 + self._keep_alive = True
50 self.request = ""
51 self.host = "localhost"
52 self.port = 3128
@@ -60,7 +60,11 @@ class Service(SocketService):
60 """
61 data = {}
62 try:
63 - raw = self._get_raw_data().split('\r\n')[-1]
63 + raw = ""
64 + for tmp in self._get_raw_data().split('\r\n'):
65 + if tmp.startswith("sample_time"):
66 + raw = tmp
67 + break
68 if raw.startswith('<'):
69 self.error("invalid data received")
70 return None
@@ -72,7 +76,6 @@ class Service(SocketService):
76 self.error("invalid data received")
77 return None
78
75 - self.debug("DATA:", str(len(raw)))
79 if len(data) == 0:
80 self.error("no data received")
81 return None
@@ -80,21 +83,31 @@ class Service(SocketService):
83 return data
84
85 def _check_raw_data(self, data):
83 - if "Content-Length" not in data[:1024]: # assuming headers should be in first 1024 bytes (performance)
84 - return True # "Content-Length" not found, assume everything is ok
85 -
86 - # TODO write some parser of "Content-Length"
87 - return True
88 - length = len(data)
89 -
86 + if "Connection: keep-alive" in data[:1024]:
87 + self._keep_alive = True
88 + else:
89 + self._keep_alive = False
90
91 - supposed = 0
92 - if length >= supposed:
91 + if "client" in data and "server.all" in data:
92 return True
93 else:
94 return False
96 -
97 - return False
95 + # # TODO write some parser of "Transfer-Encoding: chunked"
96 + # if "Transfer-Encoding: chunked" in data[:1024]:
97 + # data = data[self.__last:]
98 + #
99 + #
100 + # print(data)
101 + # import time
102 + # time.sleep(10)
103 + # return False
104 + # supposed = 0
105 + # if length >= supposed:
106 + # return True
107 + # else:
108 + # return False
109 + #
110 + # return False
111
112 def check(self):
113 """
@@ -106,8 +119,8 @@ class Service(SocketService):
119 req = self.request.decode()
120 if not req.startswith("GET"):
121 req = "GET " + req
109 - if not req.endswith(" HTTP/1.0\r\n\r\n"):
110 - req += " HTTP/1.0\r\n\r\n"
122 + if not req.endswith(" HTTP/1.1\r\n\r\n"):
123 + req += " HTTP/1.1\r\n\r\n"
124 self.request = req.encode()
125 if self._get_data() is not None:
126 return True