-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement logger adapter #239
base: master
Are you sure you want to change the base?
Conversation
Since the protocol specifies the use of 16 bit counters, it's best to reflect these in the API as well.
Turn arranging usize into u16
The expected index is a u16 at the protocol level, but the arranging implementation for orderingstream does not take this into account. This caused sending over 2**16 ordered packets to simply default to the `None` case and get ignored. This patch solves that issue.
Previously we would only store packets with indices higher than the expected index, this is obviously not going to give us good results when we receive packets 0..100 while we are currently expecting index 65500. What this patch does is that it stores all incoming packets with the condition: expected < index < expected + u16::max/2 With wrapping add this becomes slightly more complex but the gist is the same.
Fix ordering arranging handler for >65536 packets
The previous patches would erroneously skip the value 32767 and drop the next packet (32768). This patch and test ensures that this doesn't happen.
Sending over 65536 packets would previously just saturate the top_index which caused it to not accept any more packets. This patch shortens the sequence acceptance by half but always loops around the max u16 value. This means that at top_index = 0, all sequenced packets 0-32768 are accepted, while at top_index = 50000, all sequenced packets 50000-65535 and 0-17233 will be accepted.
…ays_increase Ensure that `self.remote_ack_sequence_num` is always increasing
crossjob for building and testing laminar
…#234) The connection is disconnected if we have N packets-in-flight simultaneously. Under normal usage we expect packets to be acked regularly so that our packets-in-flight size is relatively small.
b6da88f
to
c02c6a8
Compare
|
||
/// Holds a handle to a formatter function while implementing the [fmt::Display] trait. | ||
pub struct Displayer { | ||
data: Arc<dyn Fn(&mut ::std::fmt::Formatter) -> ::std::fmt::Result + Send + Sync>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Arc
realy needed here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arc
is most general, for instance if you want to send your log messages to another thread.
To be honest I'd prefer if we can do it completely without dynamic allocation but that doesn't allow for arbitrary data to be sent (because sized information is required for that) - data sent through a move |f| format!(f, "{}", x)
requires it because of the arbitrary size of x
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an actual need/use-case of wanting to do that today? I prefer not using the most general solution unless we have a hard requirement that it is needed.
pub(crate) struct DefaultLogger; | ||
|
||
impl LaminarLogger for DefaultLogger { | ||
fn trace(&self, _: Displayer) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't we want to implement this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. I think the library should be silent if not configured to log. Doing default logging could annoy a user. It's perhaps best to inform of misuse via socketevents (for instance the proposed Disconnect(addr, reason)
event or eventual panics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, seems like a good point, just moving decisions over to the user. We might implement a logger using log
and move it under the tester
feature flag. That would allow us to debug if we provide our tester flag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly think that the default logger should maintain its current behavior but we can also provide a SilentLogger
which is this implementation you can configure when setting up your connection.
36d8ff8
to
8314d46
Compare
There are some errors in the code |
@jstnlef can you check this PR as well before merging? |
|
||
/// Holds a handle to a formatter function while implementing the [fmt::Display] trait. | ||
pub struct Displayer { | ||
data: Arc<dyn Fn(&mut ::std::fmt::Formatter) -> ::std::fmt::Result + Send + Sync>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an actual need/use-case of wanting to do that today? I prefer not using the most general solution unless we have a hard requirement that it is needed.
pub(crate) struct DefaultLogger; | ||
|
||
impl LaminarLogger for DefaultLogger { | ||
fn trace(&self, _: Displayer) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly think that the default logger should maintain its current behavior but we can also provide a SilentLogger
which is this implementation you can configure when setting up your connection.
@@ -142,7 +142,10 @@ impl Socket { | |||
match self.recv_from(time) { | |||
Ok(UdpSocketState::MaybeMore) => continue, | |||
Ok(UdpSocketState::MaybeEmpty) => break, | |||
Err(e) => error!("Encountered an error receiving data: {:?}", e), | |||
Err(e) => error!( | |||
self.config.logger, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having to specify this each time is a bit annoying. Is there anything clever we could do about that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be possible to make a trait that Self
implements that returns a logger, but that's about it.
No description provided.