perfectly working system

This commit is contained in:
filipriec
2025-02-15 23:36:20 +01:00
parent b871d40759
commit 598db07f16
8 changed files with 76 additions and 62 deletions

View File

@@ -0,0 +1,6 @@
-- Add migration script here
CREATE TABLE processed_data (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);

View File

@@ -1,15 +1,16 @@
// proto/api.proto
syntax = "proto3"; syntax = "proto3";
package my_service; package multieko2;
service MyService { service DataProcessor {
rpc MyMethod (MyRequest) returns (MyResponse); rpc ProcessData (DataRequest) returns (DataResponse);
} }
message MyRequest { message DataRequest {
int32 id = 1; string data = 1;
} }
message MyResponse { message DataResponse {
string message = 1; string processed_data = 1;
} }

View File

@@ -1,7 +1,18 @@
use crate::proto::api::accounting_client::AccountingClient; // src/client/mod.rs
use tonic::transport::Channel;
use crate::proto::multieko2::data_processor_client::DataProcessorClient;
use crate::proto::multieko2::DataRequest;
pub async fn run_client() -> Result<(), Box<dyn std::error::Error>> { pub async fn run_client() -> Result<(), Box<dyn std::error::Error>> {
let mut client = AccountingClient::connect("http://[::1]:50051").await?; let mut client = DataProcessorClient::connect("http://[::1]:50051").await?;
// Client implementation
let request = tonic::Request::new(DataRequest {
data: "hello world".to_string(),
});
let response = client.process_data(request).await?;
println!("RESPONSE={:?}", response.into_inner().processed_data);
Ok(()) Ok(())
} }

View File

@@ -1,3 +1,5 @@
// src/lib.rs // src/lib.rs
pub mod db; pub mod db;
pub mod client;
pub mod server; pub mod server;
pub mod proto;

View File

@@ -1,33 +1,21 @@
// src/main.rs // src/main.rs
use tonic::transport::Server; use std::env;
use sqlx::PgPool; use dotenvy::dotenv;
use crate::db; use multieko2::{server, client, db};
use crate::server;
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> { async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load .env file dotenv().ok();
dotenvy::dotenv().ok();
// Initialize database // Initialize database
let db_config = db::DatabaseConfig::from_env(); let db_config = db::DatabaseConfig::from_env();
let db_pool = db::create_pool(&db_config) let db_pool = db::create_pool(&db_config).await?;
.await
.expect("Failed to create database pool");
match env::args().nth(1).as_deref() {
// Check database connection
db::check_connection(&db_pool)
.await
.expect("Failed to connect to database");
// Choose mode based on command line arguments
let args: Vec<String> = env::args().collect();
match args.get(1).map(|s| s.as_str()) {
Some("server") => server::run_server(db_pool).await?, Some("server") => server::run_server(db_pool).await?,
Some("client") => client::run_client().await?, Some("client") => client::run_client().await?,
Some("standalone") => standalone::run().await?, _ => println!("Usage: cargo run -- [server|client]"),
_ => println!("Usage: [server|client|standalone]"),
} }
Ok(()) Ok(())
} }

3
src/proto/mod.rs Normal file
View File

@@ -0,0 +1,3 @@
pub mod multieko2 {
tonic::include_proto!("multieko2");
}

View File

@@ -1,27 +1,51 @@
// src/server/mod.rs
use tonic::{Request, Response, Status}; use tonic::{Request, Response, Status};
use crate::{db, proto::api::*}; use crate::db;
use crate::proto::multieko2::{
data_processor_server::{DataProcessor, DataProcessorServer},
DataRequest, DataResponse
};
pub struct AccountingService { pub struct DataProcessorService {
db_pool: sqlx::PgPool, db_pool: sqlx::PgPool,
} }
#[tonic::async_trait] #[tonic::async_trait]
impl accounting_server::Accounting for AccountingService { impl DataProcessor for DataProcessorService {
async fn create_account( async fn process_data(
&self, &self,
request: Request<CreateAccountRequest>, request: Request<DataRequest>,
) -> Result<Response<CreateAccountResponse>, Status> { ) -> Result<Response<DataResponse>, Status> {
// Database implementation let data = request.into_inner().data;
// Store data in database
let stored_data = sqlx::query!(
"INSERT INTO processed_data (content) VALUES ($1) RETURNING id",
data
)
.fetch_one(&self.db_pool)
.await
.map_err(|e| Status::internal(e.to_string()))?;
// Simple processing: convert to uppercase
let processed_data = data.to_uppercase();
Ok(Response::new(DataResponse {
processed_data: format!("Processed data with ID: {}", stored_data.id)
}))
} }
} }
pub async fn run_server(pool: sqlx::PgPool) -> Result<(), Box<dyn std::error::Error>> { pub async fn run_server(db_pool: sqlx::PgPool) -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?; let addr = "[::1]:50051".parse()?;
let service = DataProcessorService { db_pool };
println!("Server listening on {}", addr);
tonic::transport::Server::builder() tonic::transport::Server::builder()
.add_service(accounting_server::AccountingServer::new( .add_service(DataProcessorServer::new(service))
AccountingService { db_pool: pool }
))
.serve(addr) .serve(addr)
.await?; .await?;
Ok(()) Ok(())
} }

View File

@@ -1,21 +0,0 @@
use crate::server::run_server;
use crate::client::run_client;
use sqlx::PgPool;
pub async fn run() -> Result<(), Box<dyn std::error::Error>> {
// Set up local PostgreSQL connection
let db_pool = PgPool::connect("postgres://user:password@localhost/multieko2").await?;
// Run the server in the background
let server_handle = tokio::spawn(async move {
run_server(db_pool).await.unwrap();
});
// Run the client
run_client("http://[::1]:50051".to_string()).await?;
// Wait for the server to finish (it won't, but this keeps the app running)
server_handle.await?;
Ok(())
}