agde

Struct Manager

source
pub struct Manager { /* private fields */ }
Expand description

The main manager of a client.

The process_* methods are for creating Messages from internal data. The apply_* methods are for accepting and evaluating Messages.

Implementations§

source§

impl Manager

source

pub fn new( persistent: bool, help_desire: i16, log_lifetime: Duration, event_log_limit: u32, ) -> Self

Creates a empty manager.

Call Self::process_hello() to get a hello message.

The options are partially explained in Capabilities::new. I recommend a default of 60s for log_lifetime and 512 for event_log_limit.

source

pub fn process_hello(&mut self) -> Message

Creates a MessageKind::Hello with the Capabilities of this manager.

source

pub fn process_event(&mut self, event: impl IntoEvent) -> Result<Message, Error>

Takes a Event and returns a Message.

last_event_send is the timestamp of when you last sent messages. It’s used as the creation date for the changes, as all our changes are diffed to that point in time.

Be careful with EventKind::Modify as you NEED to have a EventKind::Create before it on the same resource.

§Errors

Returns fast_forward::Error::ExpectedNotRunning if Manager::is_fast_forwarding is true.

source

pub fn process_event_log_check(&mut self, count: u32) -> Option<(Message, Uuid)>

May return a message with it’s the number of events less than count.

count should be around 1/4 of the limit of the event UUID log to maximise profits for all piers on the network.

If there isn’t enough events in the log, this returns None.

This also returns the conversation UUID.

§Replies

After sending this, wait a few seconds and then run Self::assure_log_check which checks if you have the “correct” version.

When you call Self::apply_event_uuid_log_check, the manager notes the MessageKind::LogCheckReply messages.

§Memory leaks

You must call Self::assure_log_check after calling this.

source

pub fn process_event_log_check_reply( &mut self, event_log_check: Check, conversation_uuid: Uuid, ) -> Message

Get a message with the reply to a MessageKind::LogCheck.

source

pub fn process_hash_check( &mut self, pier: SelectedPier, ) -> Result<Message, Error>

Constructs a message with pier as a destination for a full hash check.

This is between event log check and sync to make sure our data is valid. Then, we don’t need to sync.

§Errors

Returns fast_forward::Error::ExpectedNotRunning if Self::is_fast_forwarding.

source

pub fn process_hash_check_reply(&mut self, response: Response) -> Message

Make a message from the hash_check::Response, created using hash_check::ResponseBuilder::finish.

The response is obtained from Self::apply_hash_check.

source

pub fn process_sync( &mut self, request: Request, metadata_changes: Option<Vec<MetadataChange>>, ) -> Message

You MUST pause the Self::apply_event between when the signature is created for sync::RequestBuilder::finish and when the sync::Response is applied.

When you receive the sync::Response, call the appropriate functions on it to apply data and Self::apply_sync_reply.

The metadata_changes are the changes from our main metadata to fast_forward::Response::metadata. It should be None when we’re not fast forwarding.

source

pub fn process_sync_reply(&mut self, response: Response) -> Message

Turn the sync response to a message.

This should be sent back to the pier which requested the sync.

source

pub fn process_fast_forward(&mut self) -> Result<Option<Message>, Error>

Returns None if we haven’t registered any piers which are willing to talk to us (they haven’t cancelled us).

§Errors

Returns fast_forward::Error::ExpectedNotRunning if Self::hash_checking() is Some.

source

pub fn process_fast_forward_response( &mut self, public_metadata: Metadata, pier: Uuid, ) -> Message

The public_metadata is the metadata of the public storage.

source

pub fn process_disconnect(&mut self) -> Message

Create a disconnect message.

source

pub fn apply_hello(&mut self, hello: &Capabilities) -> Message

Handles an incoming MessageKind::Hello. Immediately send the returned message.

source

pub fn apply_welcome(&mut self, welcome: Capabilities)

Records the Capabilities of the client.

This is later used to determine which pier to send certain requests to.

source

pub fn apply_event<'a>( &'a mut self, event: &'a Event, message_uuid: Uuid, ) -> Result<EventApplier<'a>, Error>

Applies event to this manager. You get back a log::EventApplier on which you should handle the events.

Please appropriately sanitize the event before calling this, as the event might try to modify unrelated files (if that’s what “resources” are implemented as).

§Errors

Fails if the event is more than 10s from the future.

This prevents other clients from hogging our memory with items which never expire. If their clock is more than 10s off relative to our, we have a serious problem!

source

pub fn apply_event_uuid_log_check( &mut self, check: LogCheck, conversation_uuid: Uuid, sender: Uuid, ) -> LogCheckAction

Handles a MessageKind::LogCheck. This will return an LogCheckAction which tells you what to do.

§Memory leaks

You must call Self::assure_log_check after calling this.

source

pub fn apply_log_check_reply( &mut self, check: LogCheck, conversation_uuid: Uuid, sender: Uuid, )

Apply a reply to the MessageKind::LogCheck. This tracks the check from sender to be used in the next Manager::assure_log_check.

source

pub fn clean_log_checks(&mut self)

Trims the memory usage of the cache used by Self::apply_event_uuid_log_check.

Call this maybe once per minute. This just checks modification timestamps, so it’s pretty fast.

This removes conversations not used by agde for 5 minutes. This is a implementation detail and can not be relied upon.

source

pub fn assure_log_check( &mut self, conversation_uuid: Uuid, ) -> Option<SelectedPier>

Assures you are using the “correct” version of the files. This return None if that’s the case. Otherwise returns an appropriate pier to get data from.

Also returns None if the conversation wasn’t found or no responses were sent.

This will clear the conversation with conversation_uuid.

source

pub fn apply_hash_check( &self, check: Request, sender: Uuid, ) -> ResponseBuilder<'_>

Use the hash_check::ResponseBuilder::unwinder before inserting any hashes.

For each resource which hash_check::Request::matches, execute hash_check::ResponseBuilder::insert. When all are inserted, run hash_check::ResponseBuilder::finish.

sender is the UUID of the pier who sent this, Message::sender.

source

pub fn apply_hash_check_reply( &mut self, response: &Response, sender: Uuid, our_hashes: &BTreeMap<String, ResponseHash>, ) -> Result<(Option<(RequestBuilder, Vec<String>)>, Vec<String>), Error>

If the returned sync::RequestBuilder is Some, loop over each resource in the Vec next to the RequestBuilder. Add all the [dach::Signature]s for the resources. Before creating the signatures, please unwind them using the hash_check::Response::unwinder. Run sync::RequestBuilder::finish once every [dach::Signature] has been added. Then, execute Self::process_sync with the sync::RequestBuilder. If it’s None, the data matches.

Delete all the resources in the returned Vec of String. Even if this doesn’t return a sync::RequestBuilder.

§Errors

Returns fast_forward::Error::ExpectedNotRunning if Manager::is_fast_forwarding is true. If sender isn’t the pier we decided to talk to, or if we haven’t initiated a conversation (Self::process_hash_check), fast_forward::Error::UnexpectedPier is returned.

source

pub fn apply_sync<'a>( &'a self, request: &'a Request, sender: Uuid, ) -> ResponseBuilder<'a>

Creates a builder used to construct a sync response.

source

pub fn apply_sync_reply<'a>( &'a mut self, response: &mut Response, sender: Uuid, ) -> Result<SyncReplyAction<'a>, Error>

Applies the event log of the sync reply.

You MUST also call the methods on sync::Response to actually make changes to the resources returned. This only handles the event log.

The event::Rewinder returned should be called for all modified resources.

You can be sure when calling Manager::process_fast_forward and Manager::process_hash_check that they won’t return state errors, as this guarantees the action returned can be ran, because it’s currently running.

§Errors

Returns fast_forward::Error::ExpectedWaitingForDiffs if we’re syncing non-fast forward data in a fast forward. Since Self::apply_event_uuid_log_check returns LogCheckAction::Nothing when trying to execute it when fast forwarding, this is an issue with you accepting a bad message.

source

pub fn apply_fast_forward_reply( &mut self, reply: Response, sender: Uuid, ) -> Result<RequestBuilder, Error>

Applies the fast forward reply by modifying the inner state.

You need to call fast_forward::Metadata::changes on reply and remove the removed files. You also need to pass the new and modified files to sync::RequestBuilder::insert.

§Errors

sender should match with the one provided by Manager::process_fast_forward. If the internal state doesn’t expect this to happen, it will also throw an error.

source

pub fn apply_disconnect(&mut self, sender: Uuid)

Handle a disconnect message.

You should make sure nobody can forge this message, as that could lead to blackmailing of piers.

source

pub fn apply_cancelled(&mut self, sender: Uuid) -> CancelAction

Accept a cancellation event from sender.

You can be sure when calling Manager::process_fast_forward and Manager::process_hash_check that they won’t return state errors, as this guarantees the action returned can be ran, because it’s currently running.

source§

impl Manager

source

pub fn uuid(&self) -> Uuid

Get the UUID of this client.

source

pub fn rng(&self) -> impl DerefMut<Target = impl Rng> + '_

Get the random number generator of this manager.

source

pub fn generate_uuid(&mut self) -> Uuid

Generates a UUID using the internal rand::Rng.

source

pub fn capabilities(&self) -> &Capabilities

Get a reference to this manager’s capabilities.

source

pub fn event_log_limit(&self) -> u32

The max capacity of the internal event log.

Useful when calling Manager::process_event_log_check.

source

pub fn pier_count(&self) -> usize

The number of piers we know of.

source

pub fn client_count(&self) -> usize

The number of clients we know of.

Self::pier_count + 1 (ourself)

source

pub fn modern_resource_name<'a>( &self, old_name: &'a str, timestamp: SystemTime, ) -> Option<&'a str>

Attempts to get the modern name of the resource named old_name at timestamp.

If old_name is valid, it’s returned.

source

pub fn unwinder_to(&self, timestamp: SystemTime) -> Unwinder<'_>

Get an event::Unwinder to unwind a resource to timestamp.

source

pub fn rewind_from_last_commit(&self) -> Rewinder<'_>

Get an event::Rewinder which can apply all the stored diffs received since the last data commit to a resource.

You have to call Self::update_last_commit after each “merge” - after each occurrence of diffing.

This is critical when rewinding the current storage before diffing it to the public storage to send an event. Use event::Rewinder::rewind on all the modified resources.

The event::Rewinder can be reused for several resources.

source

pub fn last_commit(&self) -> Option<SystemTime>

Get the time of the last call to Self::update_last_commit.

source

pub fn last_commit_or_epoch(&self) -> SystemTime

source

pub fn update_last_commit(&mut self)

Update the inner timestamp of the last commit.

See Self::rewind_from_last_commit for more details.

source

pub fn set_last_commit(&mut self, timestamp: SystemTime)

Set the time of the last commit. Should be used with care in rare circumstances (e.g. when fast forwarding).

source

pub fn is_fast_forwarding(&self) -> bool

Returns true if we are in a fast forward. You shouldn’t commit under these circumstances.

source

pub fn last_change_to_resource(&self, resource: &str) -> SystemTime

The timestamp of the latest change to resource.

Returns SystemTime::UNIX_EPOCH if no changes to resource are in the log, or if the resource doesn’t exist.

source

pub fn hash_check_persistent(&mut self) -> Option<SelectedPier>

Get the pier to use when starting a hash check. This should only be called if our Capabilities::persistent is set. If we’re a temporary client (read: not server), this isn’t needed.

Call Manager::process_hash_check with the returned SelectedPier. It is None if no other piers (which have not returned MessageKind::Cancelled) are in the network. If that’s the case, do nothing.

source

pub fn hash_checking(&self) -> Option<Uuid>

Returns the pier we’re currently asking to check our resource’s hashes against.

source

pub fn filter_piers<'a>( &'a self, filter: impl FnMut(Uuid, &Capabilities) -> bool + 'a, ) -> impl Iterator<Item = (Uuid, &'a Capabilities)>

Get an iterator of the piers filtered by filter.

If you need the number of piers, use Self::pier_count or Self::client_count.

Trait Implementations§

source§

impl Debug for Manager

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V