A local-first private AI assistant for everyday use. Runs on-device models with encrypted P2P sync, and supports sharing chats publicly on ATProto.
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: using channel instead of manual ctrl-c to exit sync process

madclaws c51d58da 337f43bf

+14 -11
+1 -1
tiles/src/core/chats.rs
··· 19 19 use uuid::Uuid; 20 20 // model the chats table 21 21 22 - // TODO: foreign types on foreign traits, lul 22 + // Foreign types on foreign traits, lul 23 23 // someday we can do this for traits sake 24 24 // https://dev.to/iprosk/generics-in-rust-murky-waters-of-implementing-foreign-traits-on-foreign-types-584n 25 25
+13 -7
tiles/src/core/network/mod.rs
··· 30 30 get_did_from_public_key, get_public_key_from_did, get_random_bytes, get_random_bytes_32, 31 31 }; 32 32 use tokio::{ 33 - sync::{mpsc::Sender, oneshot}, 33 + sync::{ 34 + mpsc::{self, Sender}, 35 + oneshot::{self}, 36 + }, 34 37 task::spawn_blocking, 35 38 }; 36 39 use uuid::Uuid; ··· 340 343 store: MemStore, 341 344 endpoint: Endpoint, 342 345 sync_channel_sender: Sender<SyncOp>, 346 + sync_main_sender: tokio::sync::mpsc::Sender<u8>, 343 347 ) -> Result<()> { 344 348 while let Some(event) = receiver.try_next().await? { 345 349 info!( ··· 387 391 .await?; 388 392 } 389 393 MessageBody::SyncEnd => { 390 - println!("Sync completed..., you can exit now"); 394 + println!("Sync completed..., exiting.."); 395 + sync_main_sender.send(0).await?; 391 396 } 392 397 msg_body => { 393 398 info!("Invalid sync message {:?}", msg_body) ··· 427 432 let mdns = address_lookup::mdns::MdnsAddressLookup::builder().build(endpoint.id())?; 428 433 endpoint.address_lookup()?.add(mdns.clone()); 429 434 } 430 - 435 + let (sendx, mut recvx) = mpsc::channel(1); 431 436 let tx = create_sync_channel(); 432 437 if let Some(receiver_did) = did { 433 438 // INITIATOR BLOCK ··· 462 467 store, 463 468 endpoint.clone(), 464 469 tx.clone(), 470 + sendx.clone(), 465 471 )); 466 472 467 473 let receiver_last_row_counter = fetch_last_row_counter(&receiver_did, &tx).await?; ··· 479 485 "\nSyncing in progress with ....{}({})", 480 486 receiver_user.username, receiver_did 481 487 ); 482 - tokio::signal::ctrl_c().await?; 488 + recvx.recv().await; 483 489 recv_router.shutdown().await?; 484 490 } else { 485 491 // RECEIVER BLOCK ··· 506 512 store, 507 513 endpoint.clone(), 508 514 tx.clone(), 515 + sendx.clone(), 509 516 )); 510 517 println!("{}", "Ready to accept sync requests from peers...".blue()); 511 518 ··· 514 521 // for the network to form correctly 515 522 if cfg!(debug_assertions) { 516 523 println!("Use this DID {} in dev for testing", did); 517 - } 518 - tokio::signal::ctrl_c().await?; 524 + }; 525 + recvx.recv().await; 519 526 recv_router.shutdown().await?; 520 527 } 521 528 endpoint.close().await; ··· 754 761 delta: data.to_vec(), 755 762 resp: sendx, 756 763 }; 757 - 758 764 sync_channel_sender.send(sync_op_msg).await?; 759 765 760 766 recvx.await??;
-1
tiles/src/core/network/ticket.rs
··· 5 5 use iroh_gossip::TopicId; 6 6 use iroh_tickets::Ticket; 7 7 8 - //TODO: Add tests 9 8 #[derive(serde::Serialize, serde::Deserialize, Debug)] 10 9 pub struct LinkTicket { 11 10 pub nickname: String,
-2
tiles/src/core/storage/db.rs
··· 26 26 27 27 // DEFINE MIGRATIONS 28 28 29 - // TODO: add the schema doc 30 29 const COMMON_MIGRATION_ARRAY: &[M] = &[M::up( 31 30 " 32 31 CREATE TABLE IF NOT EXISTS users ( ··· 45 44 46 45 const COMMON_MIGRATIONS: Migrations = Migrations::from_slice(COMMON_MIGRATION_ARRAY); 47 46 48 - // TODO: add the schema doc 49 47 const CHATS_MIGRATION_ARRAY: &[M] = &[ 50 48 M::up( 51 49 "CREATE TABLE IF NOT EXISTS chats (