예제 #1
0
  def _Acquire(self, lease_time):
    self.lock_token = thread.get_ident()
    sqlite_connection = self.store.cache.Get(self.subject)

    # We first check if there is a lock on the subject.
    # Next we set our lease time and lock_token as identification.
    with sqlite_connection:
      locked_until, stored_token = sqlite_connection.GetLock(self.subject)

      # This is currently locked by another thread.
      if locked_until and (time.time() * 1e6) < float(locked_until):
        raise data_store.DBSubjectLockError("Subject %s is locked" %
                                            self.subject)

      # Subject is not locked, we take a lease on it.
      self.expires = int((time.time() + lease_time) * 1e6)
      sqlite_connection.SetLock(self.subject, self.expires, self.lock_token)

    # TODO(user): This shouldn't really be necessary, and seems fragile. We
    # should be able to use an UPDATE WHERE lock_expiration < now inside a
    # transaction and check that we changed one row.
    # Check if the lock stuck. If the stored token is not ours
    # then probably someone was able to grab it before us.
    locked_until, stored_token = sqlite_connection.GetLock(self.subject)
    if stored_token != self.lock_token:
      raise data_store.DBSubjectLockError("Unable to lock subject %s" %
                                          self.subject)

    self.locked = True
예제 #2
0
 def UpdateLease(self, duration):
   ret = self.store.ExtendSubjectLock(self.subject, self.transid,
                                      duration * 1e6, self.token)
   if ret != self.transid:
     raise data_store.DBSubjectLockError(
         "Unable to update the lease on %s" % self.subject)
   self.expires = int((time.time() + duration) * 1e6)
예제 #3
0
    def _Acquire(self, lease_time):
        self.lock_token = thread.get_ident()
        self.expires = int((time.time() + lease_time) * 1e6)

        # This single query will create a new entry if one doesn't exist, and update
        # the lock value if there is a lock but it's expired.  The SELECT 1
        # statement checks if there is a current lock. The select from dual is
        # essentially a way to get the numbers into the query conditional on there
        # not being an existing lock.
        query = (
            "REPLACE INTO locks(lock_expiration, lock_owner, subject_hash) "
            "SELECT %s, %s, unhex(md5(%s)) FROM dual WHERE NOT EXISTS (SELECT 1 "
            "FROM locks WHERE subject_hash=unhex(md5(%s)) AND (lock_expiration > "
            "%s))")
        args = [
            self.expires, self.lock_token, self.subject, self.subject,
            time.time() * 1e6
        ]
        unused_results, rowcount = self.store.ExecuteQuery(query, args)

        # New row rowcount == 1, updating expired lock rowcount == 2.
        if rowcount == 0:
            raise data_store.DBSubjectLockError("Subject %s is locked" %
                                                self.subject)
        self.locked = True
예제 #4
0
 def _Acquire(self, lease_time):
   self.expires = int((time.time() + lease_time) * 1e6)
   with self.store.lock:
     expires = self.store.transactions.get(self.subject)
     if expires and (time.time() * 1e6) < expires:
       raise data_store.DBSubjectLockError("Subject is locked")
     self.store.transactions[self.subject] = self.expires
     self.locked = True
예제 #5
0
 def _Acquire(self, lease_time):
   self.transid = self.store.LockSubject(self.subject, lease_time * 1e6,
                                         self.token)
   if not self.transid:
     raise data_store.DBSubjectLockError(
         "Unable to lock subject %s" % self.subject)
   self.expires = int((time.time() + lease_time) * 1e6)
   self.locked = True