Пример #1
0
    def lock(self, hash_key, timeout=60):
        """Acquires the lock on hash_key or raises LockError

        The return value is a context manager object that will
        automatically release the lock on hash_key when it exits.

        locks are not nestable, they can only be acquired once.  If the
        lock cannot be acquired a back-off strategy is implemented using
        random waits up to a total maximum of *timeout* seconds.  If the
        lock still cannot be obtained :py:class:`LockError` is raised."""
        owner = "%s_%i" % (self.magic, threading.current_thread().ident)
        with self.entity_set.OpenCollection() as locks:
            tnow = time.time()
            tstop = tnow + timeout
            twait = 0
            while tnow < tstop:
                time.sleep(twait)
                lock = locks.new_entity()
                lock['hash'].SetFromValue(hash_key)
                lock['owner'].SetFromValue(owner)
                lock['created'].SetFromValue(TimePoint.FromNowUTC())
                try:
                    locks.insert_entity(lock)
                    return LockStoreContext(self, hash_key)
                except edm.ConstraintError:
                    pass
                try:
                    lock = locks[hash_key]
                except KeyError:
                    # someone deleted the lock, go straight round again
                    twait = 0
                    tnow = time.time()
                    continue
                # has this lock expired?
                locktime = lock['created'].value.WithZone(zDirection=0)
                if locktime.get_unixtime() + self.lock_timeout < tnow:
                    # use optimistic locking
                    lock['owner'].SetFromValue(owner)
                    try:
                        locks.update_entity(lock)
                        logging.warn(
                            "LockingBlockStore removed stale lock "
                            "on %s", hash_key)
                        return LockStoreContext(self, hash_key)
                    except KeyError:
                        twait = 0
                        tnow = time.time()
                        continue
                    except edm.ConstraintError:
                        pass
                twait = random.randint(0, timeout // 5)
                tnow = time.time()
        logging.error("LockingBlockStore: timeout locking %s", hash_key)
        raise LockError
Пример #2
0
 def flush(self):
     if self._bdirty:
         # the current block is dirty, write it out
         data = self._bdata[:self._btop]
         if data:
             block = self.blocks[self._bnum]
             if block.exists:
                 self.ss.update_block(block, str(data))
             else:
                 self.blocks[self._bnum] = self.ss.store_block(
                     self.stream, self._bnum, data)
         if self.size != self.stream['size'].value:
             self.stream['size'].SetFromValue(self.size)
         now = TimePoint.FromNowUTC()
         self.stream['modified'].SetFromValue(now)
         self.stream.Update()
         self._bdirty = False
Пример #3
0
    def new_stream(self,
                   mimetype=http.MediaType('application', 'octet-stream')):
        """Creates a new stream in the store.

        mimetype
            A :py:class:`~pyslet.rfc2616.MimeType` object

        Returns a stream entity which is an
        :py:class:`~pyslet.odata2.csdl.Entity` instance.

        The stream is identified by the stream entity's key which
        you can store elsewhere as a reference."""
        with self.stream_set.OpenCollection() as streams:
            stream = streams.new_entity()
            if not isinstance(mimetype, http.MediaType):
                mimetype = http.MediaType.FromString(mimetype)
            stream['mimetype'].SetFromValue(str(mimetype))
            now = TimePoint.FromNowUTC()
            stream['size'].SetFromValue(0)
            stream['created'].SetFromValue(now)
            stream['modified'].SetFromValue(now)
            streams.insert_entity(stream)
            return stream