Better model messages

main
~erin 2023-04-20 18:39:00 -04:00
parent d11d256761
commit 98369c00bd
Signed by untrusted user: erin
GPG Key ID: 9A8E308CEFA37A47
1 changed files with 38 additions and 8 deletions

View File

@ -14,7 +14,7 @@ It reduces work of implementation, and all implementations can use the functions
```rust ```rust
// Different possible types of actors (more to be added) // Different possible types of actors (more to be added)
enum ActorType { enum ActorType {
GUI(Widget), GUI(photon::Widget),
ProgramInterface, ProgramInterface,
} }
@ -62,19 +62,24 @@ impl Actor {
} }
impl KeyPair { impl KeyPair {
fn generate_keypair(&mut self) -> Self; async fn generate_keypair(&mut self) -> Self; // Generate a public/private keypair (threaded)
fn get_pubkey(&self) -> u128; fn get_pubkey(&self) -> u128; // Return the keypair of an Actor
fn sign(&self, &[u8]) -> Result<&[u8], Error>; async fn sign(&self, &[u8]) -> Result<&[u8], Error>; // Sign some data with a private key (threaded)
fn verify_signature(&[u8], u128) -> Result<(), Error>; async fn verify_signature(&[u8], u128) -> Result<(), Error>; // Verify signed data (threaded)
} }
trait FilesystemInterface { // Interfacing with the filesystem trait FilesystemInterface { // Interfacing with the filesystem
fn read(&mut self) -> Result<(), Error>; // Read the data from the disk into the Actor using the Uuid as a search key async fn read(&mut self) -> Result<(), Error>; // Read the data from the disk into the Actor using the Uuid as a search key
fn write(&self) -> Result<(), Error>; // Write the data to the disk using the Uuid as a key async fn write(&self) -> Result<(), Error>; // Write the data to the disk using the Uuid as a key
} }
trait DataInterface { // Necessary data functions trait DataInterface { // Necessary data functions
fn to_bytes(&self) -> Result<&[u8], Error>; // Convert the data into a byte array async fn to_bytes(&self) -> Result<&[u8], Error>; // Convert the data into a byte array
}
trait MessageInterface { // Sending & receiving messages
async fn send_message(&self, MessageType, Uuid) -> Result<(), Error>; // Send a message to a recipient
async fn receive_message(&self, Channel) -> Message; // Asynchronously wait for an incoming message, and deal with the first one we get
} }
``` ```
@ -85,7 +90,20 @@ trait DataInterface { // Necessary data functions
- [postcard](https://lib.rs/crates/postcard) for message passing - [postcard](https://lib.rs/crates/postcard) for message passing
- Priority Queue for processing multiple messages, while dealing with higher-priority ones first - Priority Queue for processing multiple messages, while dealing with higher-priority ones first
Messages will be fully modelled so an actor can know *exactly* what they have to deal with, and what they can send.
Different channels are used to make each one less clogged up, and used only for a specific purpose.
Actors can read from/write to a specific channel, allowing them to ignore the others.
They can then also deal with channels in different ways, maybe deprioritizing the `Test` channel.
```rust ```rust
enum Channel { // Channels for sending/receiving messages on
Graphics, // Low-latency graphics updates
Test, // Designated channel for testing messages
Filesystem, // Batch filesystem operations
Print, // Printing text
Executable, // Executable-related messages
}
enum ProcessCode { enum ProcessCode {
Exit, // Exit the process Exit, // Exit the process
Save, // Save data Save, // Save data
@ -102,6 +120,7 @@ enum MessageType {
} }
struct Message { struct Message {
id: Uuid, // UUID of the message itself
m_type: MessageType, // Message type & content m_type: MessageType, // Message type & content
priority: u8, // For priority queueing priority: u8, // For priority queueing
sender: Uuid, // Who is sending the message sender: Uuid, // Who is sending the message
@ -109,4 +128,15 @@ struct Message {
} }
``` ```
An example message handling loop may look like this:
```rust
loop { // Continuously loop through message sending & receiving
actor.send_message(MessageType::Ping("hello!".to_string())).await; // Block and await until we can send the test message.
match actor.receive_message(&self, Channel::Test).await.m_type { // Match on a message type
Ping(s) => println!("We got pinged! {}", s), // Print if we got pinged
_ => {}, // Ignore other states
}
}
```
### Latency ### Latency