Compare commits
	
		
			4 commits
		
	
	
		
			e70be2c638
			...
			98369c00bd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 98369c00bd | |||
| d11d256761 | |||
| 1389ca88cf | |||
| a3635a465f | 
					 3 changed files with 134 additions and 3 deletions
				
			
		|  | @ -5,7 +5,7 @@ | ||||||
| # Developer Guide | # Developer Guide | ||||||
| - [Development](development/README.md) | - [Development](development/README.md) | ||||||
|     - [Understanding the Design Goals](development/design/README.md) |     - [Understanding the Design Goals](development/design/README.md) | ||||||
|         - [Actor System]() |         - [Actor System](development/design/actor.md) | ||||||
|         - [Security Features](development/design/security.md) |         - [Security Features](development/design/security.md) | ||||||
|         - [Microkernel](development/design/kernel.md) |         - [Microkernel](development/design/kernel.md) | ||||||
|         - [GUI](development/design/gui.md) |         - [GUI](development/design/gui.md) | ||||||
|  |  | ||||||
|  | @ -1,11 +1,142 @@ | ||||||
| # Actor System | # Actor System | ||||||
|  | ```admonish question title="Why?" | ||||||
|  | **Actors** work as an abstraction over data storage and messaging. | ||||||
|  | It allows for all systems *(GUI, Programs, etc.)* to work together, and rely on the same features. | ||||||
|  | It reduces work of implementation, and all implementations can use the functions. | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Features | ||||||
|  | - Petnames | ||||||
|  | - **OCAP** security | ||||||
|  | - **HMAC** message verification | ||||||
|  | 
 | ||||||
|  | ## Format | ||||||
|  | ```rust | ||||||
|  | // Different possible types of actors (more to be added) | ||||||
|  | enum ActorType { | ||||||
|  |     GUI(photon::Widget), | ||||||
|  |     ProgramInterface, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Possible states an actor can be in | ||||||
|  | enum ActorState { | ||||||
|  |     Receive, | ||||||
|  |     Send, | ||||||
|  |     Work, | ||||||
|  |     Idle, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Cryptographic keypair | ||||||
|  | struct KeyPair { | ||||||
|  |     privkey: u128, | ||||||
|  |     pubkey: u128, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // The actor itself | ||||||
|  | struct Actor<D: DataInterface> { | ||||||
|  |     petname: Option<String>, // Human-meaningful petname (explored further down) | ||||||
|  |     uuid: Uuid, // Unique identifier | ||||||
|  |     namespace: Uuid, // Parent namespace of this actor | ||||||
|  |     actor_type: ActorType, | ||||||
|  |     state: ActorState, | ||||||
|  |     keys: Option<KeyPair>, // Cryptographic keypair | ||||||
|  |     creation_date: DateTime, | ||||||
|  |     modified_date: DateTime, | ||||||
|  |     data: Option<D>, // Optional data of the generic D type | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Actor { | ||||||
|  |     fn new(namespace: Uuid, a_type: ActorType) -> Self { | ||||||
|  |         Actor { | ||||||
|  |             petname: None, | ||||||
|  |             uuid: Uuid::new(), | ||||||
|  |             namespace: namespace, | ||||||
|  |             actor_type: a_type, | ||||||
|  |             state: ActorState::Idle, | ||||||
|  |             keys: None, | ||||||
|  |             creation_date:: now(), | ||||||
|  |             modified_date: now(), | ||||||
|  |             data: None, | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl KeyPair { | ||||||
|  |     async fn generate_keypair(&mut self) -> Self; // Generate a public/private keypair (threaded) | ||||||
|  |     fn get_pubkey(&self) -> u128; // Return the keypair of an Actor | ||||||
|  |     async fn sign(&self, &[u8]) -> Result<&[u8], Error>; // Sign some data with a private key (threaded) | ||||||
|  |     async fn verify_signature(&[u8], u128) -> Result<(), Error>; // Verify signed data (threaded) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | trait FilesystemInterface { // Interfacing with the filesystem | ||||||
|  |     async fn read(&mut self) -> Result<(), Error>; // Read the data from the disk into the Actor using the Uuid as a search key | ||||||
|  |     async fn write(&self) -> Result<(), Error>; // Write the data to the disk using the Uuid as a key | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | trait DataInterface { // Necessary data functions | ||||||
|  |     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 | ||||||
|  | } | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| ## OCAP | ## OCAP | ||||||
| **TODO** | **TODO** | ||||||
| 
 | 
 | ||||||
| ## Messages | ## Messages | ||||||
| **TODO** |  | ||||||
| - [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 | ||||||
|  | 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 { | ||||||
|  |     Exit, // Exit the process | ||||||
|  |     Save, // Save data | ||||||
|  |     Clear, // Clear data | ||||||
|  |     Restart, // Restart process | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | enum MessageType { | ||||||
|  |     Ping(String), // Simple test if we can send/recieve a message | ||||||
|  |     FilesystemUpdate(gravitas::FileOperation), // We want to operate on the filesystem | ||||||
|  |     GraphicsUpdate(photon::GraphicsOperation), // Update a graphics window | ||||||
|  |     TextUpdate(String), // Send some text (text mode only) | ||||||
|  |     ProcessUpdate(ProcessCode), // Send some info about an operation to be done on the current process. Usually kernel -> exe | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct Message { | ||||||
|  |     id: Uuid, // UUID of the message itself | ||||||
|  |     m_type: MessageType, // Message type & content | ||||||
|  |     priority: u8, // For priority queueing | ||||||
|  |     sender: Uuid, // Who is sending the message | ||||||
|  |     recipient: Uuid, // Who the message is meant for | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
|  |  | ||||||
|  | @ -120,7 +120,7 @@ will be determined via [capabilities](/development/design/actor.md#ocap) | ||||||
| Created in-memory on startup, modified directly whenever the filesystem is modified. | Created in-memory on startup, modified directly whenever the filesystem is modified. | ||||||
| It's saved in the *Index Sector* (which is at a known offset), allowing it to be read in easily on boot. | It's saved in the *Index Sector* (which is at a known offset), allowing it to be read in easily on boot. | ||||||
| 
 | 
 | ||||||
| The index is simply an `alloc::` [BTreeMap](https://doc.rust-lang.org/stable/alloc/collections/btree_map/struct.BTreeMap.html). | The index is simply an `alloc::` [BTreeMap](https://doc.rust-lang.org/stable/alloc/collections/btree_map/struct.BTreeMap.html). *(If not, try [scapegoat](https://lib.rs/crates/scapegoat))*. | ||||||
| 
 | 
 | ||||||
| We also have a simple `Vec` of the chunks that are free, which we modify in reverse. | We also have a simple `Vec` of the chunks that are free, which we modify in reverse. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue