Skip to content
This repository has been archived by the owner on Aug 1, 2022. It is now read-only.

feat(proxy): waiting room requests #903

Merged
merged 64 commits into from Sep 24, 2020
Merged

Conversation

FintanH
Copy link
Contributor

@FintanH FintanH commented Sep 15, 2020

🚧 Under Construction 🚧

  • Use real PeerId
  • Use the real Repo
  • Test next under different strategies
  • Consider pushing the intermediate Requested states, i.e. Found, Cloning, and Cloned into a type parameter as well ala this pattern
  • De/serialise implementations
  • Docs

Part of ##803

@FintanH FintanH added proxy feature Something that doesn't exist yet labels Sep 15, 2020
@FintanH FintanH added this to the β1 milestone Sep 15, 2020
@FintanH FintanH requested a review from xla September 15, 2020 10:35
@FintanH FintanH self-assigned this Sep 15, 2020
@xla xla added this to In progress in Project Tracking/Replication Sep 15, 2020
@xla xla removed this from In progress in Project Tracking/Replication Sep 15, 2020
@xla xla removed this from the β1 milestone Sep 15, 2020
Copy link
Contributor

@xla xla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dope! Had a first pass.

It seems there is still some gap when it comes to transition a request during clone attemtps, where the order would be: Found -> Cloning -> CloningFailed/TimedOut -> Cloning or Found -> Cloning -> Cloned. We want to make explicit when a request is being cloned to avoid scheduling it for anohter clone. Furthermore we should get our timeouts looked at, as we have the timeouts for a single operation and the terminal state of the request alltogether having timed out.

The dependency direction seems skewed with the waiting room depending on its super while being under the request module hierarchy. Maybe both request and waiting_room can be next to each other.

In its current form are we supporting repo requests for any repo not only projects? Or did I miss-understand the current imimplementation?

proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request/waiting_room.rs Outdated Show resolved Hide resolved
proxy/coco/src/request/waiting_room.rs Outdated Show resolved Hide resolved
proxy/coco/src/request/waiting_room.rs Outdated Show resolved Hide resolved
@NunoAlexandre
Copy link
Contributor

Would love to review this once ready 💯

@xla xla changed the title feat(proxy): waiting room requests [WIP] feat(proxy): waiting room requests Sep 15, 2020
A request is modeled as the data it needs to fulfill a request and the
metadata that it encounters along its journey. We use a PhantomData
marker to ensure that transitions between our states are valid.

The waiting room is then modeled as a collection of these requests keyed
by their RadUrn. The error handling is done within the waiting room
since it needs to hide away what kind of request we had.

There's a single happy path test to get us going.
Moving the waiting room into its own module to separate the boundary
that it's a separate entity to request.

This makes it easier to define the Error types locally and replace the
() errors with these domain specific errors.
We add a Strategy enum so that the caller can pick which kind of
strategy they want when selecting the next Request in a Created state.
We introduce the intermediate states, Found, Cloning, and Cloned at the
type level so that we have more fine grained transitions. This means we
can't have just PhantomData as the state.

This introduces those changes and transitions while fixing the
end-to-end test.

However, there is still work to be done on the business logic that
happens at each state and when we need to transition to a failure state
such as canceled or timed out.
@FintanH FintanH force-pushed the fintan/tracking-notifications branch from cca8c44 to e0aebfd Compare September 15, 2020 17:11
We make more transitions explicit between request states and allow to go
back to previous states. We also keep track of how a clone went for a
given PeerId.

Left some inline comments as reminder for what's next.
We capture shared functionality: Having peers and be able to cancel a
request, and we organise them in traits. This allows us to give
instances of these traits to the states that they are relevant for. This
then means we can write generic transitions for Request.

Since these traits are very particular they are sealed by this module.
We have some cases where it's easy to define the functions over a list
of states.

We also clean up some of the functionality and code.
The code is easier to browse if we split the state and the existential
code into sub-modules.
Copy link
Contributor

