chore: initial commit
This commit is contained in:
12
crates/server/src/systems/database.rs
Normal file
12
crates/server/src/systems/database.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::components::*;
|
||||
|
||||
/// System: Poll chat.db for new messages using Bevy's task system
|
||||
pub fn poll_chat_db(
|
||||
_config: Res<AppConfig>,
|
||||
_db: Res<Database>,
|
||||
) {
|
||||
// TODO: Use Bevy's AsyncComputeTaskPool to poll chat.db
|
||||
// This will replace the tokio::spawn chat poller
|
||||
}
|
||||
116
crates/server/src/systems/gossip.rs
Normal file
116
crates/server/src/systems/gossip.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
use bevy::prelude::*;
|
||||
use parking_lot::Mutex;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::components::*;
|
||||
|
||||
/// System: Poll the gossip init task and insert resources when complete
|
||||
pub fn poll_gossip_init(
|
||||
mut commands: Commands,
|
||||
mut init_task: Option<ResMut<GossipInitTask>>,
|
||||
) {
|
||||
if let Some(mut task) = init_task {
|
||||
// Check if the task is finished (non-blocking)
|
||||
if let Some(result) = bevy::tasks::block_on(bevy::tasks::futures_lite::future::poll_once(&mut task.0)) {
|
||||
if let Some((endpoint, gossip, router, sender, receiver)) = result {
|
||||
println!("Inserting gossip resources");
|
||||
|
||||
// Insert all the resources
|
||||
commands.insert_resource(IrohEndpoint {
|
||||
endpoint,
|
||||
node_id: "TODO".to_string(), // TODO: Figure out how to get node_id in iroh 0.95
|
||||
});
|
||||
commands.insert_resource(IrohGossipHandle { gossip });
|
||||
commands.insert_resource(IrohRouter { router });
|
||||
commands.insert_resource(IrohGossipSender {
|
||||
sender: Arc::new(Mutex::new(sender)),
|
||||
});
|
||||
commands.insert_resource(IrohGossipReceiver {
|
||||
receiver: Arc::new(Mutex::new(receiver)),
|
||||
});
|
||||
|
||||
// Remove the init task
|
||||
commands.remove_resource::<GossipInitTask>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// System: Detect new messages in SQLite that need to be published to gossip
|
||||
pub fn detect_new_messages(
|
||||
_db: Res<Database>,
|
||||
_last_synced: Local<i64>,
|
||||
_publish_events: MessageWriter<PublishMessageEvent>,
|
||||
) {
|
||||
// TODO: Query SQLite for messages with rowid > last_synced
|
||||
// When we detect new messages, we'll send PublishMessageEvent
|
||||
}
|
||||
|
||||
/// System: Publish messages to gossip when PublishMessageEvent is triggered
|
||||
pub fn publish_to_gossip(
|
||||
mut events: MessageReader<PublishMessageEvent>,
|
||||
sender: Option<Res<IrohGossipSender>>,
|
||||
endpoint: Option<Res<IrohEndpoint>>,
|
||||
) {
|
||||
if sender.is_none() || endpoint.is_none() {
|
||||
// Gossip not initialized yet, skip
|
||||
return;
|
||||
}
|
||||
|
||||
let sender = sender.unwrap();
|
||||
let endpoint = endpoint.unwrap();
|
||||
|
||||
for event in events.read() {
|
||||
println!("Publishing message {} to gossip", event.message.rowid);
|
||||
|
||||
// Create sync message
|
||||
let sync_message = SyncMessage {
|
||||
message: event.message.clone(),
|
||||
sync_timestamp: chrono::Utc::now().timestamp(),
|
||||
publisher_node_id: endpoint.node_id.clone(),
|
||||
};
|
||||
|
||||
// Serialize the message
|
||||
match serialize_sync_message(&sync_message) {
|
||||
Ok(bytes) => {
|
||||
// TODO: Publish to gossip
|
||||
// For now, just log that we would publish
|
||||
println!("Would publish {} bytes to gossip", bytes.len());
|
||||
|
||||
// Note: Direct async broadcasting from Bevy systems is tricky due to Sync requirements
|
||||
// We'll need to use a different approach, possibly with channels or a dedicated task
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to serialize sync message: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// System: Receive messages from gossip
|
||||
pub fn receive_from_gossip(
|
||||
mut _gossip_events: MessageWriter<GossipMessageReceived>,
|
||||
receiver: Option<Res<IrohGossipReceiver>>,
|
||||
) {
|
||||
if receiver.is_none() {
|
||||
// Gossip not initialized yet, skip
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Implement proper async message reception
|
||||
// This will require spawning a long-running task that listens for gossip events
|
||||
// and sends them as Bevy messages. For now, this is a placeholder.
|
||||
}
|
||||
|
||||
/// System: Save received gossip messages to SQLite
|
||||
pub fn save_gossip_messages(
|
||||
mut events: MessageReader<GossipMessageReceived>,
|
||||
_db: Res<Database>,
|
||||
) {
|
||||
for event in events.read() {
|
||||
println!("Received message {} from gossip (published by {})",
|
||||
event.sync_message.message.rowid,
|
||||
event.sync_message.publisher_node_id);
|
||||
// TODO: Save to SQLite if we don't already have it
|
||||
}
|
||||
}
|
||||
7
crates/server/src/systems/mod.rs
Normal file
7
crates/server/src/systems/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
pub mod database;
|
||||
pub mod gossip;
|
||||
pub mod setup;
|
||||
|
||||
pub use database::*;
|
||||
pub use gossip::*;
|
||||
pub use setup::*;
|
||||
22
crates/server/src/systems/setup.rs
Normal file
22
crates/server/src/systems/setup.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use bevy::prelude::*;
|
||||
use bevy::tasks::AsyncComputeTaskPool;
|
||||
|
||||
use crate::components::*;
|
||||
|
||||
/// Startup system: Initialize database
|
||||
pub fn setup_database(_db: Res<Database>) {
|
||||
println!("Database resource initialized");
|
||||
}
|
||||
|
||||
/// Startup system: Initialize Iroh gossip
|
||||
pub fn setup_gossip(mut commands: Commands, topic: Res<GossipTopic>) {
|
||||
println!("Setting up Iroh gossip for topic: {:?}", topic.0);
|
||||
|
||||
let topic_id = topic.0;
|
||||
|
||||
// TODO: Initialize gossip properly
|
||||
// For now, skip async initialization due to Sync requirements in Bevy tasks
|
||||
// We'll need to use a different initialization strategy
|
||||
|
||||
println!("Gossip initialization skipped (TODO: implement proper async init)");
|
||||
}
|
||||
Reference in New Issue
Block a user