Skip to main content

reifydb_core/actors/
server.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4//! Shared message and response types for network server actors.
5//!
6//! `ServerMessage` is the unified message type used by HTTP, gRPC, and WebSocket
7//! server actors. The same actor handles all protocols — the transport layer is
8//! just a thin shell that converts protocol-specific requests into `ServerMessage`.
9
10use std::{collections::HashMap, time::Duration};
11
12use reifydb_runtime::actor::{reply::Reply, system::ActorHandle};
13use reifydb_type::{
14	error::Diagnostic,
15	params::Params,
16	value::{frame::frame::Frame, identity::IdentityId},
17};
18
19use crate::metric::ExecutionMetrics;
20
21/// The type of database operation being executed.
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub enum Operation {
24	Query,
25	Command,
26	Admin,
27	Subscribe,
28}
29
30/// Handle to a server actor.
31pub type ServerHandle = ActorHandle<ServerMessage>;
32
33/// Unified message type for all network server actors (HTTP, gRPC, WebSocket).
34pub enum ServerMessage {
35	/// Execute a read-only query.
36	Query {
37		identity: IdentityId,
38		rql: String,
39		params: Params,
40		reply: Reply<ServerResponse>,
41	},
42	/// Execute a write command.
43	Command {
44		identity: IdentityId,
45		rql: String,
46		params: Params,
47		reply: Reply<ServerResponse>,
48	},
49	/// Execute an admin operation.
50	Admin {
51		identity: IdentityId,
52		rql: String,
53		params: Params,
54		reply: Reply<ServerResponse>,
55	},
56	/// Create a subscription.
57	Subscribe {
58		identity: IdentityId,
59		rql: String,
60		reply: Reply<ServerSubscribeResponse>,
61	},
62	/// Authenticate with credentials.
63	Authenticate {
64		method: String,
65		credentials: HashMap<String, String>,
66		reply: Reply<ServerAuthResponse>,
67	},
68	/// Logout / revoke a session token.
69	Logout {
70		token: String,
71		reply: Reply<ServerLogoutResponse>,
72	},
73}
74
75/// Response from an engine dispatch operation (query, command, admin).
76pub enum ServerResponse {
77	/// Operation succeeded with result frames and compute duration.
78	Success {
79		frames: Vec<Frame>,
80		duration: Duration,
81		metrics: ExecutionMetrics,
82	},
83	/// Engine returned an error.
84	EngineError {
85		diagnostic: Box<Diagnostic>,
86		rql: String,
87	},
88}
89
90/// Response from an authentication attempt.
91pub enum ServerAuthResponse {
92	/// Authentication succeeded.
93	Authenticated {
94		identity: IdentityId,
95		token: String,
96	},
97	/// Challenge-response round-trip required.
98	Challenge {
99		challenge_id: String,
100		payload: HashMap<String, String>,
101	},
102	/// Authentication failed.
103	Failed {
104		reason: String,
105	},
106	/// Internal error during authentication.
107	Error(String),
108}
109
110/// Response from a logout attempt.
111pub enum ServerLogoutResponse {
112	/// Token successfully revoked.
113	Ok,
114	/// Token was invalid or already expired.
115	InvalidToken,
116	/// Internal error during logout.
117	Error(String),
118}
119
120/// Response from a subscribe operation.
121pub enum ServerSubscribeResponse {
122	/// Subscription created successfully.
123	Subscribed {
124		frames: Vec<Frame>,
125		duration: Duration,
126		metrics: ExecutionMetrics,
127	},
128	/// Engine returned an error.
129	EngineError {
130		diagnostic: Box<Diagnostic>,
131		rql: String,
132	},
133}
134
135/// Build the appropriate `ServerMessage` from operation parameters.
136///
137/// Used by both the native `dispatch()` function and DST clients to construct
138/// messages for the `ServerActor`.
139pub fn build_server_message(
140	operation: Operation,
141	identity: IdentityId,
142	rql: String,
143	params: Params,
144	reply: Reply<ServerResponse>,
145) -> ServerMessage {
146	match operation {
147		Operation::Query => ServerMessage::Query {
148			identity,
149			rql,
150			params,
151			reply,
152		},
153		Operation::Command => ServerMessage::Command {
154			identity,
155			rql,
156			params,
157			reply,
158		},
159		Operation::Admin => ServerMessage::Admin {
160			identity,
161			rql,
162			params,
163			reply,
164		},
165		Operation::Subscribe => unreachable!("subscribe uses a different dispatch path"),
166	}
167}