@xla xla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀

proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request.rs Outdated Show resolved Hide resolved
proxy/coco/src/request.rs Show resolved Hide resolved
Using deriving for Serialize and Deserialize for all the types so that
we can ultimately serialize and deserialize a WaitingRoom.
Since I clearly made a mistake that was caught in code review, I won't
let it happen again. It shall be caught at compile time! usize no more,
only Queries and Clones!
While it is weird, the caller of the waiting room/request API has to
hold themselves accountable in this case. If they say a peer failed then
we mark it as failed, whether it existed in the map or not.
Introducing a method that checks the elapsed time between a request and
provided timestamp.
@FintanH FintanH mentioned this pull request Sep 23, 2020
We introduce a filter function that bases the filtering criteria off of
the RequestKind and the delta of elapsed time based on a provided
timestamp. This deprecates the next and ready functions.
xla
xla previously approved these changes Sep 23, 2020
Copy link
Contributor

@xla xla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♌️ 🎁 🕸 🏌

rudolfs
rudolfs previously approved these changes Sep 23, 2020
@FintanH FintanH dismissed stale reviews from rudolfs and xla via be18d37 September 23, 2020 16:53
xla
xla previously approved these changes Sep 23, 2020
Copy link
Contributor

@xla xla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(=´∀`)

NunoAlexandre
NunoAlexandre previously approved these changes Sep 23, 2020
Copy link
Contributor

@NunoAlexandre NunoAlexandre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work, @FintanH 👏

left some comments but wouldn't mind if you skip them.

Comment on lines +90 to +92
pub const fn urn(&self) -> &RadUrn {
&self.urn
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL on pub const

Out of curiosity, why having this getter instead of making urn public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be disastrous if a user could change the RadUrn of the request in the WaitingRoom. #eNcApSuLaTiOn

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would that require it to be mut?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, it would I believe.

proxy/coco/src/request.rs Show resolved Hide resolved
proxy/coco/src/request.rs Outdated Show resolved Hide resolved
Comment on lines +17 to +26
/// Since a `Request` is parameterised over its state, it makes it difficult to talk about a
/// `Request` in general without the compiler complaining at us. For example, we cannot have
/// something like `vec![created, requested, cloning, timedout]` since they all have distinct types
/// where they differ in states.
///
/// To allow us to do this we unify all the states into `SomeRequest` where each state is a variant
/// in the enumeration.
///
/// When we pattern match we get back the request parameterised over the specific state and can
/// work in a type safe manner with this request.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice docs 👌

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merci :flag-fr:

}
}

impl<T, L: Into<SomeRequest<T>>, R: Into<SomeRequest<T>>> From<Either<L, R>> for SomeRequest<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 📖 📓

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you like some explanation? :)

/// An enumeration of the different states a `Request` can be in. This is useful if we want to
/// convey the state information without any of the other state data.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum RequestKind {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub enum RequestKind {
pub enum RequestState {

would be truer to its meaning and purpose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, I'm in agreement with this 👍

proxy/coco/src/request/states.rs Outdated Show resolved Hide resolved
proxy/coco/src/request/states.rs Show resolved Hide resolved
Comment on lines +190 to +194
impl AddAssign<usize> for Queries {
fn add_assign(&mut self, other: usize) {
*self = Self(self.0 + other)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😎

rudolfs
rudolfs previously approved these changes Sep 24, 2020
Co-authored-by: Nuno Alexandre <hi@nunoalexandre.com>
@FintanH FintanH dismissed stale reviews from rudolfs, NunoAlexandre, and xla via 474211d September 24, 2020 08:40
Copy link
Contributor

@NunoAlexandre NunoAlexandre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

Copy link
Contributor

@xla xla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕓 ⚔ 🍻 🌙

@FintanH FintanH merged commit cc1834b into master Sep 24, 2020
@FintanH FintanH deleted the fintan/tracking-notifications branch September 24, 2020 09:07
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature Something that doesn't exist yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants