Compare commits
	
		
			No commits in common. "98369c00bdec049448deadced46e479ed5d83bc7" and "e70be2c63882bbd365600935f46cb250aceac9da" have entirely different histories.
		
	
	
		
			98369c00bd
			...
			e70be2c638
		
	
		
					 3 changed files with 3 additions and 134 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](development/design/actor.md) |         - [Actor System]() | ||||||
|         - [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,142 +1,11 @@ | ||||||
| # 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). *(If not, try [scapegoat](https://lib.rs/crates/scapegoat))*. | The index is simply an `alloc::` [BTreeMap](https://doc.rust-lang.org/stable/alloc/collections/btree_map/struct.BTreeMap.html). | ||||||
| 
 | 
 | ||||||
| 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