From: Anthony Geay Date: Tue, 11 Aug 2015 10:05:51 +0000 (+0200) Subject: Multi push key,value session in a transaction. X-Git-Tag: V7_7_0a1~7 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=06f08f87620928b3c6cbc68e9f078ca6f23f0b79;p=modules%2Fkernel.git Multi push key,value session in a transaction. --- diff --git a/idl/SALOME_SDS.idl b/idl/SALOME_SDS.idl index ed8b9a39d..e0ccd185b 100644 --- a/idl/SALOME_SDS.idl +++ b/idl/SALOME_SDS.idl @@ -46,11 +46,19 @@ module SALOME { }; - interface PickelizedPyObjRdExtServer : PickelizedPyObjServer + interface PickelizedPyObjRdExtBaseServer : PickelizedPyObjServer + { + }; + + interface PickelizedPyObjRdExtServer : PickelizedPyObjRdExtBaseServer { PickelizedPyObjRdExtServer invokePythonMethodOn(in string method, in ByteVec args) raises (SALOME::SALOME_Exception); }; + interface PickelizedPyObjRdExtInitServer : PickelizedPyObjRdExtBaseServer + { + }; + interface PickelizedPyObjRdWrServer : PickelizedPyObjServer { void setSerializedContent(in ByteVec newValue) raises (SALOME::SALOME_Exception); @@ -92,6 +100,11 @@ module SALOME PickelizedPyObjRdWrServer getVar() raises (SALOME::SALOME_Exception); }; + interface TransactionMultiKeyAddSession : Transaction + { + void addKeyValueInVarErrorIfAlreadyExistingNow(in SALOME::ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception); + }; + typedef sequence ListOfTransaction; interface KeyWaiter @@ -107,7 +120,7 @@ module SALOME 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); - void addKeyValueInVarErrorIfAlreadyExistingNow(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception); + TransactionMultiKeyAddSession addMultiKeyValueSession(in string varName) raises (SALOME::SALOME_Exception); Transaction removeKeyInVarErrorIfNotAlreadyExisting(in string varName, in ByteVec keyValue) raises (SALOME::SALOME_Exception); TransactionRdWrAccess createWorkingVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception); KeyWaiter waitForKeyInVar(in string varName, in ByteVec keyVal) raises (SALOME::SALOME_Exception); diff --git a/src/SALOMESDS/CMakeLists.txt b/src/SALOMESDS/CMakeLists.txt index 79ca214dc..3ccdb393d 100644 --- a/src/SALOMESDS/CMakeLists.txt +++ b/src/SALOMESDS/CMakeLists.txt @@ -43,6 +43,7 @@ SET(SalomeSDS_SOURCES SALOMESDS_PickelizedPyObjServer.cxx SALOMESDS_PickelizedPyObjRdOnlyServer.cxx SALOMESDS_PickelizedPyObjRdExtServer.cxx + SALOMESDS_PickelizedPyObjRdExtInitServer.cxx SALOMESDS_PickelizedPyObjRdWrServer.cxx SALOMESDS_Transaction.cxx SALOMESDS_KeyWaiter.cxx diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx index 2b56d86d6..528e25664 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx @@ -23,6 +23,8 @@ #include "SALOMESDS_PickelizedPyObjRdOnlyServer.hxx" #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx" #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx" +#include "SALOMESDS_PickelizedPyObjRdExtInitServer.hxx" +#include "SALOMESDS_TrustTransaction.hxx" #include "SALOMESDS_KeyWaiter.hxx" #include "SALOMESDS_Transaction.hxx" #include "SALOME_NamingService.hxx" @@ -245,10 +247,10 @@ void DataScopeServerBase::initializePython(int argc, char *argv[]) void DataScopeServerBase::registerToSalomePiDict() const { - PyObject *mod(PyImport_ImportModule("addToKillList")); + PyObject *mod(PyImport_ImportModule("addToKillList"));//new value if(!mod) return; - PyObject *meth(PyObject_GetAttrString(mod,"addToKillList")); + PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value if(!meth) { Py_XDECREF(mod); return ; } PyObject *args(PyTuple_New(2)); @@ -257,6 +259,7 @@ void DataScopeServerBase::registerToSalomePiDict() const PyObject *res(PyObject_CallObject(meth,args)); Py_XDECREF(args); Py_XDECREF(res); + Py_XDECREF(meth); Py_XDECREF(mod); } @@ -359,6 +362,36 @@ void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& var varc->decrRef(); } +void DataScopeServerBase::moveStatusOfVarFromRdExtToRdExtInit(const std::string& varName) +{ + std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName)); + std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it); + PickelizedPyObjRdExtServer *varc(dynamic_cast(p.second)); + if(!varc) + throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtToRdExtInit : var is not a RdExt !"); + PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj); + PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj)); + CORBA::Object_var obj(newVar->activate()); + SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj)); + p.first=obj2; p.second=newVar; + varc->decrRef(); +} + +void DataScopeServerBase::moveStatusOfVarFromRdExtInitToRdExt(const std::string& varName) +{ + std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName)); + std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it); + PickelizedPyObjRdExtInitServer *varc(dynamic_cast(p.second)); + if(!varc) + throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtInitToRdExt : var is not a RdExtInit !"); + PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj); + PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj)); + CORBA::Object_var obj(newVar->activate()); + SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj)); + p.first=obj2; p.second=newVar; + varc->decrRef(); +} + std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const { std::vector allNames(getAllVarNames()); @@ -620,29 +653,12 @@ SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlrea return SALOME::Transaction::_narrow(obj); }; -class TrustTransaction -{ -public: - TrustTransaction():_must_rollback(0),_ptr(0) { } - void setTransaction(Transaction *t, bool *mustRollback) { if(!t || !mustRollback) throw Exception("TrustTransaction Error #1"); _ptr=t; _must_rollback=mustRollback; _ptr->prepareRollBackInCaseOfFailure(); } - void operate() { _ptr->perform(); } - ~TrustTransaction() { if(!_ptr) return ; if(*_must_rollback) _ptr->rollBack(); } -private: - bool *_must_rollback; - Transaction *_ptr; -}; - -void DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExistingNow(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value) +SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName) { checkVarExistingAndDict(varName); - TransactionAddKeyValueErrorIfAlreadyExisting ret(this,varName,key,value); - { - bool mustRollback(true); - TrustTransaction t; - t.setTransaction(&ret,&mustRollback); - t.operate(); - mustRollback=false; - } + TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName)); + CORBA::Object_var obj(ret->activate()); + return SALOME::TransactionMultiKeyAddSession::_narrow(obj); } SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key) diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx index 9a98b8a90..cab0c12bd 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx @@ -85,6 +85,8 @@ namespace SALOMESDS public: void moveStatusOfVarFromRdWrToRdOnly(const std::string& varName); void moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName); + void moveStatusOfVarFromRdExtToRdExtInit(const std::string& varName); + void moveStatusOfVarFromRdExtInitToRdExt(const std::string& varName); protected: std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator retrieveVarInternal3(const std::string& varName) const; std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator retrieveVarInternal4(const std::string& varName); @@ -133,7 +135,7 @@ namespace SALOMESDS 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); - void addKeyValueInVarErrorIfAlreadyExistingNow(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value); + SALOME::TransactionMultiKeyAddSession_ptr addMultiKeyValueSession(const char *varName); SALOME::Transaction_ptr removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key); SALOME::TransactionRdWrAccess_ptr createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue); SALOME::KeyWaiter_ptr waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal); diff --git a/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx new file mode 100644 index 000000000..608af2dfb --- /dev/null +++ b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony GEAY (EDF R&D) + +#include "SALOMESDS_PickelizedPyObjRdExtInitServer.hxx" +#include "SALOMESDS_DataScopeServer.hxx" +#include "SALOMESDS_Exception.hxx" + +#include +#include + +using namespace SALOMESDS; + +const char PickelizedPyObjRdExtInitServer::ACCESS_REPR[]="RdExtInit"; + +//! obj is consumed +PickelizedPyObjRdExtInitServer::PickelizedPyObjRdExtInitServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServerModifiable(father,varName,obj),_self_deep_copy(0) +{ + _self_deep_copy=DeepCopyPyObj(obj); +} + +PickelizedPyObjRdExtInitServer::~PickelizedPyObjRdExtInitServer() +{ + Py_XDECREF(_self_deep_copy); +} + +std::string PickelizedPyObjRdExtInitServer::getAccessStr() const +{ + return std::string(ACCESS_REPR); +} + +SALOME::ByteVec *PickelizedPyObjRdExtInitServer::fetchSerializedContent() +{ + Py_XINCREF(_self_deep_copy);//because pickelize consume _self_deep_copy + return FromCppToByteSeq(pickelize(_self_deep_copy)); +} + +PyObject *PickelizedPyObjRdExtInitServer::DeepCopyPyObj(PyObject *pyobj) +{ + PyObject *mod(PyImport_ImportModule("copy"));//new value + PyObject *meth(PyObject_GetAttrString(mod,"deepcopy"));//new value + PyObject *args(PyTuple_New(1)); + Py_XINCREF(pyobj); PyTuple_SetItem(args,0,pyobj); + PyObject *ret(PyObject_CallObject(meth,args)); + Py_XDECREF(args); + Py_XDECREF(meth); + Py_XDECREF(mod); + return ret; +} diff --git a/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx new file mode 100644 index 000000000..d5b7c781c --- /dev/null +++ b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony GEAY (EDF R&D) + +#ifndef __SALOMESDS_PICKELIZEDPYOBJRDEXTINITSERVER_HXX__ +#define __SALOMESDS_PICKELIZEDPYOBJRDEXTINITSERVER_HXX__ + +#include "SALOMEconfig.h" +#include CORBA_SERVER_HEADER(SALOME_SDS) + +#include + +#include "SALOMESDS_PickelizedPyObjServer.hxx" + +namespace SALOMESDS +{ + class PickelizedPyObjRdExtInitServer : public PickelizedPyObjServerModifiable, public virtual POA_SALOME::PickelizedPyObjRdExtInitServer + { + public: + PickelizedPyObjRdExtInitServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj); + ~PickelizedPyObjRdExtInitServer(); + public: + std::string getAccessStr() const; + SALOME::ByteVec *fetchSerializedContent(); + private: + static PyObject *DeepCopyPyObj(PyObject *pyobj); + private: + PyObject *_self_deep_copy; + public: + static const char ACCESS_REPR[]; + }; +} + +#endif diff --git a/src/SALOMESDS/SALOMESDS_Transaction.cxx b/src/SALOMESDS/SALOMESDS_Transaction.cxx index 964303cfe..a903cca49 100644 --- a/src/SALOMESDS/SALOMESDS_Transaction.cxx +++ b/src/SALOMESDS/SALOMESDS_Transaction.cxx @@ -23,6 +23,7 @@ #include "SALOMESDS_PickelizedPyObjServer.hxx" #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx" #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx" +#include "SALOMESDS_TrustTransaction.hxx" #include @@ -224,3 +225,49 @@ void TransactionMorphRdWrIntoRdOnly::rollBack() void TransactionMorphRdWrIntoRdOnly::notify() { } + +TransactionMultiKeyAddSession::TransactionMultiKeyAddSession(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName) +{ + _dsct->moveStatusOfVarFromRdExtToRdExtInit(_var_name); +} + +void TransactionMultiKeyAddSession::addKeyValueInVarErrorIfAlreadyExistingNow(const SALOME::ByteVec& key, const SALOME::ByteVec& value) +{ + _dsct->checkVarExistingAndDict(_var_name); + TransactionAddKeyValueErrorIfAlreadyExisting ret(_dsct,_var_name,key,value); + { + bool mustRollback(true); + TrustTransaction t; + t.setTransaction(&ret,&mustRollback); + t.operate(); + mustRollback=false;//important let this line to notify t that everything was OK + } + ret.notify(); +} + +/*! + * no implementation it is not a bug ! + */ +void TransactionMultiKeyAddSession::prepareRollBackInCaseOfFailure() +{ +} + +void TransactionMultiKeyAddSession::perform() +{ + _dsct->moveStatusOfVarFromRdExtInitToRdExt(_var_name); +} + +/*! + * no implementation it is not a bug ! + */ +void TransactionMultiKeyAddSession::rollBack() +{ +} + +/*! + * no implementation it is not a bug ! + */ +void TransactionMultiKeyAddSession::notify() +{ +} + diff --git a/src/SALOMESDS/SALOMESDS_Transaction.hxx b/src/SALOMESDS/SALOMESDS_Transaction.hxx index 4fad07b05..8d3db4479 100644 --- a/src/SALOMESDS/SALOMESDS_Transaction.hxx +++ b/src/SALOMESDS/SALOMESDS_Transaction.hxx @@ -153,6 +153,19 @@ namespace SALOMESDS void rollBack(); void notify(); }; + + class TransactionMultiKeyAddSession : public Transaction, public virtual POA_SALOME::TransactionMultiKeyAddSession + { + public: + TransactionMultiKeyAddSession(DataScopeServerTransaction *dsct, const std::string& varName); + public://remotely callable + void addKeyValueInVarErrorIfAlreadyExistingNow(const SALOME::ByteVec& key, const SALOME::ByteVec& value); + public: + void prepareRollBackInCaseOfFailure(); + void perform(); + void rollBack(); + void notify(); + }; } #endif diff --git a/src/SALOMESDS/SALOMESDS_TrustTransaction.hxx b/src/SALOMESDS/SALOMESDS_TrustTransaction.hxx new file mode 100644 index 000000000..52a91ee63 --- /dev/null +++ b/src/SALOMESDS/SALOMESDS_TrustTransaction.hxx @@ -0,0 +1,42 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony GEAY (EDF R&D) + +#ifndef __SALOMESDS_TRUSTTRANSACTION_HXX__ +#define __SALOMESDS_TRUSTTRANSACTION_HXX__ + +#include "SALOMESDS_Transaction.hxx" +#include "SALOMESDS_Exception.hxx" + +namespace SALOMESDS +{ + class TrustTransaction + { + public: + TrustTransaction():_must_rollback(0),_ptr(0) { } + void setTransaction(Transaction *t, bool *mustRollback) { if(!t || !mustRollback) throw Exception("TrustTransaction Error #1"); _ptr=t; _must_rollback=mustRollback; _ptr->prepareRollBackInCaseOfFailure(); } + void operate() { _ptr->perform(); } + ~TrustTransaction() { if(!_ptr) return ; if(*_must_rollback) _ptr->rollBack(); } + private: + bool *_must_rollback; + Transaction *_ptr; + }; +} + +#endif diff --git a/src/SALOMESDS/TestSalomeSDS.py b/src/SALOMESDS/TestSalomeSDS.py index c916d19c2..80557dc58 100644 --- a/src/SALOMESDS/TestSalomeSDS.py +++ b/src/SALOMESDS/TestSalomeSDS.py @@ -213,8 +213,17 @@ class SalomeSDSTest(unittest.TestCase): t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]})) dss.atomicApply([t0]) # - self.assertRaises(SALOME.SALOME_Exception,dss.addKeyValueInVarErrorIfAlreadyExistingNow,varName,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key ! - dss.addKeyValueInVarErrorIfAlreadyExistingNow(varName,obj2Str("cd"),obj2Str([7,8,9,10])) + self.assertEqual(dss.getAccessOfVar(varName),"RdExt") + t1=dss.addMultiKeyValueSession(varName) + self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit") + self.assertRaises(SALOME.SALOME_Exception,t1.addKeyValueInVarErrorIfAlreadyExistingNow,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key ! + self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]}) + wk=dss.waitForKeyInVar(varName,obj2Str("cd")) + t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10])) + self.assertEqual(str2Obj(wk.waitFor()),[7,8,9,10]) + self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})# it is not a bug ! commit of t1 not done ! + dss.atomicApply([t1]) + self.assertEqual(dss.getAccessOfVar(varName),"RdExt") # self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]}) wk=dss.waitForKeyInVar(varName,obj2Str("cd"))