Merge lp://staging/~jderose/filestore/explicit-create into lp://staging/filestore
Status: | Merged |
---|---|
Merged at revision: | 320 |
Proposed branch: | lp://staging/~jderose/filestore/explicit-create |
Merge into: | lp://staging/filestore |
Diff against target: |
3188 lines (+1996/-623) 9 files modified
benchmark-protocol.py (+23/-42) debian/control (+2/-2) filestore/__init__.py (+230/-174) filestore/migration.py (+281/-0) filestore/misc.py (+16/-8) filestore/tests/__init__.py (+816/-388) filestore/tests/run.py (+5/-1) filestore/tests/test_migration.py (+548/-0) filestore/tests/test_misc.py (+75/-8) |
To merge this branch: | bzr merge lp://staging/~jderose/filestore/explicit-create |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Raymond | Approve | ||
Review via email: mp+163821@code.staging.launchpad.net |
Description of the change
For background, see this bug:
https:/
The are two interwoven goals here. The first is to force the programmer always to choose between assuming no file-store yet exists in a given parentdir, or assuming a file-store already exists in a given parentdir, with an unforgiving mountain of exceptions and double checks to punish anyone who crosses the streams. Architecturally the previous fuzzy gray area here was a really bad call on my part, and so I'm trying to atone now =)
The second is to cleanly separate out the V0 to V1 upgrade functionality from day to day FileStore functionality. Because the act of creating a FileStore instance could implicitly initialize a file-store layout where there wasn't one before, the upgrade functionality really had to be hooked into FileStore.
It's better to do the "soft-upgrade" (basically, moving files/ to files0/) before you create a FileStore instance, which you can now do:
>>> parentdir = '/media/
>>> m = Migration(
>>> m.needs_upgrade() # Soft upgrade if needed, but wont "create" anything
>>> fs = FileStore(
>>> fs = FileStore.
If `Migration.
Anyway, changes include:
* A file-store layout now must always be explicitly initialized, which is done using the new FileStore.create() classmethod:
FileStore.
If path.join(
This is a slightly different API than originally discussed in the bug, but there are a few circumstances where manually assigned the ID is handy. For one, unit testing, like to see what happens if you try to connect two physically distinct file-stores that happen to have the same ID. Also, for performance reasons one might want to periodically format a drive, but then initialize the file-store using the previous ID so the ID is stable over time.
Any additional **kw get included in the filestore.json document. The two that seem handy to me at the moment are `uuid` and `label` (the containing partition's UUID and Label).
* On the other hand, FileStore.
FileStore.
Note that when "loading" an existing file-store, you can't actually change the ID. The optional `expected_id` kwarg tells FileStore.
Also note that previously you could sort of "override" the copies value, but now this can only be provided in FileStore.create(). FileStore.
* Added the low-level `_create_
_create_
It isn't indented as part of the public API just yet, but I think it's a big step forward in terms of the file-store layout initialization being closer to atomic. It's a lot more robust than it was. It creates the layout in temporary directory .dmedia-<STORE_ID>, does everything relative to an open directory descriptor (hooray for Python 3.3), and then at the very last minute renames:
.dmedia-
* FileStore instances (including TempFileStore) now all have a FileStore.doc attribute, which is a Python dict and is the exact Dmedia V1 scheme compliant doc ready to save into CouchDB. This doc is dumped to filestore.json by FileStore.create(), and then is loaded whenever you load an existing file-store with FileStore.
* Moved all upgrade/migration functionality out of filestore and into the new filestore.migration module; this is much more robust than before and has extensive unit tests
* A bit of sundry cleanup and modernization, of the sort I just can't turn down during a refactor-fest such as this