callback in `SocketService`
paulfantom committed
Jul 15, 2016 at 20:03 UTC
a6b4a8ef36487c98fd6b74b18c3818688f4f1409
2 files changed
+55
-21
python.d/python_modules/base.py
+44
-21
@@ -473,9 +473,9 @@ class UrlService(SimpleService):
473
474
class SocketService(SimpleService):
475
def __init__(self, configuration=None, name=None):
476
+ self._sock = None
477
self.host = "localhost"
478
self.port = None
478
- self.sock = None
479
self.unix_socket = None
480
self.request = ""
481
SimpleService.__init__(self, configuration=configuration, name=name)
@@ -485,61 +485,84 @@ class SocketService(SimpleService):
485
Get raw data with low-level "socket" module.
486
:return: str
487
"""
488
- if self.sock is None:
488
+ if self._sock is None:
489
try:
490
if self.unix_socket is None:
491
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
492
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
491
+ self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
492
+ self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
493
#sock.setsockopt(socket.SOL_SOCKET, socket.TCP_NODELAY, 1)
494
#sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
495
#sock.settimeout(self.update_every)
496
- sock.settimeout(0.5)
497
- sock.connect((self.host, self.port))
498
- sock.settimeout(0.5) # Just to be sure
496
+ self._sock.settimeout(0.5)
497
+ self._sock.connect((self.host, self.port))
498
+ self._sock.settimeout(0.5) # Just to be sure
499
else:
500
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
501
- #sock.settimeout(self.update_every)
502
- sock.settimeout(0.05)
503
- sock.connect(self.unix_socket)
504
- sock.settimeout(0.05) # Just to be sure
500
+ self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
501
+ #self._sock.settimeout(self.update_every)
502
+ self._sock.settimeout(0.05)
503
+ self._sock.connect(self.unix_socket)
504
+ self._sock.settimeout(0.05) # Just to be sure
505
506
except Exception as e:
507
self.error(str(e), "used configuration: host:", str(self.host), "port:", str(self.port), "socket:", str(self.unix_socket))
508
- self.sock = None
508
+ self._sock = None
509
return None
510
511
if self.request != "".encode():
512
try:
513
- sock.send(self.request)
513
+ self._sock.send(self.request)
514
except Exception as e:
515
try:
516
- sock.shutdown(1)
517
- sock.close()
516
+ self._sock.shutdown(1)
517
+ self._sock.close()
518
except:
519
pass
520
- self.sock = None
520
+ self._sock = None
521
self.error(str(e), "used configuration: host:", str(self.host), "port:", str(self.port), "socket:", str(self.unix_socket))
522
return None
523
+ # data = ""
524
+ # import select
525
+ # while True:
526
+ # try:
527
+ # ready_to_read, _, in_error = select.select([sock, ], [], [], 0.01)
528
+ # except Exception as e:
529
+ # self.debug("SELECT", str(e))
530
+ # sock.shutdown(0)
531
+ # break
532
+ # if len(ready_to_read) > 0:
533
+ # buf = sock.recv(1024)
534
+ # if len(buf) == 0 or buf is None:
535
+ # break
536
+ # data += buf.decode()
537
+ # if data == "":
538
+ # return None
539
+ # return data
540
541
size = 2
542
try:
526
- data = sock.recv(size).decode()
543
+ data = self._sock.recv(size).decode()
544
except Exception as e:
545
self.error(str(e), "used configuration: host:", str(self.host), "port:", str(self.port), "socket:", str(self.unix_socket))
529
- sock.close()
546
+ self._sock.close()
547
return None
548
549
while True:
550
# implement something like TCP Window Scaling
551
if size < 4096:
552
size *= 2
536
- buf = sock.recv(size)
553
+ buf = self._sock.recv(size)
554
data += buf.decode()
555
if len(buf) < size:
539
- break
556
+ if self._more_data_available():
557
+ size = 2
558
+ else:
559
+ break
560
561
return data
562
563
+ def _more_data_available(self):
564
+ return False
565
+
566
def _parse_config(self):
567
"""
568
Parse configuration data
python.d/squid.chart.py
+11
@@ -3,6 +3,7 @@
3
# Author: Pawel Krupa (paulfantom)
4
5
from base import SocketService
6
+import select
7
8
# default module values (can be overridden per job in `config`)
9
# update_every = 2
@@ -76,6 +77,16 @@ class Service(SocketService):
77
else:
78
return data
79
80
+ def _more_data_available(self):
81
+ try:
82
+ ready_to_read, _, in_error = select.select([self._sock, ], [], [], 0.05)
83
+ except Exception as e:
84
+ self.debug("select returned exception", str(e))
85
+ if len(ready_to_read) > 0:
86
+ return True
87
+ else:
88
+ return False
89
+
90
def check(self):
91
"""
92
Parse essential configuration, autodetect squid configuration (if needed), and check if data is available