From 25c7b4ec8ed1aa8491ba25911ffe6b29e043e11e Mon Sep 17 00:00:00 2001 From: yael Date: Sun, 9 Nov 2014 23:48:33 +0200 Subject: [PATCH] Added keepalive interface to allow controlling the keepalive for specific number of minutes Signed-off-by: yael refactored keepalive_var to keepalive_internal change comments removed -1 Small change in comment regarding keepalive_internal --- rpyc/core/stream.py | 17 +++++++++++------ rpyc/utils/classic.py | 2 +- rpyc/utils/factory.py | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/rpyc/core/stream.py b/rpyc/core/stream.py index 7071cdc2..8812855a 100644 --- a/rpyc/core/stream.py +++ b/rpyc/core/stream.py @@ -96,7 +96,7 @@ def __init__(self, sock): @classmethod def _connect(cls, host, port, family = socket.AF_INET, socktype = socket.SOCK_STREAM, - proto = 0, timeout = 3, nodelay = False, keepalive = False): + proto = 0, timeout = 3, nodelay = False, keepalive = None): family, socktype, proto, _, sockaddr = socket.getaddrinfo(host, port, family, socktype, proto)[0] s = socket.socket(family, socktype, proto) @@ -105,13 +105,18 @@ def _connect(cls, host, port, family = socket.AF_INET, socktype = socket.SOCK_ST if nodelay: s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if keepalive: + if keepalive < 1: + raise ValueError("Keepalive minimal value is 1 minute") s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - # Linux specific: after 10 idle minutes, start sending keepalives every 5 minutes. - # Drop connection after 10 failed keepalives + num_of_keepalives = 5 + # Linux specific: after seconds, start sending keepalives every seconds. + # Drop connection after 5 failed keepalives if hasattr(socket, "TCP_KEEPIDLE") and hasattr(socket, "TCP_KEEPINTVL") and hasattr(socket, "TCP_KEEPCNT"): - s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 10 * 60) - s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 5 * 60) - s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 10) + # based on the provided keepalive value (in minutes), keepalive_internal is defined + s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, num_of_keepalives) + keepalive_internal = keepalive * 60 * 60 / num_of_keepalives * 60 + 60 + s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, keepalive_internal) + s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, keepalive_internal) return s @classmethod diff --git a/rpyc/utils/classic.py b/rpyc/utils/classic.py index cb54ac98..5792b835 100644 --- a/rpyc/utils/classic.py +++ b/rpyc/utils/classic.py @@ -55,7 +55,7 @@ def connect_pipes(input, output): """ return factory.connect_pipes(input, output, SlaveService) -def connect(host, port = DEFAULT_SERVER_PORT, ipv6 = False, keepalive = False): +def connect(host, port = DEFAULT_SERVER_PORT, ipv6 = False, keepalive=None): """ Creates a socket connection to the given host and port. diff --git a/rpyc/utils/factory.py b/rpyc/utils/factory.py index b7bddc9e..43cd0975 100644 --- a/rpyc/utils/factory.py +++ b/rpyc/utils/factory.py @@ -75,7 +75,7 @@ def connect_stdpipes(service = VoidService, config = {}): """ return connect_stream(PipeStream.from_std(), service = service, config = config) -def connect(host, port, service = VoidService, config = {}, ipv6 = False, keepalive = False): +def connect(host, port, service = VoidService, config = {}, ipv6 = False, keepalive = None): """ creates a socket-connection to the given host and port