From: Anthony Geay Date: Wed, 22 Jul 2015 10:22:46 +0000 (+0200) Subject: Implementation of the 2 remaining methods. X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=5a2d451561227c919164046465ddc9b610a175cc;p=modules%2Fkernel.git Implementation of the 2 remaining methods. --- diff --git a/idl/SALOME_SDS.idl b/idl/SALOME_SDS.idl index b6685b0ba..23f10a36a 100644 --- a/idl/SALOME_SDS.idl +++ b/idl/SALOME_SDS.idl @@ -93,7 +93,10 @@ module SALOME Transaction createRdExtVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception); Transaction createRdWrVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception); Transaction addKeyValueInVarHard(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception); + Transaction addKeyValueInVarErrorIfAlreadyExisting(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception); + Transaction removeKeyInVarErrorIfNotAlreadyExisting(in string varName, in ByteVec keyValue) raises (SALOME::SALOME_Exception); KeyWaiter waitForKeyInVar(in string varName, in ByteVec keyVal) raises (SALOME::SALOME_Exception); + KeyWaiter waitForKeyInVarAndKillIt(in string varName, in ByteVec keyVal, out Transaction transac) raises (SALOME::SALOME_Exception); void atomicApply(in ListOfTransaction transactions) raises (SALOME::SALOME_Exception); }; diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx index 61dbf5156..7616e40c9 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx @@ -494,11 +494,40 @@ SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const c return SALOME::Transaction::_narrow(obj); } +SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value) +{ + checkVarExistingAndDict(varName); + TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value)); + CORBA::Object_var obj(ret->activate()); + return SALOME::Transaction::_narrow(obj); +} + +SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key) +{ + checkVarExistingAndDict(varName); + TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key)); + CORBA::Object_var obj(ret->activate()); + return SALOME::Transaction::_narrow(obj); +} + SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal) { PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName)); KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal)); - CORBA::Object_var obj(ret->activate()); + CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread ! + return SALOME::KeyWaiter::_narrow(obj); +} + +SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac) +{ + PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName)); + KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal)); + CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread ! + // + TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal)); + CORBA::Object_var obj2(ret1->activate()); + transac=SALOME::Transaction::_narrow(obj2); + // return SALOME::KeyWaiter::_narrow(obj); } diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx index b7bd2a278..b77e47dc6 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx @@ -117,7 +117,10 @@ namespace SALOMESDS SALOME::Transaction_ptr createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue); SALOME::Transaction_ptr createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue); SALOME::Transaction_ptr addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value); + SALOME::Transaction_ptr addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value); + SALOME::Transaction_ptr removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key); SALOME::KeyWaiter_ptr waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal); + SALOME::KeyWaiter_ptr waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac); void atomicApply(const SALOME::ListOfTransaction& transactions); private: PyObject *getPyCmpFunc(); @@ -125,12 +128,6 @@ namespace SALOMESDS PortableServer::POA_var _poa_for_key_waiter; std::list< KeyWaiter * > _waiting_keys; }; - - /* - SALOME::Transaction_ptr addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const char *scopeName, const SALOME::ByteVec& key, const SALOME::ByteVec& value); - SALOME::Transaction_ptr removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const char *scopeName, const SALOME::ByteVec& key); - SALOME::ByteVec *waitForKeyInVar(const char *varName, const char *scopeName, const SALOME::ByteVec& constKey); - SALOME::ByteVec *waitForKeyInVarAndKillIt(const char *varName, const char *scopeName, const SALOME::ByteVec& constKey, SALOME::Transaction_out transaction);*/ } #endif diff --git a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx index 3a2ec7561..84975a48f 100644 --- a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx +++ b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx @@ -46,7 +46,7 @@ KeyWaiter::KeyWaiter(PickelizedPyObjServer *var, const SALOME::ByteVec& keyVal): std::string st; PickelizedPyObjServer::FromByteSeqToCpp(keyVal,st); _ze_key=PickelizedPyObjServer::GetPyObjFromPickled(st,getDSS()); - PyObject *selfMeth(PyObject_GetAttrString(_var->getPyObj(),"__contains__")); + PyObject *selfMeth(PyObject_GetAttrString(_var->getPyObj(),"__contains__"));//new ref PyObject *args(PyTuple_New(1)); PyTuple_SetItem(args,0,_ze_key); Py_XINCREF(_ze_key); // _ze_key is stolen by PyTuple_SetItem PyObject *retPy(PyObject_CallObject(selfMeth,args)); diff --git a/src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.cxx b/src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.cxx index f773a32fc..2989150d4 100644 --- a/src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.cxx +++ b/src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.cxx @@ -60,15 +60,38 @@ bool PickelizedPyObjServer::isDict() return false; } +void PickelizedPyObjServer::checkKeyNotAlreadyPresent(PyObject *key) +{ + checkKeyPresence(key,false); +} + +void PickelizedPyObjServer::checkKeyPresent(PyObject *key) +{ + checkKeyPresence(key,true); +} + void PickelizedPyObjServer::addKeyValueHard(PyObject *key, PyObject *value) { - if(!isDict()) - throw Exception("PickelizedPyObjServer::addKeyValueHard : not a dict !"); bool isOK(PyDict_SetItem(_self,key,value)==0); if(!isOK) throw Exception("PickelizedPyObjServer::addKeyValueHard : error when trying to add key,value to dict !"); } +void PickelizedPyObjServer::addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value) +{ + checkKeyNotAlreadyPresent(key); + bool isOK(PyDict_SetItem(_self,key,value)==0); + if(!isOK) + throw Exception("PickelizedPyObjServer::addKeyValueErrorIfAlreadyExisting : error when trying to add key,value to dict !"); +} + +void PickelizedPyObjServer::removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key) +{ + checkKeyPresent(key); + if(PyDict_DelItem(_self,key)!=0) + throw Exception("PickelizedPyObjServer::removeKeyInVarErrorIfNotAlreadyExisting : error during deletion of key in dict !"); +} + void PickelizedPyObjServer::FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret) { std::size_t sz(bsToBeConv.length()); @@ -210,3 +233,29 @@ PyObject *PickelizedPyObjServer::CreateDftObjFromType(PyObject *globals, const s Py_XDECREF(args); return ret; } + +void PickelizedPyObjServer::checkKeyPresence(PyObject *key, bool presence) +{ + if(!isDict()) + throw Exception("PickelizedPyObjServer::checkKeyPresence : not a dict !"); + PyObject *selfMeth(PyObject_GetAttrString(_self,"__contains__"));//new ref + PyObject *args(PyTuple_New(1)); + PyTuple_SetItem(args,0,key); Py_XINCREF(key);// key is stolen by PyTuple_SetItem + PyObject *retPy(PyObject_CallObject(selfMeth,args)); + Py_XDECREF(args); + Py_XDECREF(selfMeth); + // + if(retPy!=Py_False && retPy!=Py_True) + throw Exception("PickelizedPyObjServer::checkKeyPresence : unexpected return of dict.__contains__ !"); + if(!presence) + { + if(retPy==Py_True) + throw Exception("PickelizedPyObjServer::checkKeyPresence : key is already present and it should not !"); + } + else + { + if(retPy==Py_False) + throw Exception("PickelizedPyObjServer::checkKeyPresence : key is not present and it should !"); + } + Py_XDECREF(retPy); +} diff --git a/src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.hxx b/src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.hxx index 3e77f546c..a52e27eea 100644 --- a/src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.hxx +++ b/src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.hxx @@ -42,7 +42,11 @@ namespace SALOMESDS SALOME::ByteVec *fetchSerializedContent(); public: bool isDict(); + void checkKeyNotAlreadyPresent(PyObject *key); + void checkKeyPresent(PyObject *key); void addKeyValueHard(PyObject *key, PyObject *value); + void addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value); + void removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key); PyObject *getPyObj() const { return _self; } public: static void FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret); @@ -56,6 +60,8 @@ namespace SALOMESDS void setNewPyObj(PyObject *obj); void setSerializedContentInternal(const SALOME::ByteVec& newValue); static PyObject *CreateDftObjFromType(PyObject *globals, const std::string& typeName); + private: + void checkKeyPresence(PyObject *key, bool presence); protected: static const char FAKE_VAR_NAME_FOR_WORK[]; PyObject *_self; diff --git a/src/SALOMESDS/SALOMESDS_Transaction.cxx b/src/SALOMESDS/SALOMESDS_Transaction.cxx index 0bceafbbb..9f3163b44 100644 --- a/src/SALOMESDS/SALOMESDS_Transaction.cxx +++ b/src/SALOMESDS/SALOMESDS_Transaction.cxx @@ -91,7 +91,26 @@ void TransactionRdWrVarCreate::perform() _dsct->createRdWrVarInternal(_var_name,data2); } -TransactionAddKeyValueHard::TransactionAddKeyValueHard(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):Transaction(dsct,varName),_varc(0) +TransactionDictModify::TransactionDictModify(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName),_varc(0) +{ + _varc=checkVarExistingAndDict(); +} + +void TransactionDictModify::prepareRollBackInCaseOfFailure() +{ + _zeDataBefore.clear(); + SALOME::ByteVec *zeDataBefore(_varc->fetchSerializedContent()); + PickelizedPyObjServer::FromByteSeqToCpp(*zeDataBefore,_zeDataBefore); +} + +void TransactionDictModify::rollBack() +{ + PyObject *obj(_varc->getPyObjFromPickled(_zeDataBefore)); + _varc->setNewPyObj(obj); + _zeDataBefore.clear(); +} + +TransactionAddKeyValue::TransactionAddKeyValue(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionDictModify(dsct,varName) { std::vector key2,value2; FromByteSeqToVB(key,key2); @@ -100,35 +119,62 @@ TransactionAddKeyValueHard::TransactionAddKeyValueHard(DataScopeServerTransactio _value=PickelizedPyObjServer::GetPyObjFromPickled(value2,_dsct); } -void TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure() +void TransactionAddKeyValue::prepareRollBackInCaseOfFailure() { - _varc=checkVarExistingAndDict(); - // - _zeDataBefore.clear(); - SALOME::ByteVec *zeDataBefore(_varc->fetchSerializedContent()); - PickelizedPyObjServer::FromByteSeqToCpp(*zeDataBefore,_zeDataBefore); + TransactionDictModify::prepareRollBackInCaseOfFailure(); _dsct->pingKey(_key);// check that key is OK with all waiting keys } +void TransactionAddKeyValue::notify() +{ + _dsct->notifyKey(_key,_value); +} + +TransactionAddKeyValue::~TransactionAddKeyValue() +{ + Py_XDECREF(_key); + Py_XDECREF(_value); +} + +TransactionAddKeyValueHard::TransactionAddKeyValueHard(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionAddKeyValue(dsct,varName,key,value) +{ +} + void TransactionAddKeyValueHard::perform() { _varc->addKeyValueHard(_key,_value); } -void TransactionAddKeyValueHard::rollBack() +TransactionAddKeyValueErrorIfAlreadyExisting::TransactionAddKeyValueErrorIfAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionAddKeyValue(dsct,varName,key,value) { - PyObject *obj(_varc->getPyObjFromPickled(_zeDataBefore)); - _varc->setNewPyObj(obj); - _zeDataBefore.clear(); + _varc->checkKeyNotAlreadyPresent(_key); } -void TransactionAddKeyValueHard::notify() +void TransactionAddKeyValueErrorIfAlreadyExisting::perform() { - _dsct->notifyKey(_key,_value); + _varc->addKeyValueErrorIfAlreadyExisting(_key,_value); } -TransactionAddKeyValueHard::~TransactionAddKeyValueHard() +TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key):TransactionDictModify(dsct,varName),_key(0) +{ + std::vector key2; + FromByteSeqToVB(key,key2); + _key=PickelizedPyObjServer::GetPyObjFromPickled(key2,_dsct); +} + +void TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::perform() +{ + _varc->removeKeyInVarErrorIfNotAlreadyExisting(_key); +} + +/*! + * not implementation it is not a bug ! + */ +void TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::notify() +{ +} + +TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::~TransactionRemoveKeyInVarErrorIfNotAlreadyExisting() { Py_XDECREF(_key); - Py_XDECREF(_value); } diff --git a/src/SALOMESDS/SALOMESDS_Transaction.hxx b/src/SALOMESDS/SALOMESDS_Transaction.hxx index 5024331c2..2bed22478 100644 --- a/src/SALOMESDS/SALOMESDS_Transaction.hxx +++ b/src/SALOMESDS/SALOMESDS_Transaction.hxx @@ -40,9 +40,8 @@ namespace SALOMESDS public: Transaction(DataScopeServerTransaction *dsct, const std::string& varName):_dsct(dsct),_var_name(varName) { if(!_dsct) throw Exception("Transaction constructor error !"); } std::string getVarName() const { return _var_name; } - void checkNotAlreadyExisting() { _dsct->checkNotAlreadyExistingVar(_var_name); } void checkVarExisting() { _dsct->checkExistingVar(_var_name); } - PickelizedPyObjServer *checkVarExistingAndDict() { return _dsct->checkVarExistingAndDict(_var_name); } + void checkNotAlreadyExisting() { _dsct->checkNotAlreadyExistingVar(_var_name); } PortableServer::POA_var getPOA() const { return _dsct->getPOA(); } virtual void prepareRollBackInCaseOfFailure() = 0; virtual void perform() = 0; @@ -91,20 +90,53 @@ namespace SALOMESDS class PickelizedPyObjServer; - class TransactionAddKeyValueHard : public Transaction + class TransactionDictModify : public Transaction { public: - TransactionAddKeyValueHard(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value); + TransactionDictModify(DataScopeServerTransaction *dsct, const std::string& varName); + PickelizedPyObjServer *checkVarExistingAndDict() { return _dsct->checkVarExistingAndDict(_var_name); } void prepareRollBackInCaseOfFailure(); - void perform(); void rollBack(); + protected: + std::string _zeDataBefore; + PickelizedPyObjServer *_varc; + }; + + class TransactionAddKeyValue : public TransactionDictModify + { + public: + TransactionAddKeyValue(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value); + void prepareRollBackInCaseOfFailure(); void notify(); - ~TransactionAddKeyValueHard(); - private: + ~TransactionAddKeyValue(); + protected: PyObject *_key; PyObject *_value; - std::string _zeDataBefore; - PickelizedPyObjServer *_varc; + }; + + class TransactionAddKeyValueHard : public TransactionAddKeyValue + { + public: + TransactionAddKeyValueHard(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value); + void perform(); + }; + + class TransactionAddKeyValueErrorIfAlreadyExisting : public TransactionAddKeyValue + { + public: + TransactionAddKeyValueErrorIfAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value); + void perform(); + }; + + class TransactionRemoveKeyInVarErrorIfNotAlreadyExisting : public TransactionDictModify + { + public: + TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key); + void perform(); + void notify(); + ~TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(); + private: + PyObject *_key; }; } diff --git a/src/SALOMESDS/TestSalomeSDS.py b/src/SALOMESDS/TestSalomeSDS.py index 8bae455a3..788664e29 100644 --- a/src/SALOMESDS/TestSalomeSDS.py +++ b/src/SALOMESDS/TestSalomeSDS.py @@ -129,6 +129,27 @@ class SalomeSDSTest(unittest.TestCase): self.assertEqual(asyncResult.get(),nbProc*[0]) # <- the big test is here ! dsm.removeDataScope(scopeName) + def testTransaction2(self): + scopeName="Scope1" + varName="a" + dsm=salome.naming_service.Resolve("/DataServerManager") + dsm.cleanScopesInNS() + if scopeName in dsm.listScopes(): + dsm.removeDataScope(scopeName) + dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName) + self.assertTrue(isCreated) + # + t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]})) + dss.atomicApply([t0]) + # + self.assertRaises(SALOME.SALOME_Exception,dss.addKeyValueInVarErrorIfAlreadyExisting,varName,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key ! + t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10])) + dss.atomicApply([t1]) + # + self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]}) + wk=dss.waitForKeyInVar(varName,obj2Str("cd")) + self.assertEqual(str2Obj(wk.waitFor()),[7,8,9,10]) + def setUp(self): salome.salome_init() pass