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