Commit 1fbda448 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 1c6d9f5a
......@@ -22,16 +22,22 @@
Join(zurl) joins wcfs server. If wcfs server for zurl is not yet running, it
will be automatically started if `autostart=True` is passed to join.
It will also be automatically started by default unless
$WENDELIN_CORE_WCFS_AUTOSTART=no is specified in environment.
WCFS represents filesystem-level connection to wcfs server. XXX created by join.
Conn represents logical connection that provides view of data on wcfs
filesystem as of particular database state.
The rest of wcfs.py merely wraps C++ wcfs client package:
WCFS represents connection to wcfs server obtained by join.
FileH ... XXX
XXX
- `WCFS` represents filesystem-level connection to wcfs server.
- `Conn` represents logical connection that provides view of data on wcfs
filesystem as of particular database state.
- `FileH` represent isolated file view under Conn.
- `Mapping` represents one memory mapping of FileH.
A path from WCFS to Mapping is as follows:
WCFS.connect(at) -> Conn
Conn.open(foid) -> FileH
FileH.mmap([blk_start +blk_len)) -> Mapping
Please see wcfs/client/wcfs.h for further details.
Classes in wcfs module logically mirror classes in ZODB:
......@@ -39,8 +45,18 @@ Classes in wcfs module logically mirror classes in ZODB:
wcfs.Conn <-> ZODB.Connection
$WENDELIN_CORE_WCFS_AUTOSTART
$WENDELIN_CORE_WCFS_OPTIONS
Environment variables
---------------------
The following environment variables can be used to control wcfs.py client:
$WENDELIN_CORE_WCFS_AUTOSTART
yes join: spawn wcfs server if no one was found and no explicit
autostart=X was given (default)
no join: don't spawn wcfs server unless explicitly requested via autostart=True
$WENDELIN_CORE_WCFS_OPTIONS
"" join: additional options to pass to wcfs server if one is spawned
"""
from __future__ import print_function, absolute_import
......@@ -67,20 +83,20 @@ from .client._wcfs import \
# Use join to create it.
#
# 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 .connect and Conn for details.
# data as of particular database state, and use that logical connection to create
# base-layer mappings. See .connect and Conn in C++ API for details.
#
# Raw files on wcfs can be accessed with ._path/._read/._stat/._open .
#
# WCFS logically mirrors ZODB.DB .
#
# XXX kill doc instead of C++.
# XXX +close in the end
class WCFS(_WCFS):
# .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
......@@ -143,7 +159,8 @@ def close(wc):
with _wcmu:
wc._njoin -= 1
if wc._njoin == 0:
# XXX unmount wcfs as well?
# NOTE not unmounting wcfs - it either runs as separate service, or
# is spawned on demand with -autoexit.
wc._fwcfs.close()
del _wcregistry[wc.mountpoint]
......@@ -189,6 +206,8 @@ def join(zurl, autostart=_default_autostart()): # -> WCFS
raise RuntimeError("wcfs: join %s: server not started" % zurl)
# start wcfs with telling it to automatically exit when there is no client activity.
# XXX race window if external process starts after ^^^ check
# TODO -> fs-level locking
optv_extra = os.environ.get("WENDELIN_CORE_WCFS_OPTIONS", "").split()
return _start(zurl, "-autoexit", *optv_extra)
......@@ -318,7 +337,8 @@ def serve(zurl, optv, exec_=False):
raise RuntimeError("wcfs: start %s: already started" % zurl)
# seems to be ok to start
# XXX race window if something starts after ^^^ check
# XXX race window if external process starts after ^^^ check
# TODO -> fs-level locking
argv = [_wcfs_exe()] + list(optv) + [zurl, mntpt]
if not exec_:
subprocess.check_call(argv, close_fds=True)
......
......@@ -133,7 +133,7 @@ struct PinReq;
// WCFS represents filesystem-level connection to wcfs server.
//
// XXX Use join to create it?
// Use wcfs.join in Python API to create it.
//
// 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
......
......@@ -2300,7 +2300,8 @@ func _main() (err error) {
flag.Parse()
if len(flag.Args()) != 2 {
return fmt.Errorf("Usage: %s [OPTIONS] zurl mntpt", os.Args[0])
fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS] zurl mntpt\n", os.Args[0])
os.Exit(2)
}
zurl := flag.Args()[0]
mntpt := flag.Args()[1]
......
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