Skip to content

Commit

Permalink
Add basic orphan handling for child processes
Browse files Browse the repository at this point in the history
  • Loading branch information
littleK0i committed Jul 13, 2018
1 parent 5e89557 commit 39d8ae3
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
14 changes: 13 additions & 1 deletion pyexasol/http_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,11 @@ def send_proxy(self):
sys.stdout.buffer.flush()

def handle_request(self):
self.server.handle_request()
# Wait for exactly one connection
while self.server.total_clients == 0:
self.server.handle_request()
utils.check_orphaned()

self.server.server_close()


Expand All @@ -249,6 +253,8 @@ class ExaTCPServer(TCPServer):
Instead of listening for incoming connections it connects to Exasol and uses proxy magic
It allows to bypass various connectivity problems (e.g. firewall)
"""
timeout = 5

def __init__(self, *args, **kwargs):
self.proxy_host = None
self.proxy_port = None
Expand All @@ -257,6 +263,8 @@ def __init__(self, *args, **kwargs):
self.compression = kwargs.pop('compression', False)
self.encryption = kwargs.pop('encryption', False)

self.total_clients = 0

super().__init__(*args, **kwargs)

def set_pipe(self, pipe):
Expand Down Expand Up @@ -293,6 +301,10 @@ class ExaHTTPRequestHandler(BaseHTTPRequestHandler):

def log_message(self, format, *args): pass

def setup(self):
super().setup()
self.server.total_clients += 1

def do_PUT(self):
# Compressed data loop
if self.server.compression:
Expand Down
5 changes: 5 additions & 0 deletions pyexasol/script_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import subprocess
import pathlib

from . import utils


class ExaScriptOutputProcess(object):
def __init__(self, host, port, output_dir=None):
Expand Down Expand Up @@ -130,6 +132,9 @@ class ExaScriptOutputServer(socketserver.ThreadingMixIn, socketserver.TCPServer)
def get_output_address(self):
return f"{socket.getfqdn()}:{self.socket.getsockname()[1]}"

def service_actions(self):
utils.check_orphaned()


class ExaScriptOutputHandler(socketserver.StreamRequestHandler):
def setup(self):
Expand Down
13 changes: 13 additions & 0 deletions pyexasol/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import tempfile
import socket
import ssl
import os

from . import constant

Expand Down Expand Up @@ -105,3 +106,15 @@ def generate_adhoc_ssl_context():
context.load_cert_chain(certfile=cert_file.name, keyfile=key_file.name)

return context


def check_orphaned():
"""
Raise exception if current process is "orphaned" (parent process is dead)
It is useful to stop PyEXASOL HTTP servers from being stuck in process list when parent process was killed
Currently it works only for Unix
Please let me know if you know a good way to detect orphans on Windows
"""
if os.getppid() == 1:
raise RuntimeError("Current process is orphaned, ppid=1")
2 changes: 1 addition & 1 deletion pyexasol/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.3.29'
__version__ = '0.3.30'

0 comments on commit 39d8ae3

Please sign in to comment.