Rev 16: Start working on ensuring we can handle multiple locks concurrently. in lp:~jameinel/+junk/file_locking

John Arbash Meinel john at arbash-meinel.com
Mon Sep 21 20:17:38 BST 2009


At lp:~jameinel/+junk/file_locking

------------------------------------------------------------
revno: 16
revision-id: john at arbash-meinel.com-20090921191730-wv111xgffuxh7h8c
parent: john at arbash-meinel.com-20090921171402-552ryvpccp0dj5qc
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: file_locking
timestamp: Mon 2009-09-21 14:17:30 -0500
message:
  Start working on ensuring we can handle multiple locks concurrently.
-------------- next part --------------
=== modified file 'file_lock.py'
--- a/file_lock.py	2009-09-21 17:14:02 +0000
+++ b/file_lock.py	2009-09-21 19:17:30 +0000
@@ -17,10 +17,14 @@
 """Functionality for cooperative file locking."""
 
 import cStringIO
+import os
+import time
 
 from bzrlib import (
+    config as _mod_config,
     errors,
     lockdir,
+    osutils,
     rio,
     )
 
@@ -146,7 +150,7 @@
             tracked_ids = []
         else:
             tracked_ids = stanza.get_all('t')
-        return FileLockingInfo(tracked_ids)
+        return FileLockingInfo(tracked_ids, [])
 
     def to_bytes(self, locking_info):
         content = [self._HEADER, '\n']
@@ -154,6 +158,14 @@
         for tracked_id in sorted(locking_info._tracked_ids):
             stanza.add('t', tracked_id)
         content.extend(stanza.to_lines())
+        content.append('\n')
+        stanza = rio.Stanza(active_locks=str(len(locking_info._active_locks)))
+        content.extend(stanza.to_lines())
+        content.append('\n')
+        for file_id in sorted(locking_info._active_locks):
+            info = locking_info._active_locks[file_id]
+            content.extend(info.to_lines())
+            content.append('\n')
         return ''.join(content)
 
 
@@ -164,9 +176,25 @@
     :ivar _tracked_ids: The actual locations where content is tracked
     """
 
-    def __init__(self, tracked_ids):
+    def __init__(self, tracked_ids, active_locks):
         self._tracked_ids = set(tracked_ids)
+        self._active_locks = active_locks
 
+    def create_lock(self, file_id):
+        # Mostly the same info that is generated for bzr LockDir info files
+        # Note that this is slightly wrong if you have a per-directory username
+        global_conf = _mod_config.GlobalConfig()
+        nonce = osutils.rand_chars(20)
+        s = rio.Stanza(hostname=osutils.get_host_name(),
+                   pid=str(os.getpid()),
+                   start_time=str(int(time.time())),
+                   nonce=nonce,
+                   user=global_conf.username(),
+                   file_id=file_id,
+                   )
+        self._active_locks[file_id] = s
+        return s
+        
 
 class FileLockStore(object):
     """This is the actual location where file locks are tracked.
@@ -202,7 +230,7 @@
             transport.put_bytes('README.txt',
                 'This is a Bazaar File Locking Lock Store\n'
                 'You should not need to modify any files in this directory.\n')
-            locking_info = FileLockingInfo([])
+            locking_info = FileLockingInfo([], [])
             s = FileLockingInfoSerializer()
             bytes = s.to_bytes(locking_info)
             # Instead of having a separate 'format' file, we put the data into
@@ -270,6 +298,7 @@
 
     def take_lock(self, path):
         """Take the lock for the given path."""
+        file_id = self._wt.path2id(path)
 
     def steal_lock(self, path):
         """There is a lock from someone else on the given path, take it."""

=== modified file 'tests/test_file_lock.py'
--- a/tests/test_file_lock.py	2009-09-21 17:14:02 +0000
+++ b/tests/test_file_lock.py	2009-09-21 19:17:30 +0000
@@ -16,8 +16,11 @@
 
 """Tests for cooperative file locking."""
 
+import os
+
 from bzrlib import (
     errors,
+    rio,
     tests,
     )
 
