Mountain/Vine/Server/
MountainVinegRPCService.rs

1//! # MountainVinegRPCService
2//!
3//! Defines the gRPC service implementation for Mountain. This struct handles
4//! incoming RPC calls from the `Cocoon` sidecar, dispatches them to the
5//! application's core logic via the `Track` module, and returns the results.
6
7use std::sync::Arc;
8
9use log::{error, info, trace};
10use serde_json::Value;
11use tauri::AppHandle;
12use tonic::{Request, Response, Status};
13
14use crate::{
15	RunTime::ApplicationRunTime::ApplicationRunTime,
16	Track,
17	Vine::Generated::{
18		CancelOperationRequest,
19		Empty,
20		GenericNotification,
21		GenericRequest,
22		GenericResponse,
23		RpcError as RPCError,
24		mountain_service_server::MountainService,
25	},
26};
27
28/// The concrete implementation of the `MountainService` gRPC service.
29pub struct MountainVinegRPCService {
30	ApplicationHandle:AppHandle,
31
32	RunTime:Arc<ApplicationRunTime>,
33}
34
35impl MountainVinegRPCService {
36	/// Creates a new instance of the Mountain gRPC service.
37	pub fn Create(ApplicationHandle:AppHandle, RunTime:Arc<ApplicationRunTime>) -> Self {
38		info!("[MountainVinegRPCService] New instance created.");
39
40		Self { ApplicationHandle, RunTime }
41	}
42}
43
44#[tonic::async_trait]
45impl MountainService for MountainVinegRPCService {
46	/// Handles generic request-response RPCs from Cocoon.
47	async fn process_cocoon_request(
48		&self,
49
50		request:Request<GenericRequest>,
51	) -> Result<Response<GenericResponse>, Status> {
52		let RequestData = request.into_inner();
53
54		let MethodName = RequestData.method;
55
56		let RequestIdentifier = RequestData.request_identifier;
57
58		info!(
59			"[VineServer] Received gRPC Request [ID: {}]: Method='{}'",
60			RequestIdentifier, MethodName
61		);
62
63		let ParametersValue:Value = match serde_json::from_slice(&RequestData.parameter) {
64			Ok(v) => v,
65
66			Err(Error) => {
67				let msg = format!("Failed to deserialize parameters for method '{}': {}", MethodName, Error);
68
69				error!("{}", msg);
70
71				return Ok(Response::new(GenericResponse {
72					request_identifier:RequestIdentifier,
73
74					result:vec![],
75
76					error:Some(RPCError { message:msg, code:-32700, data:vec![] }),
77				}));
78			},
79		};
80
81		trace!("[VineServer] Params for [ID: {}]: {:?}", RequestIdentifier, ParametersValue);
82
83		let DispatchResult = Track::DispatchLogic::DispatchSideCarRequest(
84			self.ApplicationHandle.clone(),
85			self.RunTime.clone(),
86			// In the future, this could come from connection metadata.
87			"cocoon-main".to_string(),
88			MethodName.clone(),
89			ParametersValue,
90		)
91		.await;
92
93		match DispatchResult {
94			Ok(SuccessfulResult) => {
95				let ResultBytes = serde_json::to_vec(&SuccessfulResult).unwrap_or_else(|Error| {
96					error!("Failed to serialize successful result for '{}': {}", MethodName, Error);
97
98					b"null".to_vec()
99				});
100
101				Ok(Response::new(GenericResponse {
102					request_identifier:RequestIdentifier,
103
104					result:ResultBytes,
105
106					error:None,
107				}))
108			},
109
110			Err(ErrorString) => {
111				Ok(Response::new(GenericResponse {
112					request_identifier:RequestIdentifier,
113
114					result:vec![],
115
116					error:Some(RPCError {
117						message:ErrorString,
118
119						// JSON-RPC Generic Server Error
120						code:-32000,
121
122						data:vec![],
123					}),
124				}))
125			},
126		}
127	}
128
129	/// Handles generic fire-and-forget notifications from Cocoon.
130	async fn send_cocoon_notification(&self, request:Request<GenericNotification>) -> Result<Response<Empty>, Status> {
131		let NotificationData = request.into_inner();
132
133		let MethodName = NotificationData.method;
134
135		info!("[VineServer] Received gRPC Notification: Method='{}'", MethodName);
136
137		// TODO: A full implementation would route these notifications to a
138		// dedicated handler for processing status updates, etc. For now, we
139		// just log and acknowledge.
140		// For example:
141		// let Parameter: Value = serde_json::from_slice(...)?;
142
143		// NotificationHandler::Handle(MethodName, Parameter).await;
144
145		Ok(Response::new(Empty {}))
146	}
147
148	/// Handles a request from Cocoon to cancel a long-running operation.
149	async fn cancel_operation(&self, _request:Request<CancelOperationRequest>) -> Result<Response<Empty>, Status> {
150		info!("[VineServer] Received CancelOperation request, but cancellation is not yet implemented.");
151
152		// A full implementation would map the RequestIdentifier_to_cancel to a
153		// CancellationToken and trigger it.
154		Ok(Response::new(Empty {}))
155	}
156}