[repository] implement a generic way to call repo-side services; closes #2203418
authorFlorent Cayré <florent.cayre@logilab.fr>
Mon, 27 Feb 2012 10:11:04 +0100
changeset 8268 c9babe49c1c1
parent 8267 486386d9f836
child 8270 38648b051199
[repository] implement a generic way to call repo-side services; closes #2203418
dbapi.py
server/__init__.py
server/repository.py
--- a/dbapi.py	Mon Feb 27 10:03:31 2012 +0100
+++ b/dbapi.py	Mon Feb 27 10:11:04 2012 +0100
@@ -556,6 +556,12 @@
             except Exception:
                 pass
 
+    # server-side service call #################################################
+
+    @check_not_closed
+    def call_service(self, regid, async=False, **kwargs):
+        return self._repo.call_service(self.sessionid, regid, async, **kwargs)
+
     # connection initialization methods ########################################
 
     def load_appobjects(self, cubes=_MARKER, subpath=None, expand=True):
--- a/server/__init__.py	Mon Feb 27 10:03:31 2012 +0100
+++ b/server/__init__.py	Mon Feb 27 10:11:04 2012 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -31,10 +31,12 @@
 
 from logilab.common.modutils import LazyObject
 from logilab.common.textutils import splitstrip
+from logilab.common.registry import yes
 
 from yams import BASE_GROUPS
 
 from cubicweb import CW_SOFTWARE_ROOT
+from cubicweb.appobject import AppObject
 
 class ShuttingDown(BaseException):
     """raised when trying to access some resources while the repository is
@@ -42,7 +44,26 @@
     catch it.
     """
 
-# server-side debugging #########################################################
+# server-side services #########################################################
+
+class Service(AppObject):
+    """Base class for services.
+
+    A service is a selectable object that performs an action server-side.
+    Use :class:`cubicweb.dbapi.Connection.call_service` to call them from
+    the web-side.
+
+    When inheriting this class, do not forget to define at least the __regid__
+    attribute (and probably __select__ too).
+    """
+    __registry__ = 'services'
+    __select__ = yes()
+
+    def call(self, **kwargs):
+        raise NotImplementedError
+
+
+# server-side debugging ########################################################
 
 # server debugging flags. They may be combined using binary operators.
 
--- a/server/repository.py	Mon Feb 27 10:03:31 2012 +0100
+++ b/server/repository.py	Mon Feb 27 10:11:04 2012 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -878,6 +878,22 @@
         del self._sessions[sessionid]
         self.info('closed session %s for user %s', sessionid, session.user.login)
 
+    def call_service(self, sessionid, regid, async, **kwargs):
+        """
+        See :class:`cubicweb.dbapi.Connection.call_service`
+        and :class:`cubicweb.server.Service`
+        """
+        def task():
+            session = self._get_session(sessionid)
+            service = session.vreg['services'].select(regid, session, **kwargs)
+            return service.call(session, **kwargs)
+        if async:
+            self.info('calling service %s asynchronously', regid)
+            self.threaded_task(task)
+        else:
+            self.info('calling service %s synchronously', regid)
+            return task()
+
     def user_info(self, sessionid, props=None):
         """this method should be used by client to:
         * check session id validity
@@ -1671,6 +1687,7 @@
     # only defining here to prevent pylint from complaining
     info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
 
+
 def pyro_unregister(config):
     """unregister the repository from the pyro name server"""
     from logilab.common.pyro_ext import ns_unregister