-
Notifications
You must be signed in to change notification settings - Fork 625
Adds better abilities to check, what exactly was rate limited #2901
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
base: next
Are you sure you want to change the base?
Conversation
The failing check seems broken, at least I do not get any error when looking at the details... |
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] | ||
enum RouteKind { | ||
$($name,)+ | ||
} |
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.
Why was this moved?
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.
To have two similar blocks next to another (Route
and OwnedRoute
).
I could move it back, but in my opinion it is more readable like this.
/// please match the variants you are interested in. | ||
#[must_use] | ||
#[allow(unused_variables)] // prevent compiler from complaining about unused variables | ||
pub fn get_common_identifiers(&self) -> RatelimitCause { |
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.
pub fn get_common_identifiers(&self) -> RatelimitCause { | |
pub fn cause(&self) -> RatelimitCause { |
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.
This does not really return the "cause" of the rate limit but the parts of the path, which was rate limited.
The "cause" would be the deletion of a message or something like 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.
So the type should not be caused RatelimitCause
, it should be called RatelimitPathParts
or something else.
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.
That is better, yes.
Can the method name stay then?
($lt:lifetime, { | ||
$( | ||
$name:ident $({ $($field_name:ident: $field_type:ty),* })?, | ||
$name:ident $({ $($field_name_route:ident: $field_type:ty | $field_type_owned:ty),* })?, |
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.
Instead of making the macro syntax messier, can you make this use traits instead? I'm pretty sure ToOwned
should handle this, but if it doesn't you can just write a simple private trait.
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.
How? I somehow need to know the type, which the OwnedRoute should use. I do not know, how a trait would be able to do that.
The problem is the "&str" type. Can you please provide an example for how to do it?
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.
The owned type is simply <$field_type as ToOwned>::Owned
, and if that doesn't return the correct types you can duplicate the definition of ToOwned
and implement it for the types needed.
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.
Will do 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.
The field_type_owned
is actually needed, I did not find a way to get compiling code without it.
Reason:
The macro would expand into something like this (irrelevant code removed):
#[derive(Clone, Debug)]
pub enum OwnedRoute {
ChannelMessageReaction { channel_id: <ChannelId as ToOwned>::Owned, message_id: <MessageId as ToOwned>::Owned, user_id: <UserId as ToOwned>::Owned, reaction: <&'a str as ToOwned>::Owned},
}
<&'a str as ToOwned>::Owned
is not valid, because 'a
does not exist. I could add the lifetime to the enum, but then we would need to carry this useless lifetime though the whole code. This can not be fixed by replacing the <&'a str as ToOwned>::Owned
with a custom macro, I already tried:
macro_rules! get_owned_type {
(&'a str) => {String};
($type:ty) => {<$type as ToOwned>::Owned};
}
#[derive(Clone, Debug)]
pub enum OwnedRoute {
ChannelMessageReaction { channel_id: get_owned_type!(ChannelId), message_id: get_owned_type!(MessageId), user_id: get_owned_type!(UserId), reaction: get_owned_type!(&'a str)},
}
will not compile for the same reason.
The compiler is not smart enough to ignore the unused lifetime at the moment.
src/http/routing.rs
Outdated
} | ||
|
||
#[must_use] | ||
pub fn get_owned_route(&self) -> OwnedRoute { |
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.
Rust convention is to name getters without the prefix, but since this is a &self
-> Owned
I think the convention would be to_owned_route
... however that's just ToOwned, so implement ToOwned
instead.
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 did not use toOwned
, because this is not really a clone and should not be treated as one, which is expected by the trait however.
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.
With that logic ToOwned
should not be a thing, but this is exactly what it's for. This is internally just converting str -> String
which is exactly the point of ToOwned
.
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.
This can not be done using ToOwned
, because this would require the "copied" object to carry the lifetime with it.
I already tried that sometime, and it makes the whole code a mess.
I renamed the method though (not pushed yet because of the other change requests).
c01e57d
to
842373b
Compare
9296017
to
efb5820
Compare
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 cannot review this PR without it being rebased correctly on-top of next.
cf3701f
to
ec3a62e
Compare
Was doing that right as you wrote that, lol xD |
7e6b73b
to
9b2d176
Compare
…erenity-rs#2646) This avoids having to allocate to store fixed length (replaced with normal array) or fixed capacity (replaced with `ArrayVec`) collections as vectors for the purposes of putting them through the `Request` plumbing. Slight behavioral change - before, setting `params` to `Some(vec![])` would still append a question mark to the end of the url. Now, we check if the params array `is_empty` instead of `is_some`, so the question mark won't be appended if the params list is empty. Co-authored-by: Michael Krasnitski <[email protected]>
Fixes CI failure
…rs#3075) Similar to message URLs, Discord also provides URLs for guild channels. Additionally, the function is added as an alternative for parsing a `Channel` from a string. Private channels are not affected by this change.
The `Deserialize` implementation neglects to add the `Bot ` prefix to the string when it is deserialised. This adds `TryFrom` implementations for `&str` and `String` and tells serde to deserialise `Token` using the `TryFrom<&str>` implementation, which will prepend the `Bot ` prefix. Fixes serenity-rs#3085
This commit refactors how the gateway connection being closed gets handled, and also reworks how resuming is performed. If a resume fails, or if the session id is invalid/doesn't exist, the shard will fall back to restart + reidentify after a 1 second delay. This behavior was only present in some circumstances before. Also, cleaned up the loop in `ShardRunner::run` by adding a `ShardAction::Dispatch` variant, since event dispatch was already mutually exclusive to hearbeating, identifying, and restarting. The overall effect is less interleaving of control flow. Plus, removed the `Shard::{reconnect, reset}` functions as they were unused. A notable change is that 4006 is no longer considered a valid close code as it is undocumented, and neither is 1000, which tungstenite assigns as `Normal` or "clean". We should stick to the [table of close codes](https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-close-event-codes) provided by Discord.
A regression introduced by serenity-rs#3099 was that successful resumes will break out of the loop inside `ShardRunner::run`, but they shouldn't (or rather, didn't before). Therefore, only break out of the loop if the resume failed and we had to fallback to reidentifying.
…3111) As the title notes, this commit replaces fxhash for foldhash as used in the cache. dashmap, due to it's sharding, has to share entropy with what's handed down to internal maps. Since `hashbrown` and by extension `std` use various sections of the high bit range for special grouping & sorting, dashmap is left with the only option to shard on low bits. This, however, presents problems, because fxhash outputs hashes of very bad quality, with only the high bits having any real entropy. This was probably a solid choice back in 2018 when we lacked other good fast alternatives. But since then `ahash` matured and we've had significant research and development in "good enough" hashing for datastructures with short keys, [the most recent step forward coming from a rather well known face][foldhash]. This improves shard selection quite a bit and reduces contention significantly. Using fxhash in a dashmap specific benchmark causes contention to go up by 3-8x when keys are k-sortable with time (Discord snowflakes) on an M1 Pro. [foldhash]: https://github.com/orlp/foldhash
…s#3088) This replaces the time unit that determines how many messages in a period of X time should be deleted when a user is banned. Discord expresses this time in seconds, whereas Serenity exposed it in days. The limit is still 7 days, but with this, users of Serenity can be more precise with which messages they want to delete.
…ap tree (serenity-rs#3114) Avoid temporarily deserializing gateway messages to a `serde_json::Map<String, Value>` before typed deserialization to an `Event`. Previously, this meant the creation of a `serde_json::Value` tree, causing creation and immediately after the destruction of upwards of hundreds to thousands of owned strings and btreemaps for every handled gateway event.
It is just a copy of Route without any lifetimes.
9b2d176
to
9b7a73a
Compare
57c79ff
to
9a811a7
Compare
Add "OwnedRoute" to "RatelimitInfo" which allows to check the cause of the rate limit and which identifiers were affected (e.g. which channel).