#4576 Python: Improve error handling and add example

This commit is contained in:
Gaute Lindkvist 2019-08-14 09:14:12 +02:00
parent 84495641f9
commit 197279ccbf
8 changed files with 99 additions and 67 deletions

View File

@ -173,6 +173,7 @@ if (RESINSIGHT_GRPC_PYTHON_EXECUTABLE)
"rips/examples/CommandExample.py"
"rips/examples/CaseGridGroup.py"
"rips/examples/CaseInfoStreamingExample.py"
"rips/examples/ErrorHandling.py"
"rips/examples/SoilPorvAsync.py"
"rips/examples/SoilPorvSync.py"
"rips/examples/SelectedCases.py"

View File

@ -8,5 +8,5 @@ message Empty
message ClientToServerStreamReply
{
int64 values_accepted = 1;
int64 accepted_value_count = 1;
}

View File

@ -25,13 +25,7 @@ class Commands:
self.commands = CmdRpc.CommandsStub(channel)
def __execute(self, **commandParams):
try:
return self.commands.Execute(Cmd.CommandParams(**commandParams))
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Command not found", commandParams.keys())
else:
print("Other error", e)
########################
# Case Control Commands
@ -71,8 +65,6 @@ class Commands:
"""
commandReply = self.__execute(loadCase=Cmd.FilePathRequest(path=path))
assert(commandReply is not None)
assert(commandReply.HasField("loadCaseResult"))
return Case(self.channel, commandReply.loadCaseResult.id)
def replaceCase(self, newGridFile, caseId=0):
@ -107,14 +99,10 @@ class Commands:
A case group id and name
"""
commandReply = self.__execute(createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(casePaths=casePaths))
assert(commandReply is not None)
assert(commandReply.HasField("createGridCaseGroupResult"))
return (commandReply.createGridCaseGroupResult.groupId, commandReply.createGridCaseGroupResult.groupName)
def createStatisticsCase(self, caseGroupId):
commandReply = self.__execute(createStatisticsCase=Cmd.CreateStatisticsCaseRequest(caseGroupId=caseGroupId))
assert(commandReply is not None)
assert(commandReply.HasField("createStatisticsCaseResult"))
return commandReply.createStatisticsCaseResult.caseId;
##################

View File

@ -12,6 +12,13 @@ from Definitions_pb2 import ClientToServerStreamReply
class Properties:
""" Class for streaming properties to and from ResInsight
Attributes:
chunkSize(int): The size of each chunk during value streaming.
A good chunk size is 64KiB = 65536B.
Meaning the ideal number of doubles would be 8192.
However we need overhead space, so the default is 8160.
This leaves 256B for overhead.
"""
def __init__(self, case):
"""
@ -20,6 +27,8 @@ class Properties:
"""
self.case = case
self.propertiesStub = Properties_pb2_grpc.PropertiesStub(self.case.channel)
self.chunkSize = 8160
def __generatePropertyInputIterator(self, values_iterator, parameters):
chunk = Properties_pb2.PropertyInputChunk()
@ -32,11 +41,7 @@ class Properties:
yield chunk
def __generatePropertyInputChunks(self, array, parameters):
# Each double is 8 bytes. A good chunk size is 64KiB = 65536B
# Meaning ideal number of doubles would be 8192.
# However we need overhead space, so if we choose 8160 in chunk size
# We have 256B left for overhead which should be plenty
chunkSize = 44431
index = -1
while index < len(array):
chunk = Properties_pb2.PropertyInputChunk()
@ -44,7 +49,7 @@ class Properties:
chunk.params.CopyFrom(parameters)
index += 1
else:
actualChunkSize = min(len(array) - index + 1, chunkSize)
actualChunkSize = min(len(array) - index + 1, self.chunkSize)
chunk.values.CopyFrom(Properties_pb2.PropertyChunk(values = array[index:index+actualChunkSize]))
index += actualChunkSize
@ -184,14 +189,9 @@ class Properties:
property_name = propertyName,
time_step = timeStep,
porosity_model = porosityModelEnum)
try:
request_iterator = self.__generatePropertyInputIterator(values_iterator, request)
self.propertiesStub.SetActiveCellProperty(request_iterator)
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Command not found")
else:
print("Other error", e)
def setActiveCellProperty(self, values, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'):
"""Set a cell property for all active cells.
@ -210,17 +210,10 @@ class Properties:
property_name = propertyName,
time_step = timeStep,
porosity_model = porosityModelEnum)
try:
request_iterator = self.__generatePropertyInputChunks(values, request)
reply = self.propertiesStub.SetActiveCellProperty(request_iterator)
if reply.values_accepted != len(values):
print("ERROR: Attempted to write outside bounds of " + propertyName + " data storage");
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Command not found")
else:
print("Other error", e)
if reply.accepted_value_count < len(values):
raise IndexError
def setGridProperty(self, values, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'):
"""Set a cell property for all grid cells.
@ -241,14 +234,8 @@ class Properties:
time_step = timeStep,
grid_index = gridIndex,
porosity_model = porosityModelEnum)
try:
request_iterator = self.__generatePropertyInputChunks(values, request)
reply = self.propertiesStub.SetGridProperty(request_iterator)
if reply.values_accepted != len(values):
print("ERROR: Attempted to write outside bounds of " + propertyName + " data storage");
if reply.accepted_value_count < len(values):
raise IndexError
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Command not found")
else:
print("Other error", e)

