backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 11 Oct 2011 11:00:24 +0200
changeset 7931 60068dc83457
parent 7929 900f1627b171 (current diff)
parent 7930 664d52cb936d (diff)
child 7934 2250a60a7653
backport stable
__pkginfo__.py
i18n/de.po
i18n/en.po
i18n/es.po
i18n/fr.po
schemas/base.py
server/migractions.py
server/repository.py
server/sources/datafeed.py
--- a/.hgtags	Mon Oct 10 16:15:55 2011 +0200
+++ b/.hgtags	Tue Oct 11 11:00:24 2011 +0200
@@ -229,3 +229,5 @@
 8a8949ca5351d48c5cf795ccdff06c1d4aab2ce0 cubicweb-debian-version-3.13.6-1
 68e8c81fa96d6bcd21cc17bc9832d388ce05a9eb cubicweb-version-3.13.7
 2f93ce32febe2f82565994fbd454f331f76ca883 cubicweb-debian-version-3.13.7-1
+249bd41693392d4716686f05c6b84628cd14dfcd cubicweb-version-3.13.8
+43f83f5d0a4d57a06e9a4990bc957fcfa691eec3 cubicweb-debian-version-3.13.8-1
--- a/debian/changelog	Mon Oct 10 16:15:55 2011 +0200
+++ b/debian/changelog	Tue Oct 11 11:00:24 2011 +0200
@@ -1,3 +1,9 @@
+cubicweb (3.13.8-1) unstable; urgency=low
+
+  * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr>  Fri, 07 Oct 2011 16:20:35 +0200
+
 cubicweb (3.13.7-1) unstable; urgency=low
 
   * new upstream release
--- a/i18n/de.po	Mon Oct 10 16:15:55 2011 +0200
+++ b/i18n/de.po	Tue Oct 11 11:00:24 2011 +0200
@@ -1864,9 +1864,6 @@
 msgid "ctxtoolbar"
 msgstr "Werkzeugleiste"
 
-msgid "currently in synchronization"
-msgstr ""
-
 msgid "custom_workflow"
 msgstr "angepasster Workflow"
 
@@ -2737,6 +2734,13 @@
 msgid "in_state_object"
 msgstr "Zustand von"
 
+msgid "in_synchronization"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "in_synchronization"
+msgstr ""
+
 msgid "incontext"
 msgstr "im Kontext"
 
@@ -3731,6 +3735,11 @@
 msgid "specifying %s is mandatory"
 msgstr ""
 
+msgid ""
+"start timestamp of the currently in synchronization, or NULL when no "
+"synchronization in progress."
+msgstr ""
+
 msgid "startup views"
 msgstr "Start-Ansichten"
 
@@ -3866,13 +3875,6 @@
 msgid "synchronization-interval must be greater than 1 minute"
 msgstr ""
 
-msgid "synchronizing"
-msgstr ""
-
-msgctxt "CWSource"
-msgid "synchronizing"
-msgstr ""
-
 msgid "table"
 msgstr "Tabelle"
 
--- a/i18n/en.po	Mon Oct 10 16:15:55 2011 +0200
+++ b/i18n/en.po	Tue Oct 11 11:00:24 2011 +0200
@@ -1816,9 +1816,6 @@
 msgid "ctxtoolbar"
 msgstr "toolbar"
 
-msgid "currently in synchronization"
-msgstr ""
-
 msgid "custom_workflow"
 msgstr "custom workflow"
 
@@ -2664,6 +2661,13 @@
 msgid "in_state_object"
 msgstr "state of"
 
+msgid "in_synchronization"
+msgstr "in synchronization"
+
+msgctxt "CWSource"
+msgid "in_synchronization"
+msgstr "in synchronization"
+
 msgid "incontext"
 msgstr "in-context"
 
@@ -3634,6 +3638,11 @@
 msgid "specifying %s is mandatory"
 msgstr ""
 
+msgid ""
+"start timestamp of the currently in synchronization, or NULL when no "
+"synchronization in progress."
+msgstr ""
+
 msgid "startup views"
 msgstr ""
 
@@ -3765,13 +3774,6 @@
 msgid "synchronization-interval must be greater than 1 minute"
 msgstr ""
 
-msgid "synchronizing"
-msgstr ""
-
-msgctxt "CWSource"
-msgid "synchronizing"
-msgstr ""
-
 msgid "table"
 msgstr ""
 