@@ -48,24 +51,93 @@
         self.assertEqual(set(['file-id-1', 'dir-id-2']), li._tracked_ids)
 
     def test_to_bytes_trivial(self):
-        li = file_lock.FileLockingInfo([])
+        li = file_lock.FileLockingInfo([], {})
         s = file_lock.FileLockingInfoSerializer()
         self.assertEqualDiff('%s\n'
+                             '\n'
+                             'active_locks: 0\n'
                              '\n' % s._HEADER, s.to_bytes(li))
+
     def test_to_bytes(self):
-        li = file_lock.FileLockingInfo(['file-id-1', 'file-id-2'])
+        li = file_lock.FileLockingInfo(['file-id-1', 'file-id-2'], {})
         s = file_lock.FileLockingInfoSerializer()
         self.assertEqualDiff('%s\n'
                              't: file-id-1\n'
-                             't: file-id-2\n' % s._HEADER, s.to_bytes(li))
+                             't: file-id-2\n'
+                             '\n'
+                             'active_locks: 0\n'
+                             '\n' % s._HEADER, s.to_bytes(li))
 
     def test_to_bytes_is_sorted(self):
-        li = file_lock.FileLockingInfo(['file-id-1', 'file-id-2', 'dir-id-3'])
+        li = file_lock.FileLockingInfo(['file-id-1', 'file-id-2', 'dir-id-3'],
+                                       {})
         s = file_lock.FileLockingInfoSerializer()
         self.assertEqualDiff('%s\n'
                              't: dir-id-3\n'
                              't: file-id-1\n'
-                             't: file-id-2\n' % s._HEADER, s.to_bytes(li))
+                             't: file-id-2\n'
+                             '\n'
+                             'active_locks: 0\n'
+                             '\n' % s._HEADER, s.to_bytes(li))
+
+    def test_create_lock(self):
+        li = file_lock.FileLockingInfo(['file-id-1', 'file-id-2'], {})
+        info = li.create_lock('file-id-1')
+        self.assertTrue('file-id-1' in li._active_locks)
+        self.assertEqual(info, li._active_locks['file-id-1'])
+        self.assertEqual('file-id-1', info['file_id'])
+        s = file_lock.FileLockingInfoSerializer()
+        self.assertEqualDiff('%s\n'
+                             't: file-id-1\n'
+                             't: file-id-2\n'
+                             '\n'
+                             'active_locks: 1\n'
+                             '\n'
+                             'file_id: file-id-1\n'
+                             'hostname: %s\n'
+                             'nonce: %s\n'
+                             'pid: %s\n'
+                             'start_time: %s\n'
+                             'user: %s\n'
+                             '\n' % (s._HEADER,
+                                     info['hostname'],
+                                     info['nonce'],
+                                     os.getpid(),
+                                     info['start_time'],
+                                     info['user'],
+                                    ), s.to_bytes(li))
+        info2 = li.create_lock('file-id-2')
+        self.assertEqualDiff('%s\n'
+                             't: file-id-1\n'
+                             't: file-id-2\n'
+                             '\n'
+                             'active_locks: 2\n'
+                             '\n'
+                             'file_id: file-id-1\n'
+                             'hostname: %s\n'
+                             'nonce: %s\n'
+                             'pid: %s\n'
+                             'start_time: %s\n'
+                             'user: %s\n'
+                             '\n'
+                             'file_id: file-id-2\n'
+                             'hostname: %s\n'
+                             'nonce: %s\n'
+                             'pid: %s\n'
+                             'start_time: %s\n'
+                             'user: %s\n'
+                             '\n' % (s._HEADER,
+                                     info['hostname'],
+                                     info['nonce'],
+                                     os.getpid(),
+                                     info['start_time'],
+                                     info['user'],
+                                     info2['hostname'],
+                                     info2['nonce'],
+                                     os.getpid(),
+                                     info2['start_time'],
+                                     info2['user'],
+                                    ), s.to_bytes(li))
 
 
 class TestHeldLockSerializer(tests.TestCase):



More information about the bazaar-commits mailing list