SERVER-39094,SERVER-38136: update Jasper process to reflect RPC changes; fix Windows failures due to sigterm.

This commit is contained in:
Kim Tao 2019-01-28 17:50:03 -05:00 committed by Kim Tao
parent b6958f0600
commit 9acc250dc9
3 changed files with 51 additions and 24 deletions

View File

@ -318,7 +318,9 @@ class Resmoke(object): # pylint: disable=too-many-instance-attributes
jasper_process.Process.jasper_pb2_grpc = jasper_pb2_grpc jasper_process.Process.jasper_pb2_grpc = jasper_pb2_grpc
curator_path = "build/curator" curator_path = "build/curator"
git_hash = "1b8c7344aa1daed0846e32204dffb21cfdda208c" if sys.platform == "win32":
curator_path += ".exe"
git_hash = "d846f0c875716e9377044ab2a50542724369662a"
curator_exists = os.path.isfile(curator_path) curator_exists = os.path.isfile(curator_path)
curator_same_version = False curator_same_version = False
if curator_exists: if curator_exists:

View File

@ -139,7 +139,6 @@ message ProcessTags {
message JasperProcessID { message JasperProcessID {
string value = 1; string value = 1;
} }
message OperationOutcome { message OperationOutcome {
@ -181,23 +180,39 @@ message ArchiveOptions {
} }
message DownloadInfo { message DownloadInfo {
string url = 1; string url = 1;
string path = 2; string path = 2;
ArchiveOptions archive_opts = 3; ArchiveOptions archive_opts = 3;
} }
message BuildloggerURLs { message BuildloggerURLs {
repeated string urls = 1; repeated string urls = 1;
} }
enum SignalTriggerID {
NONE = 0;
CLEANTERMINATION = 1;
}
message SignalTriggerParams {
JasperProcessID processID = 1;
SignalTriggerID signalTriggerID = 2;
}
message EventName {
string value = 1;
}
service JasperProcessManager { service JasperProcessManager {
rpc Status(google.protobuf.Empty) returns (StatusResponse); rpc Status(google.protobuf.Empty) returns (StatusResponse);
rpc Create(CreateOptions) returns (ProcessInfo); rpc Create(CreateOptions) returns (ProcessInfo);
rpc List(Filter) returns (stream ProcessInfo); rpc List(Filter) returns (stream ProcessInfo);
rpc Group(TagName) returns (stream ProcessInfo); rpc Group(TagName) returns (stream ProcessInfo);
rpc Get(JasperProcessID) returns (ProcessInfo); rpc Get(JasperProcessID) returns (ProcessInfo);
rpc Wait(JasperProcessID) returns (OperationOutcome); rpc Wait(JasperProcessID) returns (OperationOutcome);
rpc Respawn(JasperProcessID) returns (ProcessInfo);
rpc Signal(SignalProcess) returns (OperationOutcome); rpc Signal(SignalProcess) returns (OperationOutcome);
rpc Clear(google.protobuf.Empty) returns (OperationOutcome);
rpc Close(google.protobuf.Empty) returns (OperationOutcome); rpc Close(google.protobuf.Empty) returns (OperationOutcome);
rpc TagProcess(ProcessTags) returns (OperationOutcome); rpc TagProcess(ProcessTags) returns (OperationOutcome);
rpc ResetTags(JasperProcessID) returns (OperationOutcome); rpc ResetTags(JasperProcessID) returns (OperationOutcome);
@ -206,4 +221,6 @@ service JasperProcessManager {
rpc DownloadMongoDB(MongoDBDownloadOptions) returns (OperationOutcome); rpc DownloadMongoDB(MongoDBDownloadOptions) returns (OperationOutcome);
rpc ConfigureCache(CacheOptions) returns (OperationOutcome); rpc ConfigureCache(CacheOptions) returns (OperationOutcome);
rpc GetBuildloggerURLs(JasperProcessID) returns (BuildloggerURLs); rpc GetBuildloggerURLs(JasperProcessID) returns (BuildloggerURLs);
rpc RegisterSignalTriggerID(SignalTriggerParams) returns (OperationOutcome);
rpc SignalEvent(EventName) returns (OperationOutcome);
} }

View File

@ -5,6 +5,8 @@ Serves as an alternative to process.py.
from __future__ import absolute_import from __future__ import absolute_import
import sys
try: try:
import grpc import grpc
except ImportError: except ImportError:
@ -52,19 +54,28 @@ class Process(_process.Process):
def stop(self, kill=False): def stop(self, kill=False):
"""Terminate the process.""" """Terminate the process."""
signal = self.jasper_pb2.Signals.Value("TERMINATE") signal = self.jasper_pb2.Signals.Value("TERMINATE")
if kill: if sys.platform == "win32":
if not kill:
event_name = self.jasper_pb2.EventName(value="Global\\Mongo_" + str(self.pid))
signal_event = self._stub.SignalEvent(event_name)
if signal_event.success:
wait = self._stub.Wait(self._id, timeout=60)
if wait.success:
return
clean_termination_params = self.jasper_pb2.SignalTriggerParams(
processID=self._id,
signalTriggerID=self.jasper_pb2.SignalTriggerID.Value("CLEANTERMINATION"))
self._stub.RegisterSignalTriggerID(clean_termination_params)
elif kill:
signal = self.jasper_pb2.Signals.Value("KILL") signal = self.jasper_pb2.Signals.Value("KILL")
signal_process = self.jasper_pb2.SignalProcess(ProcessID=self._id, signal=signal) signal_process = self.jasper_pb2.SignalProcess(ProcessID=self._id, signal=signal)
try: val = self._stub.Signal(signal_process)
val = self._stub.Signal(signal_process) if not val.success \
if not val.success: and "cannot signal a process that has terminated" not in val.text \
raise OSError("Unable to stop process %d." % self.pid) and "os: process already finished" not in val.text:
except grpc.RpcError as err: raise OSError("Failed to signal Jasper process with pid {}: {}".format(
err.details = err.details() self.pid, val.text))
if "cannot signal a process that has terminated" not in err.details \
and "os: process already finished" not in err.details:
raise
def poll(self): def poll(self):
"""Poll.""" """Poll."""
@ -77,12 +88,9 @@ class Process(_process.Process):
def wait(self): def wait(self):
"""Wait until process has terminated and all output has been consumed by the logger pipes.""" """Wait until process has terminated and all output has been consumed by the logger pipes."""
if self._return_code is None: if self._return_code is None:
try: wait = self._stub.Wait(self._id)
wait = self._stub.Wait(self._id) if not wait.success:
self._return_code = wait.exit_code raise OSError("Failed to wait on process with pid {}: {}.".format(
except grpc.RpcError as err: self.pid, wait.text))
if "problem encountered while waiting: operation failed" not in err.details(): self._return_code = wait.exit_code
raise
wait = self._stub.Get(self._id)
self._return_code = wait.exit_code
return self._return_code return self._return_code