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