Commit b8add3a0 by rfkelly0

LazyFS: lazy-creation code factored out of ConnectionManagerFS

parent d18fb2a3
......@@ -22,7 +22,7 @@ import time
import copy
from fs.base import FS, threading
from fs.wrapfs import WrapFS, wrap_fs_methods
from fs.wrapfs import WrapFS, LazyFS, wrap_fs_methods
from fs.path import *
from fs.errors import *
......@@ -156,7 +156,7 @@ class RemoteFileBuffer(object):
self._lock.release()
class ConnectionManagerFS(WrapFS):
class ConnectionManagerFS(LazyFS):
"""FS wrapper providing simple connection management of a remote FS.
The ConnectionManagerFS class is designed to wrap a remote FS object
......@@ -174,9 +174,9 @@ class ConnectionManagerFS(WrapFS):
operating-system integration may be added.
Since some remote FS classes can raise RemoteConnectionError during
initialisation, this class also provides a simple "lazy initialisation"
facility. The remote FS can be specified as an FS instance, an FS
subclass, or a (class,args) or (class,args,kwds) tuple. For example:
initialisation, this class makes use of lazy initialization. The
remote FS can be specified as an FS instance, an FS subclass, or a
(class,args) or (class,args,kwds) tuple. For example:
>>> fs = ConnectionManagerFS(MyRemoteFS("http://www.example.com/"))
Traceback (most recent call last):
......@@ -200,41 +200,6 @@ class ConnectionManagerFS(WrapFS):
self._poll_sleeper = threading.Event()
self.connected = connected
def _get_wrapped_fs(self):
try:
return self.__dict__["wrapped_fs"]
except KeyError:
self._connection_cond.acquire()
try:
try:
return self.__dict__["wrapped_fs"]
except KeyError:
fs = self._fsclass(*self._fsargs,**self._fskwds)
self.__dict__["wrapped_fs"] = fs
return fs
finally:
self._connection_cond.release()
def _set_wrapped_fs(self,fs):
if isinstance(fs,FS):
self.__dict__["wrapped_fs"] = fs
elif isinstance(fs,type):
self._fsclass = fs
self._fsargs = []
self._fskwds = {}
else:
self._fsclass = fs[0]
try:
self._fsargs = fs[1]
except IndexError:
self._fsargs = []
try:
self._fskwds = fs[2]
except IndexError:
self._fskwds = {}
wrapped_fs = property(_get_wrapped_fs,_set_wrapped_fs)
def setcontents(self,path,data):
self.wrapped_fs.setcontents(path,data)
......
......@@ -512,6 +512,7 @@ class FSTestCases:
fs3 = pickle.loads(pickle.dumps(self.fs,-1))
self.assert_(fs3.isfile("test1"))
def test_big_file(self):
chunk_size = 1024 * 256
num_chunks = 4
......
......@@ -233,6 +233,7 @@ class WrapFS(FS):
self.wrapped_fs.close()
super(WrapFS,self).close()
def wrap_fs_methods(decorator,cls=None,exclude=[]):
"""Apply the given decorator to all FS methods on the given class.
......@@ -268,7 +269,74 @@ def wrap_fs_methods(decorator,cls=None,exclude=[]):
return apply_decorator(cls)
else:
return apply_decorator
class LazyFS(WrapFS):
"""Simple 'lazy initialization' for FS objects.
This FS wrapper can be created with an FS instance, an FS class, or a
(class,args,kwds) tuple. The actual FS instance will be created on demand
the first time it is accessed.
"""
def __init__(self,fs):
super(LazyFS,self).__init__(fs)
self._lazy_creation_lock = threading.RLock()
def __getstate__(self):
state = super(LazyFS,self).__getstate__()
del state["_lazy_creation_lock"]
return state
def __setstate__(self,state):
self.__dict__.update(state)
self._lazy_creation_lock = threading.RLock()
def _get_wrapped_fs(self):
"""Obtain the wrapped FS instance, created it if necessary."""
try:
return self.__dict__["wrapped_fs"]
except KeyError:
self._lazy_creation_lock.acquire()
try:
try:
return self.__dict__["wrapped_fs"]
except KeyError:
fs = self._fsclass(*self._fsargs,**self._fskwds)
self.__dict__["wrapped_fs"] = fs
return fs
finally:
self._lazy_creation_lock.release()
def _set_wrapped_fs(self,fs):
if isinstance(fs,FS):
self.__dict__["wrapped_fs"] = fs
elif isinstance(fs,type):
self._fsclass = fs
self._fsargs = []
self._fskwds = {}
else:
self._fsclass = fs[0]
try:
self._fsargs = fs[1]
except IndexError:
self._fsargs = []
try:
self._fskwds = fs[2]
except IndexError:
self._fskwds = {}
wrapped_fs = property(_get_wrapped_fs,_set_wrapped_fs)
def close(self):
if not self.closed:
# If it was never initialized, create a fake one to close.
if "wrapped_fs" not in self.__dict__:
self.__dict__["wrapped_fs"] = FS()
super(LazyFS,self).close()
class HideDotFiles(WrapFS):
"""FS wrapper class that hides dot-files in directory listings.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment