Allow the acquired file to be closed manually
Instead of requiring library users to wait for a GC pass to close the file descriptor, make it possible for a explicit close() call to do the same. This makes it possible for users of these locks to avoid running out of file descriptors that they are unable to close. Change-Id: I3fabc57b2f0f6b1cef45553cac7e04732a9c2489
This commit is contained in:
parent
a0980f8a95
commit
15e659f2b2
|
@ -16,3 +16,4 @@ coverage>=3.6
|
|||
psycopg2
|
||||
PyMySQL>=0.6.2 # MIT License
|
||||
sysv_ipc>=0.6.8 # BSD License
|
||||
fixtures>=0.3.14
|
||||
|
|
|
@ -57,6 +57,10 @@ class FileLock(locking.Lock):
|
|||
|
||||
return _lock()
|
||||
|
||||
def close(self):
|
||||
self.release()
|
||||
self.lockfile.close()
|
||||
|
||||
def release(self):
|
||||
self.unlock()
|
||||
self.acquired = False
|
||||
|
|
|
@ -74,14 +74,22 @@ class SharedWeakLockHelper(Lock):
|
|||
self._newlock = lambda: lockclass(
|
||||
self.name, *args, **kwargs)
|
||||
|
||||
def acquire(self, blocking=True):
|
||||
@property
|
||||
def lock(self):
|
||||
"""Access the underlying lock object.
|
||||
|
||||
For internal usage only.
|
||||
"""
|
||||
with self.LOCKS_LOCK:
|
||||
try:
|
||||
l = self.ACQUIRED_LOCKS[self._lock_key]
|
||||
except KeyError:
|
||||
l = self.RELEASED_LOCKS.setdefault(
|
||||
self._lock_key, self._newlock())
|
||||
return l
|
||||
|
||||
def acquire(self, blocking=True):
|
||||
l = self.lock
|
||||
if l.acquire(blocking):
|
||||
with self.LOCKS_LOCK:
|
||||
self.RELEASED_LOCKS.pop(self._lock_key, None)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2015 Yahoo! Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import uuid
|
||||
|
||||
import fixtures
|
||||
from testtools import testcase
|
||||
|
||||
from tooz import coordination
|
||||
|
||||
|
||||
class TestFileClosing(testcase.TestCase):
|
||||
@staticmethod
|
||||
def _get_random_uuid():
|
||||
return str(uuid.uuid4()).encode('ascii')
|
||||
|
||||
def setUp(self):
|
||||
super(TestFileClosing, self).setUp()
|
||||
self.tempd = self.useFixture(fixtures.TempDir())
|
||||
self.url = 'file:///%s' % self.tempd.path
|
||||
self.member_id = self._get_random_uuid()
|
||||
|
||||
def test_lock_closing(self):
|
||||
driver = coordination.get_coordinator(self.url, self.member_id)
|
||||
lk = driver.get_lock(b'test').lock
|
||||
self.assertFalse(lk.lockfile.closed)
|
||||
lk.close()
|
||||
self.assertTrue(lk.lockfile.closed)
|
Loading…
Reference in New Issue