Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
02470041
Commit
02470041
authored
Jul 16, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
f8704273
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
52 additions
and
39 deletions
+52
-39
wcfs/__init__.py
wcfs/__init__.py
+47
-5
wcfs/wcfs_test.py
wcfs/wcfs_test.py
+5
-34
No files found.
wcfs/__init__.py
View file @
02470041
...
...
@@ -43,9 +43,10 @@ from golang import sync, context
from
golang.gcompat
import
qq
import
threading
from
persistent
import
Persistent
from
ZODB.FileStorage
import
FileStorage
from
ZODB.utils
import
u64
,
p64
from
zodbtools.util
import
ashex
from
zodbtools.util
import
ashex
as
h
# XXX -> use "ashex"
# WCFS represents filesystem-level connection to wcfs server.
...
...
@@ -56,6 +57,8 @@ from zodbtools.util import ashex
# The primary way to access wcfs is to open logical connection viewing on-wcfs
# data as of particular database state, and use that logical connection to
# create base-layer mappings. See .open and Conn for details.
#
# Raw files on wcfs can be accessed with ._path/._read/._stat/._open .
class
WCFS
(
object
):
# .mountpoint path to wcfs mountpoint
# ._fwcfs /.wcfs/zurl opened to keep the server from going away (at least cleanly)
...
...
@@ -84,7 +87,7 @@ class Conn(object):
# WatchLink represents /head/watch link opened on wcfs.
#
# .sendReq()/.recvReq() provides raw IO in terms of wcfs invalidation protocol messages.
class
WatchLink
:
class
WatchLink
(
object
)
:
def
__init__
(
wlink
,
wc
):
wlink
.
_wc
=
wc
...
...
@@ -97,10 +100,10 @@ class WatchLink:
#
# fdopen takes ownership of file descriptor and closes it when file
# object is closed -> dup fd so that each file object has its own fd.
wh
=
os
.
open
(
tdb
.
_path
(
"head/watch"
),
os
.
O_RDWR
)
wh
=
os
.
open
(
wc
.
_path
(
"head/watch"
),
os
.
O_RDWR
)
wh2
=
os
.
dup
(
wh
)
t
.
_wrx
=
os
.
fdopen
(
wh
,
'rb'
)
t
.
_wtx
=
os
.
fdopen
(
wh2
,
'wb'
)
wlink
.
_wrx
=
os
.
fdopen
(
wh
,
'rb'
)
wlink
.
_wtx
=
os
.
fdopen
(
wh2
,
'wb'
)
# XXX ...
...
...
@@ -108,6 +111,45 @@ class WatchLink:
# ---- WatchLink message IO ----
# ---- WCFS raw file access ----
# _path returns path for object on wcfs.
# - str: wcfs root + obj;
# - Persistent: wcfs root + (head|@<at>)/bigfile/obj
@
func
(
WCFS
)
def
_path
(
wc
,
obj
,
at
=
None
):
if
isinstance
(
obj
,
Persistent
):
#assert type(obj) is ZBigFile XXX import cycle
objtypestr
=
type
(
obj
).
__module__
+
"."
+
type
(
obj
).
__name__
assert
objtypestr
==
"wendelin.bigfile.file_zodb.ZBigFile"
,
objtypestr
head
=
"head/"
if
at
is
None
else
(
"@%s/"
%
h
(
at
))
obj
=
"%s/bigfile/%s"
%
(
head
,
h
(
obj
.
_p_oid
))
at
=
None
assert
isinstance
(
obj
,
str
)
assert
at
is
None
# must not be used with str
return
os
.
path
.
join
(
wc
.
mountpoint
,
obj
)
# _read reads file corresponding to obj on wcfs.
@
func
(
WCFS
)
def
_read
(
wc
,
obj
,
at
=
None
):
path
=
wc
.
_path
(
obj
,
at
=
at
)
with
open
(
path
,
'rb'
)
as
f
:
# XXX -> readfile
return
f
.
read
()
# _stat stats file corresponding to obj on wcfs.
@
func
(
WCFS
)
def
_stat
(
wc
,
obj
,
at
=
None
):
path
=
wc
.
_path
(
obj
,
at
=
at
)
return
os
.
stat
(
path
)
# _open opens file corresponding to obj on wcfs.
@
func
(
WCFS
)
def
_open
(
wc
,
obj
,
mode
=
'rb'
,
at
=
None
):
path
=
wc
.
_path
(
obj
,
at
=
at
)
return
open
(
path
,
mode
,
0
)
# unbuffered
"""
# open creates wcfs file handle, which can be mmaped to give data of ZBigFile.
#
...
...
wcfs/wcfs_test.py
View file @
02470041
...
...
@@ -207,8 +207,6 @@ class DFile:
#
# tDB must be explicitly closed once no longer used.
#
# Raw files on wcfs can be accessed with ._path/._read/._stat/._open .
#
# XXX print -> t.trace/debug() + t.verbose depending on py.test -v -v ?
class
tDB
:
@
func
...
...
@@ -429,7 +427,7 @@ class tDB:
t
.
_wc_zheadv
.
append
(
wchead
)
# head/at = last txn of whole db
assert
t
.
_read
(
"head/at"
)
==
h
(
t
.
head
)
assert
t
.
wc
.
_read
(
"head/at"
)
==
h
(
t
.
head
)
# _blkheadaccess marks head/zf[blk] accessed.
def
_blkheadaccess
(
t
,
zf
,
blk
):
...
...
@@ -440,33 +438,6 @@ class tDB:
def
_blkaccessed
(
t
,
zf
):
# set(blk)
return
t
.
_blkaccessedViaHead
.
setdefault
(
zf
,
set
())
# _path returns path for object on wcfs.
# - str: wcfs root + obj;
# - Persistent: wcfs root + (head|@<at>)/bigfile/obj
def
_path
(
t
,
obj
,
at
=
None
):
if
isinstance
(
obj
,
Persistent
):
head
=
"head/"
if
at
is
None
else
(
"@%s/"
%
h
(
at
))
obj
=
"%s/bigfile/%s"
%
(
head
,
h
(
obj
.
_p_oid
))
at
=
None
assert
isinstance
(
obj
,
str
)
assert
at
is
None
# must not be used with str
return
os
.
path
.
join
(
t
.
wc
.
mountpoint
,
obj
)
# _read reads file corresponding to obj on wcfs.
def
_read
(
t
,
obj
,
at
=
None
):
path
=
t
.
_path
(
obj
,
at
=
at
)
return
readfile
(
path
)
# _stat stats file corresponding to obj on wcfs.
def
_stat
(
t
,
obj
,
at
=
None
):
path
=
t
.
_path
(
obj
,
at
=
at
)
return
os
.
stat
(
path
)
# _open opens file corresponding to obj on wcfs.
def
_open
(
t
,
obj
,
mode
=
'rb'
,
at
=
None
):
path
=
t
.
_path
(
obj
,
at
=
at
)
return
open
(
path
,
mode
,
0
)
# unbuffered
# tFile provides testing environment for one bigfile opened on wcfs.
#
...
...
@@ -483,7 +454,7 @@ class tFile:
t
.
tdb
=
tdb
t
.
zf
=
zf
t
.
at
=
at
t
.
f
=
tdb
.
_open
(
zf
,
at
=
at
)
t
.
f
=
tdb
.
wc
.
_open
(
zf
,
at
=
at
)
t
.
blksize
=
zf
.
blksize
# mmap the file past the end up to _max_tracked_pages and setup
...
...
@@ -753,7 +724,7 @@ class tWatch:
class
tWatchLink
(
wcfs
.
WatchLink
):
def
__init__
(
t
,
tdb
):
super
(
tWatchLink
,
t
).
__init__
(
t
,
t
db
.
wc
)
super
(
tWatchLink
,
t
).
__init__
(
tdb
.
wc
)
t
.
tdb
=
tdb
...
...
@@ -765,7 +736,7 @@ class tWatchLink(wcfs.WatchLink):
#
# fdopen takes ownership of file descriptor and closes it when file
# object is closed -> dup fd so that each file object has its own fd.
wh
=
os
.
open
(
tdb
.
_path
(
"head/watch"
),
os
.
O_RDWR
)
wh
=
os
.
open
(
tdb
.
wc
.
_path
(
"head/watch"
),
os
.
O_RDWR
)
wh2
=
os
.
dup
(
wh
)
t
.
_wrx
=
os
.
fdopen
(
wh
,
'rb'
)
t
.
_wtx
=
os
.
fdopen
(
wh2
,
'wb'
)
...
...
@@ -1308,7 +1279,7 @@ def test_wcfs_basic():
# >>> lookup non-BigFile -> must be rejected
with
raises
(
OSError
)
as
exc
:
t
.
_stat
(
t
.
nonzfile
)
t
.
wc
.
_stat
(
"head/bigfile/%s"
%
h
(
t
.
nonzfile
.
_p_oid
)
)
assert
exc
.
value
.
errno
==
EINVAL
# >>> file initially empty
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment