mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4576 Python: Improve error handling and add example
This commit is contained in:
parent
84495641f9
commit
197279ccbf
@ -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"
|
||||
|
@ -8,5 +8,5 @@ message Empty
|
||||
|
||||
message ClientToServerStreamReply
|
||||
{
|
||||
int64 values_accepted = 1;
|
||||
int64 accepted_value_count = 1;
|
||||
}
|
@ -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)
|
||||
return self.commands.Execute(Cmd.CommandParams(**commandParams))
|
||||
|
||||
########################
|
||||
# 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;
|
||||
|
||||
##################
|
||||
|
@ -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)
|
||||
|
||||
request_iterator = self.__generatePropertyInputIterator(values_iterator, request)
|
||||
self.propertiesStub.SetActiveCellProperty(request_iterator)
|
||||
|
||||
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)
|
||||
request_iterator = self.__generatePropertyInputChunks(values, request)
|
||||
reply = self.propertiesStub.SetActiveCellProperty(request_iterator)
|
||||
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");
|
||||
request_iterator = self.__generatePropertyInputChunks(values, request)
|
||||
reply = self.propertiesStub.SetGridProperty(request_iterator)
|
||||
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)
|
||||
|
@ -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")
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user