Hi Hieu,

Please see my comment marked with [Quyen].

Thanks,
Quyen

On 10/5/2017 5:26 PM, Hieu Nguyen wrote:
---
  python/pyosaf/utils/__init__.py       | 38 +++++++++++++++++++++++++++++++++++
  python/pyosaf/utils/clm/__init__.py   | 18 ++++++++---------
  python/pyosaf/utils/immoi/__init__.py | 12 +++++------
  python/pyosaf/utils/immom/__init__.py | 11 +++++-----
  python/pyosaf/utils/log/__init__.py   |  4 ++--
  python/pyosaf/utils/ntf/__init__.py   | 17 ++++++++--------
  6 files changed, 69 insertions(+), 31 deletions(-)

diff --git a/python/pyosaf/utils/__init__.py b/python/pyosaf/utils/__init__.py
index 0d4b648..17a1408 100644
--- a/python/pyosaf/utils/__init__.py
+++ b/python/pyosaf/utils/__init__.py
@@ -16,6 +16,7 @@
  ############################################################################
import time
+from copy import deepcopy
from pyosaf.saAis import eSaAisErrorT @@ -70,3 +71,40 @@ def decorate(function):
          return error
return inner
+
+
+def initialize_decorate(function, current_version):
[Quyen] I think argument current_version should be removed, it should use the version that user passes to `function`
+    ''' Decorate the given SAF initialize() with current version so that it
+        retries a fixed number of times if needed and raises an exception
+        if it encounters any fault other than SA_AIS_ERR_TRY_AGAIN.
+    '''
+    # Backup current version
+    backup_version = deepcopy(current_version)
[Quyen] Backing up the version should be done inside the inner function.
+
+    def inner(*args):
+        ''' Calls "function" in the lexical scope in a retry loop and raises
+            an exception if it encounters any other faults.
+        '''
+        one_sec_sleeps = 0
[Quyen] the backup_version should be done at here, please also have a note in the function docstring to emphasize that the give SAF initialize must have 3 arguments and the last argument is the version.
backup_version = deepcopy(args[2])
+        error = function(*args)
+
+        while error == eSaAisErrorT.SA_AIS_ERR_TRY_AGAIN:
+            if one_sec_sleeps == TRY_AGAIN_COUNT:
+                break
+
+            time.sleep(1)
+            one_sec_sleeps += 1
+
+            # If SAF initialize() returns ERR_TRY_AGAIN, the version will be
+            # updated to the latest version
+            # Set current version in this case
[Quyen] Should we rephrase it like this: "So we need to revert the version back to the original version before trying again" or something similar.
+            current_version = deepcopy(backup_version)
+            args = args[:2] + (current_version,)
+            error = function(*args)
+
+        if error != eSaAisErrorT.SA_AIS_OK:
+            raise_saf_exception(function, error)
+
+        return error
+
+    return inner
diff --git a/python/pyosaf/utils/clm/__init__.py 
b/python/pyosaf/utils/clm/__init__.py
index 9b9e11f..926e2f4 100644
--- a/python/pyosaf/utils/clm/__init__.py
+++ b/python/pyosaf/utils/clm/__init__.py
@@ -20,12 +20,15 @@
from pyosaf import saClm, saAis -from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
+
+# Define CLM version
+CLM_VER = saAis.SaVersionT('B', 4, 1)
[Quyen] No need to have a constant here as it's only used in one place
# Decorate the raw saClm* functions with retry and raising exceptions
-saClmInitialize                = decorate(saClm.saClmInitialize)
-saClmInitialize_3              = decorate(saClm.saClmInitialize_3)
-saClmInitialize_4              = decorate(saClm.saClmInitialize_4)
+saClmInitialize = initialize_decorate(saClm.saClmInitialize, CLM_VER)
+saClmInitialize_3 = initialize_decorate(saClm.saClmInitialize_3, CLM_VER)
+saClmInitialize_4 = initialize_decorate(saClm.saClmInitialize_4, CLM_VER)

  saClmSelectionObjectGet        = decorate(saClm.saClmSelectionObjectGet)
  saClmDispatch                  = decorate(saClm.saClmDispatch)
  saClmFinalize                  = decorate(saClm.saClmFinalize)
@@ -119,11 +122,8 @@ def initialize(track_fn=None):
      callbacks.saClmClusterNodeGetCallback = 
