vfs is a multi-module Java project that exposes a shared in-memory file tree over TCP.
Multiple terminal clients can connect to one server, navigate the same directory structure,
create and manage nodes, and coordinate access with per-node locks.
The system is intentionally simple:
- single server process
- in-memory state only
- no persistence across restarts
- session-based locking, not distributed consensus
Modules: vfs-core, vfs-client, vfs-server
Stack: Java 25, Spring Boot, Netty, Protocol Buffers
For the deeper runtime design, see ARCHITECTURE.md.
- Quick Start
- Module Layout
- Protocol
- Commands
- File System And Locking
- Configuration
- Local Operations
- Tests
From the repo root:
mvn -f vfs/pom.xml packageFrom the module directory:
cd vfs
mvn packagejava -jar vfs/server/target/VFS.jarDefault address: localhost:4499
java -jar vfs/client/target/VFS-client.jarThe client command parser accepts both forms:
connect localhost:4499 alice
connect localhost 4499 alice
connect localhost:4499 alice
mkdir docs
cd docs
mkfile notes.txt
print
whoami
quit
exit
| Module | Responsibility |
|---|---|
vfs-core |
shared protocol, command parsing, request/response factories, shared exceptions/utilities |
vfs-client |
interactive CLI client, Netty client bootstrap, response handling |
vfs-server |
Spring Boot server, command execution, in-memory tree, locking, session timeout |
Key code paths:
vfs-core/src/main/resources/protocol.protodefines the wire protocolvfs-coregeneratesProtocol.javaduring Mavengenerate-sourcesvfs-clientprovides the REPL and Netty client pipelinevfs-serverhosts the shared tree and all command implementations
Communication uses Protocol Buffers with Netty varint framing. The schema lives in vfs/core/src/main/resources/protocol.proto.
| Field | Type | Meaning |
|---|---|---|
id |
string |
session id |
login |
string |
user login |
| Field | Type | Meaning |
|---|---|---|
user |
User |
caller identity |
command |
string |
raw command text |
| Field | Type | Meaning |
|---|---|---|
code |
ResponseType |
result status |
message |
string |
human-readable output |
specificCode |
string |
optional extra value; used for the assigned session id on connect |
| Value | Meaning |
|---|---|
OK |
command succeeded |
FAIL |
command failed |
SUCCESS_CONNECT |
login accepted |
FAIL_CONNECT |
login rejected |
SUCCESS_QUIT |
session closed |
FAIL_QUIT |
session close failed |
On the first request, the client sends a placeholder user id (0).
If login succeeds:
specificCodecontains the real session UUIDmessagecontains the current working directory path
| Command | Syntax | Description |
|---|---|---|
connect |
connect <host>:<port> <login> |
open a socket and request a server session |
connect |
connect <host> <port> <login> |
equivalent space-separated form |
exit |
exit |
close the client process; if connected, sends quit first |
| Command | Syntax | Description |
|---|---|---|
quit |
quit |
disconnect from the server and remove the user home directory |
cd |
cd <directory> |
change current working directory |
mkdir |
mkdir <directory> |
create a directory |
mkfile |
mkfile <file> |
create a file |
rm |
rm <node> |
remove a node |
rename |
rename <node> <name> |
rename a node |
copy |
copy <node> <directory> |
deep-copy a node into a directory |
move |
move <node> <directory> |
move a node into a directory |
print |
print |
print the tree starting from the current directory |
lock |
lock [-r] <node> |
lock one node or a subtree |
unlock |
unlock [-r] <node> |
unlock one node or a subtree |
whoami |
whoami |
print the current login |
help |
help |
print command help |
The tree exists only in server memory. At startup the server creates:
/
└── home
On successful connect, the server creates:
/home/<login>
On quit or timeout, that home directory is removed.
/is the root- paths are relative to the current working directory unless they start with
/ .resolves to the current node..resolves to the parent node- duplicate child names under the same parent are rejected
Each node stores:
nametypeasDIRorFILEparent- ordered child list
print sorts directories and files before rendering the tree.
Locks are tracked in memory by LockService with a ConcurrentHashMap<Node, NodeLock>.
- locks are owned by the session user
-rapplies the operation recursively- a restart clears all locks
- mutating commands consult the lock state before changing the tree
Server configuration lives in vfs/server/src/main/resources/application.yaml.
| Key | Default | Meaning |
|---|---|---|
delimiter |
/ |
path separator |
server.name |
localhost |
bind address |
server.port |
4499 |
TCP port |
server.pool |
100 |
configured network pool size |
server.timeout |
10 |
idle timeout in minutes for logged-in sessions |
TimeoutJob also removes empty pre-login sessions after one minute.
lsof -i tcp:4499
kill -9 <PID>Run the full VFS module test suite:
mvn -f vfs/pom.xml testThe test suite covers:
- core command parsing and protocol factories
- client command flow and Netty client helpers
- server node management, locking, timeout, and session behavior