--- a/i18n/es.po	Mon Oct 10 16:15:55 2011 +0200
+++ b/i18n/es.po	Tue Oct 11 11:00:24 2011 +0200
@@ -1890,9 +1890,6 @@
 msgid "ctxtoolbar"
 msgstr "Barra de herramientas"
 
-msgid "currently in synchronization"
-msgstr ""
-
 msgid "custom_workflow"
 msgstr "Workflow específico"
 
@@ -2776,6 +2773,13 @@
 msgid "in_state_object"
 msgstr "Estado de"
 
+msgid "in_synchronization"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "in_synchronization"
+msgstr ""
+
 msgid "incontext"
 msgstr "En el contexto"
 
@@ -3778,6 +3782,11 @@
 msgid "specifying %s is mandatory"
 msgstr "especificar %s es obligatorio"
 
+msgid ""
+"start timestamp of the currently in synchronization, or NULL when no "
+"synchronization in progress."
+msgstr ""
+
 msgid "startup views"
 msgstr "Vistas de inicio"
 
@@ -3913,13 +3922,6 @@
 msgid "synchronization-interval must be greater than 1 minute"
 msgstr "synchronization-interval debe ser mayor a 1 minuto"
 
-msgid "synchronizing"
-msgstr ""
-
-msgctxt "CWSource"
-msgid "synchronizing"
-msgstr ""
-
 msgid "table"
 msgstr "Tabla"
 
--- a/i18n/fr.po	Mon Oct 10 16:15:55 2011 +0200
+++ b/i18n/fr.po	Tue Oct 11 11:00:24 2011 +0200
@@ -1896,9 +1896,6 @@
 msgid "ctxtoolbar"
 msgstr "barre d'outils"
 
-msgid "currently in synchronization"
-msgstr "en cours de synchronisation"
-
 msgid "custom_workflow"
 msgstr "workflow spécifique"
 
@@ -2778,6 +2775,13 @@
 msgid "in_state_object"
 msgstr "état de"
 
+msgid "in_synchronization"
+msgstr "en cours de synchronisation"
+
+msgctxt "CWSource"
+msgid "in_synchronization"
+msgstr "en cours de synchronisation"
+
 msgid "incontext"
 msgstr "dans le contexte"
 
@@ -3784,6 +3788,12 @@
 msgid "specifying %s is mandatory"
 msgstr "spécifier %s est obligatoire"
 
+msgid ""
+"start timestamp of the currently in synchronization, or NULL when no "
+"synchronization in progress."
+msgstr ""
+"horodate de départ de la synchronisation en cours, ou NULL s'il n'y en a pas."
+
 msgid "startup views"
 msgstr "vues de départ"
 
@@ -3919,13 +3929,6 @@
 msgid "synchronization-interval must be greater than 1 minute"
 msgstr "synchronization-interval doit être supérieur à 1 minute"
 
-msgid "synchronizing"
-msgstr "synchronisation"
-
-msgctxt "CWSource"
-msgid "synchronizing"
-msgstr "synchronisation"
-
 msgid "table"
 msgstr "table"
 
--- a/misc/migration/3.13.0_Any.py	Mon Oct 10 16:15:55 2011 +0200
+++ b/misc/migration/3.13.0_Any.py	Tue Oct 11 11:00:24 2011 +0200
@@ -1,4 +1,3 @@
 sync_schema_props_perms('cw_source', syncprops=False)
-add_attribute('CWSource', 'synchronizing')
 if schema['BigInt'].eid is None:
     add_entity_type('BigInt')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.13.8_Any.py	Tue Oct 11 11:00:24 2011 +0200
@@ -0,0 +1,5 @@
+change_attribute_type('CWCache', 'timestamp', 'TZDatetime')
+change_attribute_type('CWUser', 'last_login_time', 'TZDatetime')
+change_attribute_type('CWSource', 'latest_retrieval', 'TZDatetime')
+drop_attribute('CWSource', 'synchronizing')
+add_attribute('CWSource', 'in_synchronization')
--- a/schemas/base.py	Mon Oct 10 16:15:55 2011 +0200
+++ b/schemas/base.py	Tue Oct 11 11:00:24 2011 +0200
@@ -22,7 +22,8 @@
 
 from yams.buildobjs import (EntityType, RelationType, RelationDefinition,
                             SubjectRelation,
-                            String, Datetime, Password, Interval, Boolean)
+                            String, TZDatetime, Datetime, Password, Interval,
+                            Boolean)
 from cubicweb.schema import (
     RQLConstraint, WorkflowableEntityType, ERQLExpression, RRQLExpression,
     PUB_SYSTEM_ENTITY_PERMS, PUB_SYSTEM_REL_PERMS, PUB_SYSTEM_ATTR_PERMS)