saClm.SaClmClusterNodeGetCallbackT_4(node_get_callback)
      callbacks.saClmClusterTrackCallback = 
saClm.SaClmClusterTrackCallbackT_4(track_callback)
- # Define which version to use of the CLM API
-    version = saAis.SaVersionT('B', 4, 1)
-
      # Initialize the CLM API
-    saClmInitialize_4(HANDLE, callbacks, version)
+    saClmInitialize_4(HANDLE, callbacks, CLM_VER)
[Quyen] Should keep the original code, no need to replace with constant CLM_VER
def track(flags=saAis.saAis.SA_TRACK_CHANGES_ONLY):
      saClmClusterTrack_4(HANDLE, flags, None)
@@ -131,7 +131,7 @@ def track(flags=saAis.saAis.SA_TRACK_CHANGES_ONLY):
  def get_members():
      notification_buffer = saClm.SaClmClusterNotificationBufferT_4()
- saClmClusterTrack_4(HANDLE, saAis.saAis.SA_TRACK_CURRENT,
+    saClmClusterTrack_4(HANDLE, saAis.saAis.SA_TRACK_CURRENT,
                          notification_buffer)
cluster_nodes = []
diff --git a/python/pyosaf/utils/immoi/__init__.py 
b/python/pyosaf/utils/immoi/__init__.py
index 02ad89b..ecfeb7e 100644
--- a/python/pyosaf/utils/immoi/__init__.py
+++ b/python/pyosaf/utils/immoi/__init__.py
@@ -38,7 +38,7 @@ from pyosaf.utils.immom.object import ImmObject
  from pyosaf.utils.immom.ccb import marshal_c_array
  from pyosaf.utils.immom.iterator import SearchIterator
-from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
from ctypes import c_char_p, c_void_p, cast, pointer @@ -49,8 +49,11 @@ TRYAGAIN_CNT = 60 OPENSAF_IMM_OBJECT = "opensafImm=opensafImm,safApp=safImmService" +# Define IMM OI version
+OI_VER = SaVersionT('A', 2, 15)
+
  # Decorate the raw saImmOi* functions with retry and raising exceptions
-saImmOiInitialize_2       = decorate(saImmOi.saImmOiInitialize_2)
+saImmOiInitialize_2 = initialize_decorate(saImmOi.saImmOiInitialize_2, OI_VER)
  saImmOiSelectionObjectGet = decorate(saImmOi.saImmOiSelectionObjectGet)
  saImmOiDispatch           = decorate(saImmOi.saImmOiDispatch)
  saImmOiFinalize           = decorate(saImmOi.saImmOiFinalize)
@@ -71,10 +74,7 @@ saImmOiCcbSetErrorString  = 
decorate(saImmOi.saImmOiCcbSetErrorString)
def initialize(callbacks=None):
      ''' Initializes IMM OI '''
-
-    version = SaVersionT('A', 2, 15)
-
-    saImmOiInitialize_2(HANDLE, callbacks, version)
+    saImmOiInitialize_2(HANDLE, callbacks, OI_VER)
def register_applier(name):
diff --git a/python/pyosaf/utils/immom/__init__.py 
b/python/pyosaf/utils/immom/__init__.py
index 09370c8..8d2a49e 100644
--- a/python/pyosaf/utils/immom/__init__.py
+++ b/python/pyosaf/utils/immom/__init__.py
@@ -31,7 +31,7 @@ from pyosaf.saImm import eSaImmScopeT, unmarshalSaImmValue, 
SaImmAttrNameT, \
  from pyosaf.saImmOm import SaImmHandleT, SaImmAccessorHandleT,\
      saImmOmAdminOwnerInitialize
-from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
from pyosaf.utils import SafException
  from pyosaf.utils.immom.object import ImmObject
@@ -39,8 +39,11 @@ from pyosaf.utils.immom.object import ImmObject
  HANDLE = saImmOm.SaImmHandleT()
  ACCESSOR_HANDLE = SaImmAccessorHandleT()
+# Define IMM OM version
+OM_VER = SaVersionT('A', 2, 15)
+
  # Decorate IMM functions to add retry loops and error handling
-saImmOmInitialize         = decorate(saImmOm.saImmOmInitialize)
+saImmOmInitialize = initialize_decorate(saImmOm.saImmOmInitialize, OM_VER)
  saImmOmSelectionObjectGet = decorate(saImmOm.saImmOmSelectionObjectGet)
  saImmOmDispatch           = decorate(saImmOm.saImmOmDispatch)
  saImmOmFinalize           = decorate(saImmOm.saImmOmFinalize)
@@ -74,9 +77,7 @@ saImmOmAdminOperationContinuationClear = 
decorate(saImmOm.saImmOmAdminOperationC
def initialize():
      ''' saImmOmInitialize with TRYAGAIN handling '''
-    version = SaVersionT('A', 2, 15)
-
-    err = saImmOmInitialize(HANDLE, None, version)
+    err = saImmOmInitialize(HANDLE, None, OM_VER)
err = saImmOmAccessorInitialize(HANDLE, ACCESSOR_HANDLE) diff --git a/python/pyosaf/utils/log/__init__.py b/python/pyosaf/utils/log/__init__.py
index 152df61..695d53a 100644
--- a/python/pyosaf/utils/log/__init__.py
+++ b/python/pyosaf/utils/log/__init__.py
@@ -20,12 +20,12 @@
  '''
  from pyosaf import saLog, saAis
-from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
LOG_VERSION = saAis.SaVersionT('A', 2, 1) # Decorate LOG functions to add retry loops and error handling
-saLogInitialize         = decorate(saLog.saLogInitialize)
+saLogInitialize = initialize_decorate(saLog.saLogInitialize, LOG_VERSION)
  saLogSelectionObjectGet = decorate(saLog.saLogSelectionObjectGet)
  saLogDispatch           = decorate(saLog.saLogDispatch)
  saLogFinalize           = decorate(saLog.saLogFinalize)
diff --git a/python/pyosaf/utils/ntf/__init__.py 
b/python/pyosaf/utils/ntf/__init__.py
index 95df5f6..4034cfb 100644
--- a/python/pyosaf/utils/ntf/__init__.py
+++ b/python/pyosaf/utils/ntf/__init__.py
@@ -22,17 +22,20 @@
  from pyosaf import saNtf, saAis
  import ctypes
-from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
-saNtfInitialize = decorate(saNtf.saNtfInitialize)
+# Define NTF version
+NTF_VER = saAis.SaVersionT('A', 1, 1)
+
+saNtfInitialize = initialize_decorate(saNtf.saNtfInitialize, NTF_VER)
  saNtfLocalizedMessageFree       = decorate(saNtf.saNtfLocalizedMessageFree)
  saNtfStateChangeNotificationFilterAllocate = 
decorate(saNtf.saNtfStateChangeNotificationFilterAllocate)
  saNtfNotificationUnsubscribe    = decorate(saNtf.saNtfNotificationUnsubscribe)
  saNtfNotificationReadInitialize = 
decorate(saNtf.saNtfNotificationReadInitialize)
-saNtfInitialize_2               = decorate(saNtf.saNtfInitialize_2)
+saNtfInitialize_2 = initialize_decorate(saNtf.saNtfInitialize_2, NTF_VER)
  saNtfNotificationReadInitialize_2 = 
decorate(saNtf.saNtfNotificationReadInitialize_2)
  saNtfNotificationSubscribe      = decorate(saNtf.saNtfNotificationSubscribe)
-saNtfInitialize_3               = decorate(saNtf.saNtfInitialize_3)
+saNtfInitialize_3 = initialize_decorate(saNtf.saNtfInitialize_3, NTF_VER)
  saNtfSelectionObjectGet         = decorate(saNtf.saNtfSelectionObjectGet)
  saNtfDispatch                   = decorate(saNtf.saNtfDispatch)
  saNtfFinalize                   = decorate(saNtf.saNtfFinalize)
@@ -135,10 +138,6 @@ def dummy_func(*args):
def initialize(notification_callback=None):
      ''' Initializes the NTF library'''
-
-    # Initialize the NTF API
-    version = saAis.SaVersionT('A', 1, 1)
-
      # Assign default values for callbacks
      CALLBACKS.saNtfNotificationCallback = \
                      saNtf.SaNtfNotificationCallbackT(dummy_func)
@@ -151,7 +150,7 @@ def initialize(notification_callback=None):
                      saNtf.SaNtfNotificationCallbackT(notification_callback)
# Initialize the API
-    saNtfInitialize(HANDLE, CALLBACKS, version)
+    saNtfInitialize(HANDLE, CALLBACKS, NTF_VER)
# Get the selection object
      saNtfSelectionObjectGet(HANDLE, SELECTION_OBJECT)

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to