mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#9307 Python: avoid assigning same port number to multiple grpc sessions
* Python: avoid assigning same port number to multiple grpc sessions * Add retry count when checking for port number file * Use grpc to find and use port number * Add test used to start several instances of resinsight at the same time Testing up to 50 instances works well * Python: allow launch_port == 0 to assign port by GRPC in Instance.launch(). Also allow longer wait before failing the port number file reading: it can take some time to launch when launching lots of instances at the same time.
This commit is contained in:
committed by
GitHub
parent
587f700ae4
commit
c2b5ab8d2c
@@ -9,6 +9,7 @@ import os
|
||||
import socket
|
||||
import logging
|
||||
import time
|
||||
import tempfile
|
||||
|
||||
import grpc
|
||||
|
||||
@@ -56,6 +57,22 @@ class Instance:
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def __read_port_number_from_file(file_path):
|
||||
retry_count = 0
|
||||
while not os.path.exists(file_path) and retry_count < 30:
|
||||
time.sleep(1)
|
||||
retry_count = retry_count + 1
|
||||
|
||||
print("Portnumber file retry count : ", retry_count)
|
||||
|
||||
if os.path.isfile(file_path):
|
||||
with open(file_path) as f:
|
||||
value = f.readline()
|
||||
return int(value)
|
||||
else:
|
||||
return -1
|
||||
|
||||
@staticmethod
|
||||
def launch(
|
||||
resinsight_executable="",
|
||||
@@ -73,18 +90,19 @@ class Instance:
|
||||
environment variable.
|
||||
console (bool): If True, launch as console application, without GUI.
|
||||
launch_port(int): If -1 will use the default port 50051 or RESINSIGHT_GRPC_PORT
|
||||
if anything else, ResInsight will try to launch with this port
|
||||
if anything else, ResInsight will try to launch with this port.
|
||||
If 0 a random port will be used.
|
||||
command_line_parameters(list): Additional parameters as string entries in the list.
|
||||
Returns:
|
||||
Instance: an instance object if it worked. None if not.
|
||||
"""
|
||||
|
||||
port = 50051
|
||||
requested_port = 50051
|
||||
port_env = os.environ.get("RESINSIGHT_GRPC_PORT")
|
||||
if port_env:
|
||||
port = int(port_env)
|
||||
requested_port = int(port_env)
|
||||
if launch_port != -1:
|
||||
port = launch_port
|
||||
requested_port = launch_port
|
||||
|
||||
if not resinsight_executable:
|
||||
resinsight_executable = os.environ.get("RESINSIGHT_EXECUTABLE")
|
||||
@@ -95,12 +113,6 @@ class Instance:
|
||||
)
|
||||
return None
|
||||
|
||||
print("Trying port " + str(port))
|
||||
while Instance.__is_port_in_use(port):
|
||||
port += 1
|
||||
print("Trying port " + str(port))
|
||||
|
||||
print("Port " + str(port))
|
||||
print("Trying to launch", resinsight_executable)
|
||||
|
||||
if command_line_parameters is None:
|
||||
@@ -108,19 +120,33 @@ class Instance:
|
||||
elif isinstance(command_line_parameters, str):
|
||||
command_line_parameters = [str]
|
||||
|
||||
parameters = ["ResInsight", "--server", str(port)] + command_line_parameters
|
||||
if console:
|
||||
print("Launching as console app")
|
||||
parameters.append("--console")
|
||||
with tempfile.TemporaryDirectory() as tmp_dir_path:
|
||||
port_number_file = tmp_dir_path + "/portnumber.txt"
|
||||
parameters = [
|
||||
"ResInsight",
|
||||
"--server",
|
||||
requested_port,
|
||||
"--portnumberfile",
|
||||
port_number_file,
|
||||
] + command_line_parameters
|
||||
if console:
|
||||
print("Launching as console app")
|
||||
parameters.append("--console")
|
||||
|
||||
# Stringify all parameters
|
||||
for i in range(0, len(parameters)):
|
||||
parameters[i] = str(parameters[i])
|
||||
# Stringify all parameters
|
||||
for i in range(0, len(parameters)):
|
||||
parameters[i] = str(parameters[i])
|
||||
|
||||
pid = os.spawnv(os.P_NOWAIT, resinsight_executable, parameters)
|
||||
if pid:
|
||||
instance = Instance(port=port, launched=True)
|
||||
return instance
|
||||
pid = os.spawnv(os.P_NOWAIT, resinsight_executable, parameters)
|
||||
if pid:
|
||||
port = Instance.__read_port_number_from_file(port_number_file)
|
||||
if port == -1:
|
||||
print("Unable to read port number. Launch failed.")
|
||||
# Need to kill the process using PID since there is no GRPC connection to use.
|
||||
os.kill(pid)
|
||||
else:
|
||||
instance = Instance(port=port, launched=True)
|
||||
return instance
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
@@ -178,10 +204,10 @@ class Instance:
|
||||
port(int): port number
|
||||
"""
|
||||
logging.basicConfig()
|
||||
location = "localhost:" + str(port)
|
||||
self.location = "localhost:" + str(port)
|
||||
|
||||
self.channel = grpc.insecure_channel(
|
||||
location, options=[("grpc.enable_http_proxy", False)]
|
||||
self.location, options=[("grpc.enable_http_proxy", False)]
|
||||
)
|
||||
self.launched = launched
|
||||
self.commands = Commands_pb2_grpc.CommandsStub(self.channel)
|
||||
@@ -189,7 +215,7 @@ class Instance:
|
||||
# Main version check package
|
||||
self.app = App_pb2_grpc.AppStub(self.channel)
|
||||
|
||||
self._check_connection_and_version(self.channel, launched, location)
|
||||
self._check_connection_and_version(self.channel, launched, self.location)
|
||||
|
||||
# Intercept UNAVAILABLE errors and retry on failures
|
||||
interceptors = (
|
||||
|
||||
Reference in New Issue
Block a user