Architecture
Parallelism at two levels — across tasks via the connection pool, within transfers via chunk pipelining on a single SMB session.
Connection pool
HybridSMB runs up to four SMB operations in parallel through
SmbConnectionPool(4). Each slot is one smb2_context —
its own TCP socket and full session:
TCP → NEGOTIATE → SESSION SETUP → TREE CONNECT
Tasks call requestContext(mode), hold a slot for the operator's lifetime,
then release via PoolContextHandle. One operator per slot (mutex on the context).
Work on different slots runs concurrently.
Slot assignment
| Slot | Accepts | Typical work |
|---|---|---|
slot[0] |
Interactive only |
listDirectory, getPathInfo, rename, move |
slot[1..3] |
Any mode | Download, upload, copy, delete; grows on demand |
Acquire modes
| Mode | Operators |
|---|---|
Interactive |
getPathInfo, shallow listDirectory, moveItem, renameItem, createDirectory, getSecurityDescriptor, listShares |
Metadata |
downloadFile, uploadFile, copyItem, duplicateItem, deleteItem, recursive listDirectory |
FIFO queue per mode.
Pool vs SMB3 multichannel
The server sees each active slot as a separate client connection — multiple full sessions to the same host/share, not channels bound to one session.
| This pool | SMB3 multichannel | |
|---|---|---|
| Sessions | One per slot | One across channels |
| Server view | N connections | 1 client, N channels |
| Slot 0 reserved for UI | Yes | — |
| Requires server multichannel cap | No | Yes |
libsmb2 does not implement SMB3 multichannel. Each smb2_context maps to one
file descriptor, so the pool uses independent contexts instead.
Chunk pipeline
Cross-task parallelism is the pool. Within a single transfer,
SmbFileIO pipelines up to eight SMB2 READ/WRITE requests
on the same smb2_context (kMaxInFlight).
Same connection, same session — credit-based pipelining, separate from slot assignment.
Diagnostics
const info = smb.getPoolInfo(); const id = smb.subscribePoolInfo((snap) => console.log(snap)); smb.unsubscribePoolInfo(id);
PoolSlotInfo fields: index, interactiveOnly, state, isConnected, shareName, taskId, kind.
| Observation | Likely cause |
|---|---|
Same index turning over quickly | Tasks queuing on one slot |
Slots 1–3 all Assigned, metadata pending | Pool full |
Interactive kind on slot 1–3 | Slot 0 was busy |
See example/components/PoolDebugPanel.js for a live debug UI.