View File

@ -0,0 +1,52 @@
import rips
import grpc
resInsight = rips.Instance.find()
case = None
# Try loading a non-existing case. We should get a grpc.RpcError exception from the server
try:
case = resInsight.project.loadCase("Nonsense")
except grpc.RpcError as e:
print("Expected Server Exception Received: ", e)
case = resInsight.project.case(id=0)
if case is not None:
results = case.properties.activeCellProperty('STATIC_NATIVE', 'PORO', 0)
activeCellCount = len(results)
# Send the results back to ResInsight inside try / except construct
try:
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0)
print("Everything went well as expected")
except: # Match any exception, but it should not happen
print("Ooops!")
# Add another value, so this is outside the bounds of the active cell result storage
results.append(1.0)
# This time we should get a grpc.RpcError exception, which is a server side error.
try:
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0)
print("Everything went well??")
except grpc.RpcError as e:
print("Expected Server Exception Received: ", e)
except IndexError:
print ("Got index out of bounds error. This shouldn't happen here")
# With a chunk size exactly matching the active cell count the server will not
# be able to see any error as it will successfully close the stream after receiving
# the correct number of values, even if the python client has more chunks to send
case.properties.chunkSize = activeCellCount
try:
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0)
print("Everything went well??")
except grpc.RpcError as e:
print("Got unexpected server exception", e, "This should not happen now")
except IndexError:
print ("Got expected index out of bounds error on client side")

View File

@ -1,5 +1,6 @@
import rips
import time
import grpc
resInsight = rips.Instance.find()
start = time.time()
@ -12,7 +13,11 @@ results = []
for (poro, permx) in zip(poroResults, permxResults):
results.append(poro * permx)
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROPERMXSY', 0)
try:
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROPERMXSY', 0)
except grpc.RpcError as e:
print("Exception Received: ", e)
end = time.time()
print("Time elapsed: ", end - start)

View File

@ -341,8 +341,8 @@ void RiaGrpcClientToServerStreamCallback<ServiceT, RequestT, ReplyT, StateHandle
}
else
{
CAF_ASSERT(m_stateHandler->nrOfValuesReceived() <= m_stateHandler->cellCount());
if (m_stateHandler->nrOfValuesReceived() == m_stateHandler->cellCount())
CAF_ASSERT(m_stateHandler->streamedValueCount() <= m_stateHandler->cellCount());
if (m_stateHandler->streamedValueCount() == m_stateHandler->cellCount())
{
this->setNextCallState(RiaGrpcCallbackInterface::FINISH_REQUEST);
m_reader.Finish(this->m_reply, grpc::Status::OK, this);

View File

@ -56,7 +56,7 @@ public:
RiaCellResultsStateHandler(bool clientStreamer = false)
: m_request(nullptr)
, m_eclipseCase(nullptr)
, m_nrOfValuesReceived(0u)
, m_streamedValueCount(0u)
, m_cellCount(0u)
, m_clientStreamer(clientStreamer)
{
@ -73,9 +73,9 @@ public:
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t nrOfValuesReceived() const
size_t streamedValueCount() const
{
return m_nrOfValuesReceived;
return m_streamedValueCount;
}
//--------------------------------------------------------------------------------------------------
@ -150,9 +150,9 @@ public:
const size_t packageSize = RiaGrpcServiceInterface::numberOfMessagesForByteCount(sizeof(rips::PropertyChunk));
size_t packageIndex = 0u;
reply->mutable_values()->Reserve((int)packageSize);
for (; packageIndex < packageSize && m_nrOfValuesReceived < m_cellCount; ++packageIndex, ++m_nrOfValuesReceived)
for (; packageIndex < packageSize && m_streamedValueCount < m_cellCount; ++packageIndex, ++m_streamedValueCount)
{
reply->add_values(cellResult(m_nrOfValuesReceived));
reply->add_values(cellResult(m_streamedValueCount));
}
if (packageIndex > 0u)
{
@ -167,25 +167,24 @@ public:
//--------------------------------------------------------------------------------------------------
Status receiveStreamRequest(const PropertyInputChunk* request, ClientToServerStreamReply* reply)
{
CAF_ASSERT(!request->has_params());
if (request->has_values())
{
auto values = request->values().values();
if (!values.empty())
{
size_t currentCellIdx = m_nrOfValuesReceived;
m_nrOfValuesReceived += values.size();
size_t currentCellIdx = m_streamedValueCount;
m_streamedValueCount += values.size();
for (int i = 0; i < values.size() && currentCellIdx < m_cellCount; ++i, ++currentCellIdx)
{
setCellResult(currentCellIdx, values[i]);
}
if (m_nrOfValuesReceived > m_cellCount)
if (m_streamedValueCount > m_cellCount)
{
return grpc::Status(grpc::OUT_OF_RANGE, "Attempting to write out of bounds");
}
reply->set_values_accepted(static_cast<int64_t>(currentCellIdx));
reply->set_accepted_value_count(static_cast<int64_t>(currentCellIdx));
return Status::OK;
}
}
@ -224,7 +223,7 @@ protected:
protected:
const rips::PropertyRequest* m_request;
RimEclipseCase* m_eclipseCase;
size_t m_nrOfValuesReceived;
size_t m_streamedValueCount;
size_t m_cellCount;
bool m_clientStreamer;
RigEclipseResultAddress m_resultAddress;