# XXX TODO
# Update the repository (in the background)
- await self.has_changed()
+ await self.changed()
async def remove_build(self, build, user=None):
"""
pass
# Update the repository (in the background)
- await self.has_changed()
+ await self.changed()
# Sources
return self.backend.pakfire(distro=self.distro, repos=[self], **kwargs)
- async def has_changed(self):
+ # Has Changed?
+
+ __has_changed = {}
+
+ @property
+ def has_changed(self):
+ """
+ This is set when the repository has been changed and needs an update
+ """
+ try:
+ event = self.__has_changed[self.id]
+ except KeyError:
+ event = self.__has_changed[self.id] = asyncio.Event()
+
+ return event
+
+ async def changed(self):
"""
Convenience function that should be called when a package has been
added/removed from this repository.
# Run the update process at the next convenient moment
self.backend.run_task(self.update)
+ __locks = {}
+
+ @property
+ def lock(self):
+ """
+ Locks the repository when it is being rewritten
+ """
+ try:
+ lock = self.__locks[self.id]
+ except KeyError:
+ lock = self.__locks[self.id] = asyncio.Lock()
+
+ return lock
+
async def update(self):
"""
Called to perform an update of this repository
"""
- # Write/rewrite the repository
- await self.write()
+ # If the repository is currently being rewritten,
+ # we will mark it as changed and return.
+ if self.lock.locked():
+ log.debug("%s is currently being updated" % self)
+
+ # Set flag
+ self.has_changed.set()
+ return
+
+ # Otherwise, try to acquire the lock
+ async with self.lock:
+ # Clear the "has changed" flag
+ self.has_changed.clear()
+
+ # Write/rewrite the repository
+ await self.write()
+
+ # Check if the repository has been changed in the meantime
+ # and if so, call ourselves again
+ if self.has_changed.is_set():
+ await self.update()
# Relaunch any pending jobs
await self.relaunch_pending_jobs()
# Write repository
- __locks = {}
-
- @property
- def __lock(self):
- try:
- lock = self.__locks[self.id]
- except KeyError:
- lock = self.__locks[self.id] = asyncio.Lock()
-
- return lock
-
async def write(self):
"""
Called to write/rewrite/update the repository metadata
"""
- with self.__lock:
- return await asyncio.to_thread(self._write)
+ return await asyncio.to_thread(self._write)
def _write(self):
log.info("Writing repository %s..." % self)