mirror of
https://github.com/OMGeeky/gdriver2.git
synced 2026-02-23 15:38:32 +01:00
Initial prototype
This prototype has basic IPC working, with starting actions and waiting for actions or just getting information
This commit is contained in:
18
gdriver-backend/Cargo.toml
Normal file
18
gdriver-backend/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "gdriver-backend"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
fuser={ version = "0.14", default_features = true, features = ["serializable"] }
|
||||
tracing.workspace = true
|
||||
tokio.workspace = true
|
||||
serde.workspace = true
|
||||
tarpc.workspace = true
|
||||
futures.workspace = true
|
||||
chrono.workspace = true
|
||||
|
||||
[dependencies.gdriver-common]
|
||||
path = "../gdriver-common/"
|
||||
29
gdriver-backend/src/drive.rs
Normal file
29
gdriver-backend/src/drive.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use gdriver_common::{drive_structure::drive_id::DriveId, prelude::CONFIGURATION};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub struct Drive {
|
||||
tracked_files: HashMap<DriveId, DateTime<Utc>>,
|
||||
}
|
||||
impl Drive {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
tracked_files: HashMap::new(),
|
||||
}
|
||||
}
|
||||
pub fn get_file_tracking_state(&self, id: &DriveId) -> TrackingState {
|
||||
let file = self.tracked_files.get(id);
|
||||
match file {
|
||||
Some(date) => TrackingState::Tracked(*date),
|
||||
None => TrackingState::Untracked,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum TrackingState {
|
||||
Untracked,
|
||||
Tracked(DateTime<Utc>),
|
||||
}
|
||||
23
gdriver-backend/src/main.rs
Normal file
23
gdriver-backend/src/main.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use futures::{future, prelude::*};
|
||||
use std::net::SocketAddr;
|
||||
use tarpc::{
|
||||
context,
|
||||
server::{self, incoming::Incoming, Channel},
|
||||
tokio_serde::formats::Json,
|
||||
};
|
||||
mod prelude;
|
||||
use crate::prelude::*;
|
||||
pub(crate) use gdriver_common::prelude::*;
|
||||
mod drive;
|
||||
mod sample;
|
||||
mod service;
|
||||
|
||||
pub(crate) async fn spawn(fut: impl Future<Output = ()> + Send + 'static) {
|
||||
tokio::spawn(fut);
|
||||
}
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// sample::main().await?;
|
||||
service::start().await?;
|
||||
Ok(())
|
||||
}
|
||||
2
gdriver-backend/src/prelude.rs
Normal file
2
gdriver-backend/src/prelude.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub(crate) type Result<T> = StdResult<T, Box<dyn Error>>;
|
||||
use std::{error::Error, result::Result as StdResult};
|
||||
38
gdriver-backend/src/sample.rs
Normal file
38
gdriver-backend/src/sample.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use super::*;
|
||||
use gdriver_common::ipc::sample::World;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct HelloServer(SocketAddr);
|
||||
|
||||
impl World for HelloServer {
|
||||
async fn hello(self, _: context::Context, name: String) -> String {
|
||||
println!("Got Hello request with name: {name}");
|
||||
format!("Hello {}", name)
|
||||
}
|
||||
}
|
||||
pub(super) async fn main() -> Result<()> {
|
||||
println!("Hello, world!");
|
||||
let config = &CONFIGURATION;
|
||||
let server_addr = (config.ip, config.port);
|
||||
let mut listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?;
|
||||
|
||||
println!("Listening");
|
||||
listener.config_mut().max_frame_length(usize::MAX);
|
||||
listener
|
||||
// Ignore accept errors.
|
||||
.filter_map(|r| future::ready(r.ok()))
|
||||
.map(server::BaseChannel::with_defaults)
|
||||
// Limit channels to 1 per IP.
|
||||
.max_channels_per_key(1, |t| t.transport().peer_addr().unwrap().ip())
|
||||
// serve is generated by the service attribute. It takes as input any type implementing
|
||||
// the generated World trait.
|
||||
.map(|channel| {
|
||||
let server = HelloServer(channel.transport().peer_addr().unwrap());
|
||||
channel.execute(server.serve()).for_each(spawn)
|
||||
})
|
||||
// Max 10 channels.
|
||||
.buffer_unordered(10)
|
||||
.for_each(|_| async {})
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
100
gdriver-backend/src/service.rs
Normal file
100
gdriver-backend/src/service.rs
Normal file
@@ -0,0 +1,100 @@
|
||||
use std::{sync::Arc, thread};
|
||||
|
||||
use chrono::Duration;
|
||||
use gdriver_common::{
|
||||
drive_structure::drive_id::ROOT_ID,
|
||||
ipc::gdriver_service::{BackendActionError, BackendActionRequest, GDriverService},
|
||||
};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::drive::Drive;
|
||||
|
||||
use super::*;
|
||||
#[derive(Clone)]
|
||||
struct GdriverServer {
|
||||
socket_address: SocketAddr,
|
||||
drive: Arc<Mutex<Drive>>,
|
||||
}
|
||||
impl GDriverService for GdriverServer {
|
||||
async fn do_something2(
|
||||
self,
|
||||
_: ::tarpc::context::Context,
|
||||
req: BackendActionRequest,
|
||||
) -> std::result::Result<String, BackendActionError> {
|
||||
println!("You are connected from {}", self.socket_address);
|
||||
|
||||
match req {
|
||||
BackendActionRequest::ShutdownGracefully => {
|
||||
println!("Shutdown request received, but I dont want to.");
|
||||
Err(BackendActionError::CouldNotComplete)
|
||||
//Ok(String::from("OK. Shutting down"))
|
||||
}
|
||||
BackendActionRequest::UpdateChanges => {
|
||||
println!("UpdateChanges request received");
|
||||
let drive = &self.drive;
|
||||
print_sample_tracking_state(drive).await;
|
||||
|
||||
Ok(String::from("OK"))
|
||||
}
|
||||
BackendActionRequest::Ping => {
|
||||
println!("Ping request received");
|
||||
Ok(String::from("Pong"))
|
||||
}
|
||||
BackendActionRequest::RunLong => {
|
||||
println!("RunLong request received");
|
||||
long_running_task(&self.drive).await;
|
||||
Ok(String::from("OK"))
|
||||
}
|
||||
BackendActionRequest::StartLong => {
|
||||
println!("StartLong request received");
|
||||
tokio::spawn(async move { long_running_task(&self.drive).await });
|
||||
Ok(String::from("OK"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn long_running_task(drive: &Arc<Mutex<Drive>>) {
|
||||
thread::sleep(Duration::seconds(10).to_std().unwrap());
|
||||
print_sample_tracking_state(drive).await;
|
||||
}
|
||||
async fn print_sample_tracking_state(drive: &Arc<Mutex<Drive>>) {
|
||||
let lock = drive.lock();
|
||||
let drive = lock.await;
|
||||
let state = drive.get_file_tracking_state(&ROOT_ID);
|
||||
dbg!(state);
|
||||
}
|
||||
pub async fn start() -> Result<()> {
|
||||
println!("Hello, world!");
|
||||
let config = &CONFIGURATION;
|
||||
println!("Config: {:?}", **config);
|
||||
|
||||
let drive = Drive::new();
|
||||
let m = Arc::new(Mutex::new(drive));
|
||||
|
||||
let server_addr = (config.ip, config.port);
|
||||
let mut listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?;
|
||||
listener.config_mut().max_frame_length(usize::MAX);
|
||||
|
||||
println!("Listening");
|
||||
listener
|
||||
// Ignore accept errors.
|
||||
.filter_map(|r| future::ready(r.ok()))
|
||||
.map(server::BaseChannel::with_defaults)
|
||||
// // Limit channels to 1 per IP.
|
||||
.max_channels_per_key(1, |t| t.transport().peer_addr().unwrap().ip())
|
||||
// serve is generated by the service attribute. It takes as input any type implementing
|
||||
// the generated World trait.
|
||||
.map(|channel| {
|
||||
let c = channel.transport().peer_addr().unwrap();
|
||||
let server = GdriverServer {
|
||||
socket_address: c,
|
||||
drive: m.clone(),
|
||||
};
|
||||
channel.execute(server.serve()).for_each(spawn)
|
||||
})
|
||||
// Max 10 channels.
|
||||
.buffer_unordered(10)
|
||||
.for_each(|_| async {})
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user