Add unix socket listner
This commit is contained in:
parent
833dc9ed3c
commit
70107257c2
23 changed files with 299 additions and 11 deletions
|
@ -10,6 +10,7 @@ license = "MIT OR Apache-2.0"
|
|||
repository = "https://forgejo.fireturlte.net/lazy-supplements"
|
||||
|
||||
[workspace.dependencies]
|
||||
ciborium = "0.2.2"
|
||||
dioxus = { version = "0.6.0", features = [] }
|
||||
lazy-supplements-core.path = "lazy-supplements-core"
|
||||
libp2p = { version = "0.55.0", features = ["macros", "mdns", "noise", "ping", "tcp", "tokio", "yamux" ] }
|
||||
|
@ -17,3 +18,4 @@ sea-orm-migration = { version = "1.1.0", features = ["runtime-tokio-rustls", "sq
|
|||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
thiserror = "2.0.12"
|
||||
tokio = { version = "1.45.0", features = ["macros", "rt", "rt-multi-thread"] }
|
||||
uuid = { version = "1.17.0", features = ["v7"] }
|
||||
|
|
|
@ -25,7 +25,7 @@ tokio.workspace = true
|
|||
toml = "0.8.22"
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
||||
uuid = { version = "1.17.0", features = ["v7"] }
|
||||
uuid.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.20.0"
|
||||
|
|
14
lazy-supplements-core/src/cache/entity/mod.rs
vendored
14
lazy-supplements-core/src/cache/entity/mod.rs
vendored
|
@ -0,0 +1,14 @@
|
|||
mod multi_address;
|
||||
mod peer;
|
||||
|
||||
pub use multi_address::{
|
||||
ActiveModel as MultiAddressActiveModel,
|
||||
Model as MultiAddressModel,
|
||||
Entity as MultiAddressEntity,
|
||||
};
|
||||
|
||||
pub use peer::{
|
||||
ActiveModel as PeerActiveModel,
|
||||
Model as PeerModel,
|
||||
Entity as PeerEntity,
|
||||
};
|
60
lazy-supplements-core/src/cache/entity/multi_address.rs
vendored
Normal file
60
lazy-supplements-core/src/cache/entity/multi_address.rs
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
use chrono::Local;
|
||||
use sea_orm::entity::{
|
||||
*,
|
||||
prelude::*
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "node")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: u32,
|
||||
#[sea_orm(indexed)]
|
||||
pub created_at: DateTimeUtc,
|
||||
#[sea_orm(indexed)]
|
||||
pub updated_at: DateTimeUtc,
|
||||
#[sea_orm(indexed)]
|
||||
pub synced_at: Option<DateTimeUtc>,
|
||||
#[sea_orm(indexed)]
|
||||
pub peer_id: String,
|
||||
#[sea_orm(column_type = "Text")]
|
||||
pub note: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
impl ActiveModel {
|
||||
pub fn new() -> Self {
|
||||
let timestamp: DateTimeUtc = Local::now().to_utc();
|
||||
Self{
|
||||
created_at: Set(timestamp),
|
||||
updated_at: Set(timestamp),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use libp2p::identity;
|
||||
use crate::global::GLOBAL;
|
||||
|
||||
#[tokio::test]
|
||||
async fn check_insert_node() {
|
||||
let db = crate::global::get_or_init_temporary_main_database().await;
|
||||
|
||||
ActiveModel{
|
||||
peer_id: Set(identity::Keypair::generate_ed25519().public().to_peer_id().to_string()),
|
||||
note: Set("test note".to_owned()),
|
||||
..ActiveModel::new()
|
||||
}.insert(db).await.unwrap();
|
||||
}
|
||||
|
||||
}
|
55
lazy-supplements-core/src/cache/entity/peer.rs
vendored
Normal file
55
lazy-supplements-core/src/cache/entity/peer.rs
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
use chrono::Local;
|
||||
use sea_orm::entity::{
|
||||
*,
|
||||
prelude::*
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "node")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: u32,
|
||||
#[sea_orm(indexed)]
|
||||
pub created_at: DateTimeUtc,
|
||||
#[sea_orm(indexed)]
|
||||
pub updated_at: DateTimeUtc,
|
||||
#[sea_orm(indexed)]
|
||||
pub peer_id: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
impl ActiveModel {
|
||||
pub fn new() -> Self {
|
||||
let timestamp: DateTimeUtc = Local::now().to_utc();
|
||||
Self{
|
||||
created_at: Set(timestamp),
|
||||
updated_at: Set(timestamp),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use libp2p::identity;
|
||||
use crate::global::GLOBAL;
|
||||
|
||||
#[tokio::test]
|
||||
async fn check_insert_node() {
|
||||
let db = crate::global::get_or_init_temporary_main_database().await;
|
||||
|
||||
ActiveModel{
|
||||
peer_id: Set(identity::Keypair::generate_ed25519().public().to_peer_id().to_string()),
|
||||
..ActiveModel::new()
|
||||
}.insert(db).await.unwrap();
|
||||
}
|
||||
|
||||
}
|
|
@ -14,8 +14,3 @@ pub use record_deletion::{
|
|||
Entity as RecordDeletionEntity,
|
||||
Model as RecordDeletionModel,
|
||||
};
|
||||
use uuid::{ContextV7, Timestamp, Uuid};
|
||||
|
||||
pub fn generate_uuid() -> Uuid {
|
||||
Uuid::new_v7(Timestamp::now(ContextV7::new()))
|
||||
}
|
|
@ -32,7 +32,7 @@ impl ActiveModel {
|
|||
pub fn new() -> Self {
|
||||
let timestamp: DateTimeUtc = Local::now().to_utc();
|
||||
Self{
|
||||
id: Set(super::generate_uuid()),
|
||||
id: Set(crate::global::generate_uuid()),
|
||||
created_at: Set(timestamp),
|
||||
updated_at: Set(timestamp),
|
||||
..Default::default()
|
||||
|
|
|
@ -26,7 +26,7 @@ impl ActiveModel {
|
|||
pub fn new() -> Self {
|
||||
let timestamp: DateTimeUtc = Local::now().to_utc();
|
||||
Self{
|
||||
id: Set(super::generate_uuid()),
|
||||
id: Set(crate::global::generate_uuid()),
|
||||
created_at: Set(timestamp),
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ mod tests {
|
|||
|
||||
assert!(ActiveModel{
|
||||
table_name: Set("test_table".to_string()),
|
||||
record_id: Set(super::super::generate_uuid()),
|
||||
record_id: Set(crate::global::generate_uuid()),
|
||||
..ActiveModel::new()
|
||||
}.insert(db).await.is_ok());
|
||||
}
|
||||
|
|
|
@ -9,6 +9,11 @@ use tokio::sync::{OnceCell, RwLock};
|
|||
|
||||
mod database;
|
||||
use database::GlobalDatabase;
|
||||
use uuid::{ContextV7, Timestamp, Uuid};
|
||||
|
||||
pub fn generate_uuid() -> Uuid {
|
||||
Uuid::new_v7(Timestamp::now(ContextV7::new()))
|
||||
}
|
||||
|
||||
pub static PRODUCT_NAME: LazyLock<String> = LazyLock::new(|| {
|
||||
env!("CARGO_PKG_NAME").to_string()
|
||||
|
|
4
lazy-supplements-core/src/ipc.rs
Normal file
4
lazy-supplements-core/src/ipc.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
pub trait Message {
|
||||
fn into_vec_u8(self) -> Vec<u8>;
|
||||
fn from_vec_u8() -> Self;
|
||||
}
|
|
@ -3,6 +3,7 @@ pub mod config;
|
|||
pub mod data;
|
||||
pub mod error;
|
||||
pub mod global;
|
||||
pub mod ipc;
|
||||
pub mod migration;
|
||||
pub mod p2p;
|
||||
#[cfg(any(test, feature="test"))]
|
||||
|
|
|
@ -11,6 +11,7 @@ default = []
|
|||
test = ["lazy-supplements-core/test"]
|
||||
|
||||
[dependencies]
|
||||
ciborium.workspace = true
|
||||
clap = { version = "4.5.38", features = ["derive"] }
|
||||
dirs = "6.0.0"
|
||||
lazy-supplements-core.workspace = true
|
||||
|
@ -18,6 +19,7 @@ libp2p.workspace = true
|
|||
serde.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
uuid.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
lazy-supplements-core = {workspace = true, features = ["test"]}
|
||||
lazy-supplements-core = {workspace = true, features = ["test"]}
|
||||
|
|
11
lazy-supplements-desktop/src/ipc/client/mod.rs
Normal file
11
lazy-supplements-desktop/src/ipc/client/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
#[cfg(unix)]
|
||||
pub mod unix;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub mod windows;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use unix::*;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub use windows::*;
|
0
lazy-supplements-desktop/src/ipc/client/unix.rs
Normal file
0
lazy-supplements-desktop/src/ipc/client/unix.rs
Normal file
0
lazy-supplements-desktop/src/ipc/client/windows.rs
Normal file
0
lazy-supplements-desktop/src/ipc/client/windows.rs
Normal file
4
lazy-supplements-desktop/src/ipc/message/mod.rs
Normal file
4
lazy-supplements-desktop/src/ipc/message/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
mod response;
|
||||
mod request;
|
||||
pub use response::*;
|
||||
pub use request::*;
|
24
lazy-supplements-desktop/src/ipc/message/request.rs
Normal file
24
lazy-supplements-desktop/src/ipc/message/request.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
use lazy_supplements_core::global::generate_uuid;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Request {
|
||||
pub id: Uuid,
|
||||
pub content: RequestContent,
|
||||
}
|
||||
|
||||
impl From<RequestContent> for Request {
|
||||
fn from(c: RequestContent) -> Self {
|
||||
Self{
|
||||
id: generate_uuid(),
|
||||
content: c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub enum RequestContent {
|
||||
Ping,
|
||||
ListPeers,
|
||||
}
|
27
lazy-supplements-desktop/src/ipc/message/response.rs
Normal file
27
lazy-supplements-desktop/src/ipc/message/response.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
use lazy_supplements_core::{
|
||||
global::generate_uuid,
|
||||
cache::entity::PeerModel,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Response {
|
||||
pub id: Uuid,
|
||||
pub content: ResponseContent,
|
||||
}
|
||||
|
||||
impl From<ResponseContent> for Response {
|
||||
fn from(c: ResponseContent) -> Self {
|
||||
Self{
|
||||
id: generate_uuid(),
|
||||
content: c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub enum ResponseContent {
|
||||
Pong,
|
||||
ListPeers(Vec<PeerModel>)
|
||||
}
|
3
lazy-supplements-desktop/src/ipc/mod.rs
Normal file
3
lazy-supplements-desktop/src/ipc/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub mod client;
|
||||
pub mod server;
|
||||
pub mod message;
|
11
lazy-supplements-desktop/src/ipc/server/mod.rs
Normal file
11
lazy-supplements-desktop/src/ipc/server/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
#[cfg(unix)]
|
||||
pub mod unix;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub mod windows;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use unix::*;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub use windows::*;
|
69
lazy-supplements-desktop/src/ipc/server/unix.rs
Normal file
69
lazy-supplements-desktop/src/ipc/server/unix.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
use std::{collections::VecDeque, path::Path, sync::Arc};
|
||||
|
||||
use lazy_supplements_core::error::Error;
|
||||
use tokio::{io::Interest, net::UnixStream, sync::Mutex};
|
||||
|
||||
use crate::ipc::message::{RequestContent, Response, ResponseContent};
|
||||
|
||||
pub async fn listen<T>(path: T) -> Result<(), Error>
|
||||
where T: AsRef<Path> {
|
||||
let stream = UnixStream::connect(path).await?;
|
||||
let write_que: Arc<Mutex<VecDeque<Vec<u8>>>> = Arc::new(Mutex::new(VecDeque::new()));
|
||||
let mut write_next: Option<Vec<u8>> = None;
|
||||
loop {
|
||||
let ready = stream.ready(Interest::READABLE).await?;
|
||||
if ready.is_readable() {
|
||||
let mut data = Vec::new();
|
||||
match stream.try_read(&mut data) {
|
||||
Ok(x) => {
|
||||
println!("read {} bytes", x)
|
||||
}
|
||||
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
|
||||
continue;
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e.into())
|
||||
}
|
||||
}
|
||||
let write_que2 = write_que.clone();
|
||||
tokio::spawn( async move {
|
||||
let mut buf = Vec::new();
|
||||
let request: crate::ipc::message::Request = ciborium::from_reader_with_buffer(data.as_slice(), &mut buf).unwrap();
|
||||
let response_id = request.id;
|
||||
let response_content: ResponseContent = match request.content {
|
||||
RequestContent::Ping => {
|
||||
ResponseContent::Pong
|
||||
}
|
||||
RequestContent::ListPeers => todo!(),
|
||||
};
|
||||
let mut response_buf = Vec::new();
|
||||
if let Err(e) = ciborium::into_writer(&Response{
|
||||
id: response_id,
|
||||
content: response_content,
|
||||
}, &mut response_buf) {
|
||||
todo!();
|
||||
};
|
||||
let mut que = write_que2.lock().await;
|
||||
que.push_back(response_buf);
|
||||
|
||||
});
|
||||
} else if ready.is_writable() {
|
||||
if let Some(x) = write_next.take() {
|
||||
|
||||
match stream.try_write(&x) {
|
||||
Ok(x) => {
|
||||
println!("write {} bytes", x)
|
||||
}
|
||||
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
|
||||
continue;
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut locked_que = write_que.lock().await;
|
||||
write_next = locked_que.pop_front();
|
||||
}
|
||||
}
|
0
lazy-supplements-desktop/src/ipc/server/windows.rs
Normal file
0
lazy-supplements-desktop/src/ipc/server/windows.rs
Normal file
|
@ -1,8 +1,9 @@
|
|||
pub mod cli;
|
||||
pub mod error;
|
||||
pub mod global;
|
||||
pub mod ipc;
|
||||
pub use lazy_supplements_core::{
|
||||
cache,
|
||||
config,
|
||||
data,
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue