pub struct Manager { /* private fields */ }
Expand description
Implementations§
source§impl Manager
impl Manager
sourcepub fn new(
persistent: bool,
help_desire: i16,
log_lifetime: Duration,
event_log_limit: u32,
) -> Self
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
.
sourcepub fn process_hello(&mut self) -> Message
pub fn process_hello(&mut self) -> Message
Creates a MessageKind::Hello
with the Capabilities
of this manager.
sourcepub fn process_event(&mut self, event: impl IntoEvent) -> Result<Message, Error>
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.
sourcepub fn process_event_log_check(&mut self, count: u32) -> Option<(Message, Uuid)>
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.
sourcepub fn process_event_log_check_reply(
&mut self,
event_log_check: Check,
conversation_uuid: Uuid,
) -> Message
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
.
sourcepub fn process_hash_check(
&mut self,
pier: SelectedPier,
) -> Result<Message, Error>
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
.
sourcepub fn process_hash_check_reply(&mut self, response: Response) -> Message
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
.
sourcepub fn process_sync(
&mut self,
request: Request,
metadata_changes: Option<Vec<MetadataChange>>,
) -> Message
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.
sourcepub fn process_sync_reply(&mut self, response: Response) -> Message
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.
sourcepub fn process_fast_forward(&mut self) -> Result<Option<Message>, Error>
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
.
sourcepub fn process_fast_forward_response(
&mut self,
public_metadata: Metadata,
pier: Uuid,
) -> Message
pub fn process_fast_forward_response( &mut self, public_metadata: Metadata, pier: Uuid, ) -> Message
The public_metadata
is the metadata of the public storage.
sourcepub fn process_disconnect(&mut self) -> Message
pub fn process_disconnect(&mut self) -> Message
Create a disconnect message.
sourcepub fn apply_hello(&mut self, hello: &Capabilities) -> Message
pub fn apply_hello(&mut self, hello: &Capabilities) -> Message
Handles an incoming MessageKind::Hello
.
Immediately send the returned message.
sourcepub fn apply_welcome(&mut self, welcome: Capabilities)
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.
sourcepub fn apply_event<'a>(
&'a mut self,
event: &'a Event,
message_uuid: Uuid,
) -> Result<EventApplier<'a>, Error>
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!
sourcepub fn apply_event_uuid_log_check(
&mut self,
check: LogCheck,
conversation_uuid: Uuid,
sender: Uuid,
) -> LogCheckAction
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.
sourcepub fn apply_log_check_reply(
&mut self,
check: LogCheck,
conversation_uuid: Uuid,
sender: Uuid,
)
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
.
sourcepub fn clean_log_checks(&mut self)
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.
sourcepub fn assure_log_check(
&mut self,
conversation_uuid: Uuid,
) -> Option<SelectedPier>
pub fn assure_log_check( &mut self, conversation_uuid: Uuid, ) -> Option<SelectedPier>
sourcepub fn apply_hash_check(
&self,
check: Request,
sender: Uuid,
) -> ResponseBuilder<'_>
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
.
sourcepub fn apply_hash_check_reply(
&mut self,
response: &Response,
sender: Uuid,
our_hashes: &BTreeMap<String, ResponseHash>,
) -> Result<(Option<(RequestBuilder, Vec<String>)>, Vec<String>), Error>
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.
sourcepub fn apply_sync<'a>(
&'a self,
request: &'a Request,
sender: Uuid,
) -> ResponseBuilder<'a>
pub fn apply_sync<'a>( &'a self, request: &'a Request, sender: Uuid, ) -> ResponseBuilder<'a>
Creates a builder used to construct a sync response.
sourcepub fn apply_sync_reply<'a>(
&'a mut self,
response: &mut Response,
sender: Uuid,
) -> Result<SyncReplyAction<'a>, Error>
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.
sourcepub fn apply_fast_forward_reply(
&mut self,
reply: Response,
sender: Uuid,
) -> Result<RequestBuilder, Error>
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.
sourcepub fn apply_disconnect(&mut self, sender: Uuid)
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.
sourcepub fn apply_cancelled(&mut self, sender: Uuid) -> CancelAction
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
impl Manager
sourcepub fn rng(&self) -> impl DerefMut<Target = impl Rng> + '_
pub fn rng(&self) -> impl DerefMut<Target = impl Rng> + '_
Get the random number generator of this manager.
sourcepub fn generate_uuid(&mut self) -> Uuid
pub fn generate_uuid(&mut self) -> Uuid
Generates a UUID using the internal rand::Rng
.
sourcepub fn capabilities(&self) -> &Capabilities
pub fn capabilities(&self) -> &Capabilities
Get a reference to this manager’s capabilities.
sourcepub fn event_log_limit(&self) -> u32
pub fn event_log_limit(&self) -> u32
The max capacity of the internal event log.
Useful when calling Manager::process_event_log_check
.
sourcepub fn pier_count(&self) -> usize
pub fn pier_count(&self) -> usize
The number of piers we know of.
sourcepub fn client_count(&self) -> usize
pub fn client_count(&self) -> usize
The number of clients we know of.
Self::pier_count
+ 1 (ourself)
sourcepub fn modern_resource_name<'a>(
&self,
old_name: &'a str,
timestamp: SystemTime,
) -> Option<&'a str>
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.
sourcepub fn unwinder_to(&self, timestamp: SystemTime) -> Unwinder<'_>
pub fn unwinder_to(&self, timestamp: SystemTime) -> Unwinder<'_>
Get an event::Unwinder
to unwind a resource to timestamp
.
sourcepub fn rewind_from_last_commit(&self) -> Rewinder<'_>
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.
sourcepub fn last_commit(&self) -> Option<SystemTime>
pub fn last_commit(&self) -> Option<SystemTime>
Get the time of the last call to Self::update_last_commit
.
sourcepub fn last_commit_or_epoch(&self) -> SystemTime
pub fn last_commit_or_epoch(&self) -> SystemTime
The last commit or SystemTime::UNIX_EPOCH
.
sourcepub fn update_last_commit(&mut self)
pub fn update_last_commit(&mut self)
Update the inner timestamp of the last commit.
See Self::rewind_from_last_commit
for more details.
sourcepub fn set_last_commit(&mut self, timestamp: SystemTime)
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).
sourcepub fn is_fast_forwarding(&self) -> bool
pub fn is_fast_forwarding(&self) -> bool
Returns true if we are in a fast forward. You shouldn’t commit under these circumstances.
sourcepub fn last_change_to_resource(&self, resource: &str) -> SystemTime
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.
sourcepub fn hash_check_persistent(&mut self) -> Option<SelectedPier>
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.
sourcepub fn hash_checking(&self) -> Option<Uuid>
pub fn hash_checking(&self) -> Option<Uuid>
Returns the pier we’re currently asking to check our resource’s hashes against.
sourcepub fn filter_piers<'a>(
&'a self,
filter: impl FnMut(Uuid, &Capabilities) -> bool + 'a,
) -> impl Iterator<Item = (Uuid, &'a Capabilities)>
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
.