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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
0327a441
Commit
0327a441
authored
Jul 15, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
62016a67
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
104 additions
and
66 deletions
+104
-66
wcfs/__init__.py
wcfs/__init__.py
+90
-65
wcfs/wcfs_test.py
wcfs/wcfs_test.py
+14
-1
No files found.
wcfs/__init__.py
View file @
0327a441
...
...
@@ -49,23 +49,20 @@ from zodbtools.util import ashex
# WCFS represents connection to wcfs server.
#
# It has to be created with join.
# Only 1 connection is maintained for one file server.
class
WCFS
(
object
):
# .mountpoint path to wcfs mountpoint
# ._fwcfs /.wcfs/zurl opened to keep the server from going away (at least cleanly)
# ._njoin this connection was returned for so many joins
# XXX for-testing only?
# ._proc wcfs process if it was opened by this WCFS | None
pass
def
__init__
(
self
,
mountpoint
,
fwcfs
,
proc
):
self
.
mountpoint
=
mountpoint
self
.
_fwcfs
=
fwcfs
self
.
_proc
=
proc
def
close
(
self
):
# XXX unmount wcfs as well?
self
.
_fwcfs
.
close
()
"""
# open creates wcfs file handle, which can be mmaped to give data of ZBigFile.
#
# XXX more text
...
...
@@ -106,6 +103,7 @@ class FileH(object):
def mmap(self, pgoffset, pglen):
return _VMA(self.fd, pgoffset, pglen, pagesize, mmap.PROT_READ)
"""
...
...
@@ -113,39 +111,24 @@ class FileH(object):
# ---- join/run wcfs ----
# serve starts and runs wcfs server for ZODB @ zurl.
#
# it mounts wcfs at a location that is with 1-1 correspondence with zurl.
# it then waits for wcfs to exit (either due to unmount or an error).
#
# it is an error if wcfs was already started.
#
# XXX optv
# if exec_ is True, wcfs is not spawned, but executed into.
#
# serve(zurl, exec_=False).
def
serve
(
zurl
,
optv
,
exec_
=
False
):
mntpt
=
_mntpt_4zurl
(
zurl
)
# try opening .wcfs - it is an error if we can do it.
# XXX -> option to wcfs itself?
try
:
f
=
open
(
mntpt
+
"/.wcfs/zurl"
)
except
IOError
as
e
:
if
e
.
errno
!=
ENOENT
:
raise
else
:
f
.
close
()
raise
RuntimeError
(
"wcfs: start %s: already started"
%
zurl
)
# seems to be ok to start
# XXX race window if something starts after ^^^ check
argv
=
[
_wcfs_exe
()]
+
list
(
optv
)
+
[
zurl
,
mntpt
]
if
not
exec_
:
subprocess
.
check_call
(
argv
,
close_fds
=
True
)
else
:
os
.
execv
(
argv
[
0
],
argv
)
_wcmu
=
threading
.
Lock
()
_wcregistry
=
{}
# mntpt -> WCFS
@
func
(
WCFS
)
def
__init__
(
wc
,
mountpoint
,
fwcfs
,
proc
):
wc
.
mountpoint
=
mountpoint
wc
.
_fwcfs
=
fwcfs
wc
.
_njoin
=
1
wc
.
_proc
=
proc
@
func
(
WCFS
)
def
close
(
wc
):
with
_wcmu
:
wc
.
_njoin
-=
1
if
wc
.
_njoin
==
0
:
# XXX unmount wcfs as well?
wc
.
_fwcfs
.
close
()
del
_wcregistry
[
wc
.
mountpoint
]
# _default_autostart returns default autostart setting for join.
#
...
...
@@ -162,36 +145,39 @@ def _default_autostart():
#
# If wcfs for that zurl was already started, join connects to it.
# Otherwise it starts wcfs for zurl if autostart is True.
#
# If shared is True - a shared connection is returned - one that will be also XXX -> always this way
# returned for following join(shared=True) requests with the same zurl.
def
join
(
zurl
,
autostart
=
_default_autostart
(),
shared
=
False
):
# -> Conn
# XXX implement shared
def
join
(
zurl
,
autostart
=
_default_autostart
()):
# -> WCFS
mntpt
=
_mntpt_4zurl
(
zurl
)
# try opening .wcfs - if we succeed - it is already mounted.
# XXX -> wcfs itself?
try
:
f
=
open
(
mntpt
+
"/.wcfs/zurl"
)
except
IOError
as
e
:
if
e
.
errno
!=
ENOENT
:
raise
else
:
# already have it
return
WCFS
(
mntpt
,
f
,
None
)
if
not
autostart
:
raise
RuntimeError
(
"wcfs: join %s: server not started"
%
zurl
)
# start wcfs with telling it to automatically exit when there is no client activity.
optv_extra
=
os
.
environ
.
get
(
"WENDELIN_CORE_WCFS_OPTIONS"
,
""
).
split
()
return
_start
(
zurl
,
"-autoexit"
,
*
optv_extra
)
with
_wcmu
:
# check if we already have connection to wcfs server from this process
wc
=
_wcregistry
.
get
(
mntpt
)
if
wc
is
not
None
:
wc
.
_njoin
+=
1
return
wc
# no. try opening .wcfs - if we succeed - wcfs is already mounted.
try
:
f
=
open
(
mntpt
+
"/.wcfs/zurl"
)
except
IOError
as
e
:
if
e
.
errno
!=
ENOENT
:
raise
else
:
# already have it
wc
=
WCFS
(
mntpt
,
f
,
None
)
_wcregistry
[
mntpt
]
=
wc
return
wc
if
not
autostart
:
raise
RuntimeError
(
"wcfs: join %s: server not started"
%
zurl
)
# start wcfs with telling it to automatically exit when there is no client activity.
optv_extra
=
os
.
environ
.
get
(
"WENDELIN_CORE_WCFS_OPTIONS"
,
""
).
split
()
return
_start
(
zurl
,
"-autoexit"
,
*
optv_extra
)
# _start starts wcfs server for ZODB @ zurl.
#
# optv can be optionally given to pass flags to wcfs.
# called under _wcmu
def
_start
(
zurl
,
*
optv
):
# -> WCFS
mntpt
=
_mntpt_4zurl
(
zurl
)
log
.
info
(
"wcfs: starting for %s ..."
,
zurl
)
...
...
@@ -255,9 +241,14 @@ def _start(zurl, *optv): # -> WCFS
wg
.
go
(
_
)
wg
.
wait
()
assert
mntpt
not
in
_wcregistry
_wcregistry
[
mntpt
]
=
wc
return
wc
# ---- misc ----
# _wcfs_exe returns path to wcfs executable.
def
_wcfs_exe
():
return
'%s/wcfs'
%
dirname
(
__file__
)
...
...
@@ -301,6 +292,40 @@ def _mkdir_p(path):
raise
# serve starts and runs wcfs server for ZODB @ zurl.
#
# it mounts wcfs at a location that is with 1-1 correspondence with zurl.
# it then waits for wcfs to exit (either due to unmount or an error).
#
# it is an error if wcfs was already started.
#
# XXX optv
# if exec_ is True, wcfs is not spawned, but executed into.
#
# serve(zurl, exec_=False).
def
serve
(
zurl
,
optv
,
exec_
=
False
):
mntpt
=
_mntpt_4zurl
(
zurl
)
# try opening .wcfs - it is an error if we can do it.
# XXX -> option to wcfs itself?
try
:
f
=
open
(
mntpt
+
"/.wcfs/zurl"
)
except
IOError
as
e
:
if
e
.
errno
!=
ENOENT
:
raise
else
:
f
.
close
()
raise
RuntimeError
(
"wcfs: start %s: already started"
%
zurl
)
# seems to be ok to start
# XXX race window if something starts after ^^^ check
argv
=
[
_wcfs_exe
()]
+
list
(
optv
)
+
[
zurl
,
mntpt
]
if
not
exec_
:
subprocess
.
check_call
(
argv
,
close_fds
=
True
)
else
:
os
.
execv
(
argv
[
0
],
argv
)
# if called as main just -> serve()
...
...
wcfs/wcfs_test.py
View file @
0327a441
...
...
@@ -114,16 +114,23 @@ def test_join():
with
raises
(
RuntimeError
,
match
=
"wcfs: join .*: server not started"
):
wcfs
.
join
(
zurl
,
autostart
=
False
)
assert
wcfs
.
_wcregistry
==
{}
def
_
():
assert
wcfs
.
_wcregistry
==
{}
defer
(
_
)
wc
=
wcfs
.
_start
(
zurl
)
defer
(
wc
.
close
)
assert
wc
.
mountpoint
==
testmntpt
assert
wc
.
_njoin
==
1
assert
readfile
(
wc
.
mountpoint
+
"/.wcfs/zurl"
)
==
zurl
assert
os
.
path
.
isdir
(
wc
.
mountpoint
+
"/head"
)
assert
os
.
path
.
isdir
(
wc
.
mountpoint
+
"/head/bigfile"
)
wc2
=
wcfs
.
join
(
zurl
,
autostart
=
False
)
defer
(
wc2
.
close
)
assert
wc2
.
mountpoint
==
wc
.
mountpoint
assert
wc2
is
wc
assert
wc
.
_njoin
==
2
# test that join(autostart=y) works.
@
func
...
...
@@ -132,9 +139,15 @@ def test_join_autostart():
with
raises
(
RuntimeError
,
match
=
"wcfs: join .*: server not started"
):
wcfs
.
join
(
zurl
,
autostart
=
False
)
assert
wcfs
.
_wcregistry
==
{}
def
_
():
assert
wcfs
.
_wcregistry
==
{}
defer
(
_
)
wc
=
wcfs
.
join
(
zurl
,
autostart
=
True
)
defer
(
wc
.
close
)
assert
wc
.
mountpoint
==
testmntpt
assert
wc
.
_njoin
==
1
assert
readfile
(
wc
.
mountpoint
+
"/.wcfs/zurl"
)
==
zurl
assert
os
.
path
.
isdir
(
wc
.
mountpoint
+
"/head"
)
assert
os
.
path
.
isdir
(
wc
.
mountpoint
+
"/head/bigfile"
)
...
...
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