@@ -41,7 +42,7 @@
     upassword = Password(required=True) # password is a reserved word for mysql
     firstname = String(maxsize=64)
     surname   = String(maxsize=64)
-    last_login_time  = Datetime(description=_('last connection date'))
+    last_login_time = TZDatetime(description=_('last connection date'))
     in_group = SubjectRelation('CWGroup', cardinality='+*',
                                constraints=[RQLConstraint('NOT O name "owners"')],
                                description=_('groups grant permissions to the user'))
@@ -226,7 +227,7 @@
 
     name = String(required=True, unique=True, maxsize=128,
                   description=_('name of the cache'))
-    timestamp = Datetime(default='NOW')
+    timestamp = TZDatetime(default='NOW')
 
 
 class CWSource(EntityType):
@@ -252,9 +253,9 @@
     # may changes when sources are specified
     url = String(description=_('URLs from which content will be imported. You can put one url per line'))
     parser = String(description=_('parser to use to extract entities from content retrieved at given URLs.'))
-    latest_retrieval = Datetime(description=_('latest synchronization time'))
-    synchronizing = Boolean(description=_('currently in synchronization'),
-                            default=False)
+    latest_retrieval = TZDatetime(description=_('latest synchronization time'))
+    in_synchronization = TZDatetime(description=_('start timestamp of the currently in synchronization, or NULL when no synchronization in progress.'))
+
 
 ENTITY_MANAGERS_PERMISSIONS = {
     'read':   ('managers',),
--- a/server/migractions.py	Mon Oct 10 16:15:55 2011 +0200
+++ b/server/migractions.py	Tue Oct 11 11:00:24 2011 +0200
@@ -1553,7 +1553,7 @@
         """
         rschema = self.repo.schema.rschema(attr)
         oldtype = rschema.objects(etype)[0]
-        rdefeid = rschema.rproperty(etype, oldtype, 'eid')
+        rdefeid = rschema.rdef(etype, oldtype).eid
         sql = ("UPDATE cw_CWAttribute "
                "SET cw_to_entity=(SELECT cw_eid FROM cw_CWEType WHERE cw_name='%s')"
                "WHERE cw_eid=%s") % (newtype, rdefeid)
--- a/server/repository.py	Mon Oct 10 16:15:55 2011 +0200
+++ b/server/repository.py	Tue Oct 11 11:00:24 2011 +0200
@@ -890,7 +890,7 @@
           deleted since the given timestamp
         """
         session = self.internal_session()
-        updatetime = datetime.now()
+        updatetime = datetime.utcnow()
         try:
             modentities, delentities = self.system_source.modified_entities(
                 session, etypes, mtime)
--- a/server/sources/__init__.py	Mon Oct 10 16:15:55 2011 +0200
+++ b/server/sources/__init__.py	Tue Oct 11 11:00:24 2011 +0200
@@ -65,13 +65,13 @@
         self.ttl = timedelta(seconds=ttl)
 
     def __setitem__(self, key, value):
-        dict.__setitem__(self, key, (datetime.now(), value))
+        dict.__setitem__(self, key, (datetime.utcnow(), value))
 
     def __getitem__(self, key):
         return dict.__getitem__(self, key)[1]
 
     def clear_expired(self):
-        now_ = datetime.now()
+        now_ = datetime.utcnow()
         ttl = self.ttl
         for key, (timestamp, value) in self.items():
             if now_ - timestamp > ttl:
--- a/server/sources/datafeed.py	Mon Oct 10 16:15:55 2011 +0200
+++ b/server/sources/datafeed.py	Tue Oct 11 11:00:24 2011 +0200
@@ -55,6 +55,15 @@
                    'external source (default to 5 minutes, must be >= 1 min).'),
           'group': 'datafeed-source', 'level': 2,
           }),
+        ('max-lock-lifetime',
+         {'type' : 'time',
+          'default': '1h',
+          'help': ('Maximum time allowed for a synchronization to be run. '
+                   'Exceeded that time, the synchronization will be considered '
+                   'as having failed and not properly released the lock, hence '
+                   'it won\'t be considered'),
+          'group': 'datafeed-source', 'level': 2,
+          }),
         ('delete-entities',
          {'type' : 'yn',
           'default': True,
@@ -92,6 +101,7 @@
         properly typed with defaults set
         """
         self.synchro_interval = timedelta(seconds=typedconfig['synchronization-interval'])
+        self.max_lock_lifetime = timedelta(seconds=typedconfig['max-lock-lifetime'])
         if source_entity is not None:
             self._entity_update(source_entity)
         self.config = typedconfig
@@ -140,8 +150,11 @@
     def acquire_synchronization_lock(self, session):
         # XXX race condition until WHERE of SET queries is executed using
         # 'SELECT FOR UPDATE'
-        if not session.execute('SET X synchronizing TRUE WHERE X eid %(x)s, X synchronizing FALSE',
-                               {'x': self.eid}):
+        now = datetime.utcnow()
+        if not session.execute('SET X in_synchronizaton %(now)s WHERE X eid %(x)s, X synchronizing NULL OR X synchronizing < %(maxdt)s',
+                               {'x': self.eid,
+                                'now': now,
+                                'maxdt': now - self.max_lock_lifetime}):
             self.error('concurrent synchronization detected, skip pull')
             session.commit(free_cnxset=False)
             return False
@@ -150,7 +163,7 @@
 
     def release_synchronization_lock(self, session):
         session.set_cnxset()
-        session.execute('SET X synchronizing FALSE WHERE X eid %(x)s',
+        session.execute('SET X synchronizing None WHERE X eid %(x)s',
                         {'x': self.eid})
         session.commit()
 
--- a/server/sources/native.py	Mon Oct 10 16:15:55 2011 +0200
+++ b/server/sources/native.py	Tue Oct 11 11:00:24 2011 +0200
@@ -972,7 +972,7 @@
             extid = b64encode(extid)
         uri = 'system' if source.copy_based_source else source.uri
         attrs = {'type': entity.__regid__, 'eid': entity.eid, 'extid': extid,
-                 'source': uri, 'asource': source.uri, 'mtime': datetime.now()}
+                 'source': uri, 'asource': source.uri, 'mtime': datetime.utcnow()}
         self.doexec(session, self.sqlgen.insert('entities', attrs), attrs)
         # insert core relations: is, is_instance_of and cw_source
         try:
@@ -1002,7 +1002,7 @@
             self.index_entity(session, entity=entity)
         # update entities.mtime.
         # XXX Only if entity.__regid__ in self.multisources_etypes?
-        attrs = {'eid': entity.eid, 'mtime': datetime.now()}
+        attrs = {'eid': entity.eid, 'mtime': datetime.utcnow()}
         self.doexec(session, self.sqlgen.update('entities', attrs, ['eid']), attrs)
 
     def delete_info_multi(self, session, entities, uri):
@@ -1019,7 +1019,7 @@
         if entities[0].__regid__ not in self.multisources_etypes:
             return
         attrs = {'type': entities[0].__regid__,
-                 'source': uri, 'dtime': datetime.now()}
+                 'source': uri, 'dtime': datetime.utcnow()}
         for entity in entities:
             extid = entity.cw_metainformation()['extid']
             if extid is not None:
@@ -1173,7 +1173,7 @@
         table when some undoable transaction is started
         """
         ueid = session.user.eid
-        attrs = {'tx_uuid': uuid, 'tx_user': ueid, 'tx_time': datetime.now()}
+        attrs = {'tx_uuid': uuid, 'tx_user': ueid, 'tx_time': datetime.utcnow()}
         self.doexec(session, self.sqlgen.insert('transactions', attrs), attrs)
 
     def _save_attrs(self, session, entity, attrs):
--- a/web/data/cubicweb.facets.js	Mon Oct 10 16:15:55 2011 +0200
+++ b/web/data/cubicweb.facets.js	Tue Oct 11 11:00:24 2011 +0200
@@ -60,11 +60,11 @@
         var rql = result[0];
         var $bkLink = jQuery('#facetBkLink');
         if ($bkLink.length) {
-            var bkPath = 'view?rql=' + escape(rql);
+            var bkPath = 'view?rql=' + encodeURIComponent(rql);
             if (vid) {
-                bkPath += '&vid=' + escape(vid);
+                bkPath += '&vid=' + encodeURIComponent(vid);
             }
-            var bkUrl = $bkLink.attr('cubicweb:target') + '&path=' + escape(bkPath);
+            var bkUrl = $bkLink.attr('cubicweb:target') + '&path=' + encodeURIComponent(bkPath);
             $bkLink.attr('href', bkUrl);
         }
         var toupdate = result[1];