commands: classify commands into none/read/write lock scopes
This commit is contained in:
@@ -31,9 +31,44 @@ pub const ErrorCode = enum(i32) {
|
|||||||
invalid_pipeline_operator = 40324,
|
invalid_pipeline_operator = 40324,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Which lock (if any) a command needs on the engine. Contract: only
|
||||||
|
/// `.write` commands may call engine mutation functions (insert, replace,
|
||||||
|
/// remove, drop*, get_or_create_collection, compact); `.read` commands may
|
||||||
|
/// only read (`get_collection`, `database_names`, `collection_names`);
|
||||||
|
/// `.none` commands must not touch the engine at all.
|
||||||
|
const CommandKind = enum { none, read, write };
|
||||||
|
|
||||||
|
fn command_kind(name: []const u8) CommandKind {
|
||||||
|
// Read-only: scan the engine without mutating it.
|
||||||
|
if (std.mem.eql(u8, name, "find") or
|
||||||
|
std.mem.eql(u8, name, "count") or
|
||||||
|
std.mem.eql(u8, name, "aggregate") or
|
||||||
|
std.mem.eql(u8, name, "listDatabases") or
|
||||||
|
std.mem.eql(u8, name, "listCollections")) return .read;
|
||||||
|
// Writes: exclusive, totally ordered.
|
||||||
|
if (std.mem.eql(u8, name, "create") or
|
||||||
|
std.mem.eql(u8, name, "drop") or
|
||||||
|
std.mem.eql(u8, name, "dropDatabase") or
|
||||||
|
std.mem.eql(u8, name, "insert") or
|
||||||
|
std.mem.eql(u8, name, "update") or
|
||||||
|
std.mem.eql(u8, name, "delete") or
|
||||||
|
std.mem.eql(u8, name, "findAndModify")) return .write;
|
||||||
|
// Everything else (handshake, admin info, no-ops) needs no lock.
|
||||||
|
return .none;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dispatch(ctx: *Context, msg: *wire.Message, reply: *wire.Reply) !void {
|
pub fn dispatch(ctx: *Context, msg: *wire.Message, reply: *wire.Reply) !void {
|
||||||
|
switch (command_kind(msg.command_name())) {
|
||||||
|
.none => {},
|
||||||
|
.read => {
|
||||||
|
try ctx.engine.lock_read();
|
||||||
|
defer ctx.engine.unlock_read();
|
||||||
|
},
|
||||||
|
.write => {
|
||||||
try ctx.engine.lock();
|
try ctx.engine.lock();
|
||||||
defer ctx.engine.unlock();
|
defer ctx.engine.unlock();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const name = msg.command_name();
|
const name = msg.command_name();
|
||||||
if (std.mem.eql(u8, name, "hello")) return cmd_hello(ctx, reply);
|
if (std.mem.eql(u8, name, "hello")) return cmd_hello(ctx, reply);
|
||||||
|
|||||||
Reference in New Issue
Block a user