Skip to content

Commit c8eb289

Browse files
HTGAzureX1212Erk-
andauthored
feat(cache, model, gateway): add gateway ratelimited event (#2483)
Co-authored-by: Erk <[email protected]>
1 parent 9f9904a commit c8eb289

File tree

7 files changed

+52
-7
lines changed

7 files changed

+52
-7
lines changed

twilight-cache-inmemory/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,7 @@ impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for Event {
10381038
| Event::InviteDelete(_)
10391039
| Event::MessagePollVoteAdd(_)
10401040
| Event::MessagePollVoteRemove(_)
1041+
| Event::RateLimited(_)
10411042
| Event::Resumed
10421043
| Event::ThreadMembersUpdate(_)
10431044
| Event::ThreadMemberUpdate(_)

twilight-gateway/src/event.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ bitflags! {
195195
const VOICE_STATE_UPDATE = 1 << 43;
196196
/// Webhook in a guild has been updated.
197197
const WEBHOOKS_UPDATE = 1 << 44;
198+
/// The shard encountered a gateway rate limit for an event, e.g.
199+
/// request guild members.
200+
const RATE_LIMITED = 1 << 79;
198201

199202
/// All [`EventTypeFlags`] in [`Intents::AUTO_MODERATION_CONFIGURATION`].
200203
///
@@ -384,6 +387,7 @@ impl From<EventType> for EventTypeFlags {
384387
EventType::MessagePollVoteRemove => Self::MESSAGE_POLL_VOTE_REMOVE,
385388
EventType::MessageUpdate => Self::MESSAGE_UPDATE,
386389
EventType::PresenceUpdate => Self::PRESENCE_UPDATE,
390+
EventType::RateLimited => Self::RATE_LIMITED,
387391
EventType::ReactionAdd => Self::REACTION_ADD,
388392
EventType::ReactionRemove => Self::REACTION_REMOVE,
389393
EventType::ReactionRemoveAll => Self::REACTION_REMOVE_ALL,

twilight-model/src/gateway/event/dispatch.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub enum DispatchEvent {
5757
MessagePollVoteRemove(MessagePollVoteRemove),
5858
MessageUpdate(Box<MessageUpdate>),
5959
PresenceUpdate(Box<PresenceUpdate>),
60+
RateLimited(RateLimited),
6061
ReactionAdd(Box<ReactionAdd>),
6162
ReactionRemove(Box<ReactionRemove>),
6263
ReactionRemoveAll(ReactionRemoveAll),
@@ -130,6 +131,7 @@ impl DispatchEvent {
130131
Self::MessagePollVoteRemove(_) => EventType::MessagePollVoteRemove,
131132
Self::MessageUpdate(_) => EventType::MessageUpdate,
132133
Self::PresenceUpdate(_) => EventType::PresenceUpdate,
134+
Self::RateLimited(_) => EventType::RateLimited,
133135
Self::ReactionAdd(_) => EventType::ReactionAdd,
134136
Self::ReactionRemove(_) => EventType::ReactionRemove,
135137
Self::ReactionRemoveAll(_) => EventType::ReactionRemoveAll,
@@ -389,6 +391,7 @@ impl<'de> DeserializeSeed<'de> for DispatchEventWithTypeDeserializer<'_> {
389391
"PRESENCE_UPDATE" => {
390392
DispatchEvent::PresenceUpdate(Box::new(PresenceUpdate::deserialize(deserializer)?))
391393
}
394+
"RATE_LIMITED" => DispatchEvent::RateLimited(RateLimited::deserialize(deserializer)?),
392395
"READY" => DispatchEvent::Ready(Ready::deserialize(deserializer)?),
393396
"RESUMED" => {
394397
deserializer.deserialize_ignored_any(IgnoredAny)?;

twilight-model/src/gateway/event/kind.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub enum EventType {
6060
MessagePollVoteRemove,
6161
MessageUpdate,
6262
PresenceUpdate,
63+
RateLimited,
6364
#[serde(rename = "MESSAGE_REACTION_ADD")]
6465
ReactionAdd,
6566
#[serde(rename = "MESSAGE_REACTION_REMOVE")]
@@ -139,6 +140,7 @@ impl EventType {
139140
Self::MessagePollVoteAdd => Some("MESSAGE_POLL_VOTE_ADD"),
140141
Self::MessagePollVoteRemove => Some("MESSAGE_POLL_VOTE_REMOVE"),
141142
Self::PresenceUpdate => Some("PRESENCE_UPDATE"),
143+
Self::RateLimited => Some("RATE_LIMITED"),
142144
Self::ReactionAdd => Some("MESSAGE_REACTION_ADD"),
143145
Self::ReactionRemove => Some("MESSAGE_REACTION_REMOVE"),
144146
Self::ReactionRemoveAll => Some("MESSAGE_REACTION_REMOVE_ALL"),
@@ -222,6 +224,7 @@ impl<'a> TryFrom<&'a str> for EventType {
222224
"MESSAGE_REACTION_REMOVE" => Ok(Self::ReactionRemove),
223225
"MESSAGE_REACTION_REMOVE_ALL" => Ok(Self::ReactionRemoveAll),
224226
"MESSAGE_REACTION_REMOVE_EMOJI" => Ok(Self::ReactionRemoveEmoji),
227+
"RATE_LIMITED" => Ok(Self::RateLimited),
225228
"READY" => Ok(Self::Ready),
226229
"RESUMED" => Ok(Self::Resumed),
227230
"GUILD_ROLE_CREATE" => Ok(Self::RoleCreate),
@@ -349,6 +352,7 @@ mod tests {
349352
assert_variant(EventType::MessagePollVoteAdd, "MESSAGE_POLL_VOTE_ADD");
350353
assert_variant(EventType::MessagePollVoteRemove, "MESSAGE_POLL_VOTE_REMOVE");
351354
assert_variant(EventType::PresenceUpdate, "PRESENCE_UPDATE");
355+
assert_variant(EventType::RateLimited, "RATE_LIMITED");
352356
assert_variant(EventType::ReactionAdd, "MESSAGE_REACTION_ADD");
353357
assert_variant(EventType::ReactionRemove, "MESSAGE_REACTION_REMOVE");
354358
assert_variant(EventType::ReactionRemoveAll, "MESSAGE_REACTION_REMOVE_ALL");

twilight-model/src/gateway/event/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub use self::{
1212
};
1313

1414
use super::{CloseFrame, payload::incoming::*};
15+
use crate::gateway::payload::incoming::rate_limited::RateLimitMetadata;
1516
use crate::id::{Id, marker::GuildMarker};
1617
use std::error::Error;
1718
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
@@ -129,6 +130,8 @@ pub enum Event {
129130
MessageUpdate(Box<MessageUpdate>),
130131
/// A user's active presence (such as game or online status) was updated.
131132
PresenceUpdate(Box<PresenceUpdate>),
133+
/// A shard was rate limited for a gateway opcode.
134+
RateLimited(RateLimited),
132135
/// A reaction was added to a message.
133136
ReactionAdd(Box<ReactionAdd>),
134137
/// A reaction was removed from a message.
@@ -225,6 +228,10 @@ impl Event {
225228
Event::MessagePollVoteAdd(e) => e.guild_id,
226229
Event::MessagePollVoteRemove(e) => e.guild_id,
227230
Event::PresenceUpdate(e) => Some(e.0.guild_id),
231+
Event::RateLimited(RateLimited {
232+
meta: RateLimitMetadata::RequestGuildMembers { guild_id, .. },
233+
..
234+
}) => Some(*guild_id),
228235
Event::ReactionAdd(e) => e.0.guild_id,
229236
Event::ReactionRemove(e) => e.0.guild_id,
230237
Event::ReactionRemoveAll(e) => e.guild_id,
@@ -312,6 +319,7 @@ impl Event {
312319
Self::MessagePollVoteRemove(_) => EventType::MessagePollVoteRemove,
313320
Self::MessageUpdate(_) => EventType::MessageUpdate,
314321
Self::PresenceUpdate(_) => EventType::PresenceUpdate,
322+
Self::RateLimited(_) => EventType::RateLimited,
315323
Self::ReactionAdd(_) => EventType::ReactionAdd,
316324
Self::ReactionRemove(_) => EventType::ReactionRemove,
317325
Self::ReactionRemoveAll(_) => EventType::ReactionRemoveAll,
@@ -393,6 +401,7 @@ impl From<DispatchEvent> for Event {
393401
DispatchEvent::MessagePollVoteRemove(v) => Self::MessagePollVoteRemove(v),
394402
DispatchEvent::MessageUpdate(v) => Self::MessageUpdate(v),
395403
DispatchEvent::PresenceUpdate(v) => Self::PresenceUpdate(v),
404+
DispatchEvent::RateLimited(v) => Self::RateLimited(v),
396405
DispatchEvent::ReactionAdd(v) => Self::ReactionAdd(v),
397406
DispatchEvent::ReactionRemove(v) => Self::ReactionRemove(v),
398407
DispatchEvent::ReactionRemoveAll(v) => Self::ReactionRemoveAll(v),
@@ -464,7 +473,7 @@ impl Error for EventConversionError {}
464473

465474
#[cfg(test)]
466475
mod tests {
467-
//! `EVENT_THRESHOLD` is equivalent to 192 bytes. This was decided based on
476+
//! `EVENT_THRESHOLD` is equivalent to 312 bytes. This was decided based on
468477
//! the size of `Event` at the time of writing. The assertions here are to
469478
//! ensure that in the case the events themselves grow or shrink past the
470479
//! threshold, they are properly boxed or unboxed respectively.
@@ -534,6 +543,7 @@ mod tests {
534543
const_assert!(mem::size_of::<MessageDelete>() <= EVENT_THRESHOLD);
535544
const_assert!(mem::size_of::<MessageDeleteBulk>() <= EVENT_THRESHOLD);
536545
const_assert!(mem::size_of::<MemberRemove>() <= EVENT_THRESHOLD);
546+
const_assert!(mem::size_of::<RateLimited>() <= EVENT_THRESHOLD);
537547
const_assert!(mem::size_of::<Ready>() <= EVENT_THRESHOLD);
538548
const_assert!(mem::size_of::<ReactionRemoveAll>() <= EVENT_THRESHOLD);
539549
const_assert!(mem::size_of::<RoleCreate>() <= EVENT_THRESHOLD);

twilight-model/src/gateway/payload/incoming/mod.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//! [1]: https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events
1313
1414
pub mod invite_create;
15+
pub mod rate_limited;
1516
pub mod reaction_remove_emoji;
1617

1718
mod auto_moderation_action_execution;
@@ -105,12 +106,12 @@ pub use self::{
105106
message_create::MessageCreate, message_delete::MessageDelete,
106107
message_delete_bulk::MessageDeleteBulk, message_poll_vote_add::MessagePollVoteAdd,
107108
message_poll_vote_remove::MessagePollVoteRemove, message_update::MessageUpdate,
108-
presence_update::PresenceUpdate, reaction_add::ReactionAdd, reaction_remove::ReactionRemove,
109-
reaction_remove_all::ReactionRemoveAll, reaction_remove_emoji::ReactionRemoveEmoji,
110-
ready::Ready, role_create::RoleCreate, role_delete::RoleDelete, role_update::RoleUpdate,
111-
stage_instance_create::StageInstanceCreate, stage_instance_delete::StageInstanceDelete,
112-
stage_instance_update::StageInstanceUpdate, thread_create::ThreadCreate,
113-
thread_delete::ThreadDelete, thread_list_sync::ThreadListSync,
109+
presence_update::PresenceUpdate, rate_limited::RateLimited, reaction_add::ReactionAdd,
110+
reaction_remove::ReactionRemove, reaction_remove_all::ReactionRemoveAll,
111+
reaction_remove_emoji::ReactionRemoveEmoji, ready::Ready, role_create::RoleCreate,
112+
role_delete::RoleDelete, role_update::RoleUpdate, stage_instance_create::StageInstanceCreate,
113+
stage_instance_delete::StageInstanceDelete, stage_instance_update::StageInstanceUpdate,
114+
thread_create::ThreadCreate, thread_delete::ThreadDelete, thread_list_sync::ThreadListSync,
114115
thread_member_update::ThreadMemberUpdate, thread_members_update::ThreadMembersUpdate,
115116
thread_update::ThreadUpdate, typing_start::TypingStart, unavailable_guild::UnavailableGuild,
116117
user_update::UserUpdate, voice_server_update::VoiceServerUpdate,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use crate::{
2+
gateway::OpCode,
3+
id::{Id, marker::GuildMarker},
4+
};
5+
use serde::{Deserialize, Serialize};
6+
7+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
8+
pub struct RateLimited {
9+
pub opcode: OpCode,
10+
pub retry_after: f32,
11+
pub meta: RateLimitMetadata,
12+
}
13+
14+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
15+
#[non_exhaustive]
16+
pub enum RateLimitMetadata {
17+
RequestGuildMembers {
18+
guild_id: Id<GuildMarker>,
19+
#[serde(skip_serializing_if = "Option::is_none")]
20+
nonce: Option<String>,
21+
},
22+
}

0 commit comments

Comments
 (0)