Use TCP keepalives for ovsdb connections
Ultimately, this is something that should be fixed in python-ovs, but setting the SO_KEEPALIVE socket option benefits the client by removing the need to send 'echo' requests, which can time out on an overloaded ovsdb-server, which causes a disconnection which then# adds even more load on the ovsdb-server as it has to send the entire db contents over the wire after the connection is restored. This patch ports the optimisation form neutron to reduce the likelyhood of a reconnection which can cause the nova compute agent to hang temporarily while the connection is reestablished. Change-Id: I984ec62730276f8ee60d71a02a98fbfc4c37f7d8 Related-Bug: #1930926 Partial-Bug: #1929446
This commit is contained in:
parent
b837c1a74f
commit
09c0629bb7
|
@ -10,7 +10,12 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import functools
|
||||
import socket
|
||||
|
||||
from ovs.db import idl
|
||||
from ovs import socket_util
|
||||
from ovs import stream
|
||||
from ovsdbapp.backend.ovs_idl import connection
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
from ovsdbapp.backend.ovs_idl import vlog
|
||||
|
@ -49,3 +54,43 @@ class NeutronOvsdbIdl(impl_idl.OvsdbIdl, api.ImplAPI):
|
|||
|
||||
def has_table_column(self, table, column):
|
||||
return column in self._get_table_columns(table)
|
||||
|
||||
|
||||
# this is derived form https://review.opendev.org/c/openstack/neutron/+/794892
|
||||
def add_keepalives(fn):
|
||||
@functools.wraps(fn)
|
||||
def _open(*args, **kwargs):
|
||||
error, sock = fn(*args, **kwargs)
|
||||
try:
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
||||
except socket.error as e:
|
||||
sock.close()
|
||||
return socket_util.get_exception_errno(e), None
|
||||
return error, sock
|
||||
return _open
|
||||
|
||||
|
||||
class NoProbesMixin:
|
||||
@staticmethod
|
||||
def needs_probes():
|
||||
# If we are using keepalives, we can force probe_interval=0
|
||||
return False
|
||||
|
||||
|
||||
class TCPStream(stream.TCPStream, NoProbesMixin):
|
||||
@classmethod
|
||||
@add_keepalives
|
||||
def _open(cls, suffix, dscp):
|
||||
return super()._open(suffix, dscp)
|
||||
|
||||
|
||||
class SSLStream(stream.SSLStream, NoProbesMixin):
|
||||
@classmethod
|
||||
@add_keepalives
|
||||
def _open(cls, suffix, dscp):
|
||||
return super()._open(suffix, dscp)
|
||||
|
||||
|
||||
# Overwriting globals in a library is clearly a good idea
|
||||
stream.Stream.register_method("tcp", TCPStream)
|
||||
stream.Stream.register_method("ssl", SSLStream)
|
||||
|
|
Loading…
Reference in New Issue