-
Notifications
You must be signed in to change notification settings - Fork 12
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
Make examples work #47
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughThis pull request introduces significant changes to the handling of suspended events and intents across multiple modules. The Additionally, a new Possibly related PRs
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 6
🧹 Outside diff range and nitpick comments (2)
aper/src/aper.rs (1)
Line range hint
1-30
: Summary: Changes look good, but thorough testing is recommended.The modifications to the
suspended_event
method in theAper
trait align with the PR objective of making examples work. The change fromIntentMetadata
toDateTime<Utc>
simplifies the suspended event structure.Given the potential impact of this change on the broader codebase, I recommend:
- Updating all implementations of the
Aper
trait to match the new signature.- Reviewing and updating any code that relies on the
suspended_event
method.- Conducting thorough testing, including integration tests, to ensure that the changes don't introduce any regressions or unexpected behavior.
- Updating relevant documentation to reflect the new structure of suspended events.
These steps will help ensure that the changes are fully integrated and don't cause issues in other parts of the system.
examples/drop-four/common/src/state.rs (1)
227-234
: Consider using dynamic timestamps in testsIn the test code, the
timestamp
field is set to a fixed value usingUtc.timestamp_millis_opt(0).unwrap()
. For more realistic tests, consider using the current time or varying timestamps to simulate real-world scenarios.You can update the timestamps as follows:
let player1_meta = IntentMetadata { client: Some(player1), - timestamp: Utc.timestamp_millis_opt(0).unwrap(), + timestamp: Utc::now(), }; let player2_meta = IntentMetadata { client: Some(player2), - timestamp: Utc.timestamp_millis_opt(0).unwrap(), + timestamp: Utc::now(), };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
- aper-stateroom/src/lib.rs (4 hunks)
- aper/src/aper.rs (2 hunks)
- aper/src/connection.rs (3 hunks)
- examples/counter/common/src/lib.rs (2 hunks)
- examples/drop-four/common/src/state.rs (11 hunks)
- examples/drop-four/service/.cargo/config (1 hunks)
- examples/timer/common/src/lib.rs (2 hunks)
✅ Files skipped from review due to trivial changes (1)
- examples/drop-four/service/.cargo/config
🔇 Additional comments (12)
examples/counter/common/src/lib.rs (4)
1-1
: LGTM: Import statement updated correctly.The import statement has been appropriately updated to replace
IntentEvent
withIntentMetadata
, which aligns with the changes made to theapply
method signature.
26-26
: LGTM: Method signature updated appropriately.The
apply
method signature has been updated to directly use&CounterIntent
instead of&IntentEvent<CounterIntent>
, simplifying the interface. The addition of the_metadata: &IntentMetadata
parameter allows for future use of intent metadata if needed. The underscore prefix in_metadata
correctly indicates that it's currently unused.
29-29
: LGTM: Method implementation updated correctly.The
apply
method implementation has been correctly updated to useintent
instead ofevent.intent
in the match statement. This change is consistent with the new method signature, and the overall logic for handling the intents (Add, Subtract, and Reset) remains unchanged, preserving the functionality of modifying the counter's value.
Line range hint
1-42
: Overall: Changes improve code structure and maintainability.The modifications to the
Counter
struct and itsAper
implementation enhance the code's clarity and align well with the PR objective of making examples work. The changes simplify intent handling and prepare the code for potential future use of intent metadata.aper/src/aper.rs (2)
6-6
: LGTM: New import added correctly.The new import from the
chrono
crate is necessary for the changes made to thesuspended_event
method. It's correctly placed with other external crate imports.
28-30
: LGTM:suspended_event
method signature updated.The change from
Option<(Self::Intent, IntentMetadata)>
toOption<(DateTime<Utc>, Self::Intent)>
simplifies the suspended event structure by replacingIntentMetadata
with a timestamp. This aligns with the PR objective of making examples work.Please verify that all implementations of the
Aper
trait have been updated to match this new signature. Run the following script to check for any remaining occurrences of the old signature:✅ Verification successful
Further Verification Required: Ensure all
suspended_event
implementations use the new signature.Please run the following scripts to verify that every implementation of the
Aper
trait correctly uses the updatedsuspended_event
method signature and thatIntentMetadata
is no longer referenced in this context:
Verification Successful: All
suspended_event
implementations are updated correctly.The
suspended_event
method signature has been uniformly updated across the codebase, and there are no remaining references toIntentMetadata
within its implementations.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for occurrences of the old suspended_event signature # Test: Search for the old signature. Expect: No results. rg --type rust 'fn suspended_event.*Option<\(.*Intent, IntentMetadata\)>' # Test: Search for implementations of the Aper trait. Expect: All implementations use the new signature. rg --type rust 'impl.*Aper.*\{' -A 10Length of output: 17229
Script:
#!/bin/bash # Description: Verify all implementations of `suspended_event` use the new signature and do not reference `IntentMetadata` # Check for implementations of the new `suspended_event` signature rg --type rust 'fn suspended_event\(&self\) -> Option<\(DateTime<Utc>, Self::Intent\)>' # Ensure `IntentMetadata` is not used within `suspended_event` implementations rg --type rust 'fn suspended_event\(&self\).*IntentMetadata'Length of output: 242
examples/timer/common/src/lib.rs (1)
21-27
: Implementation ofapply
method is correctThe
apply
method correctly handles intents by updatingself.value
andself.last_increment
using the providedintent
andmetadata
. The logic aligns with the intended functionality.aper-stateroom/src/lib.rs (2)
14-14
: Change tosuspended_event
field type is appropriateThe modification of the
suspended_event
field to includeDateTime<Utc>
enhances clarity by explicitly associating a timestamp with the suspended intent. This is consistent with the updated handling of suspended events.
51-51
: Duration calculation handles scheduling correctlyThe calculation of
dur
usingev.0.signed_duration_since(Utc::now())
correctly computes the duration until the scheduled event. The use of.max(0)
ensures that the timer is set to zero if the event time is in the past, preventing negative durations.aper/src/connection.rs (2)
86-86
: Confirm consistency in constructingMessageToServer::Intent
with newmetadata
fieldIncluding the
metadata
field when constructingMessageToServer::Intent
ensures that the message aligns with the updated enum definition. This consistency is important for correct serialization and deserialization of messages.
168-168
: Update pattern matching to include the newmetadata
fieldBy adding
metadata
to the pattern match in thereceive
method, you ensure that all necessary information is correctly extracted from theMessageToServer::Intent
. This update is crucial for processing intents with the new metadata.examples/drop-four/common/src/state.rs (1)
157-158
: Ensureapply
method signature aligns with theAper
traitThe
apply
method signature has been updated to acceptintent
andmetadata
separately. Please verify that this change is consistent with theAper
trait definition and that all implementations and invocations are updated accordingly.You can run the following script to confirm that all
Aper
implementations have updated theapply
method signature:✅ Verification successful
Confirmed:
apply
method signature aligns with theAper
trait🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all implementations of the `Aper` trait have the updated `apply` method signature. # Search for `impl Aper` blocks and check for the `apply` method signature. rg --type rust -A5 'impl\s+Aper\s+for' | rg 'fn\s+apply\(&mut self,\s*intent:.*,\s*metadata:.*\)'Length of output: 359
fn suspended_event(&self) -> Option<(DateTime<Utc>, TimerIntent)> { | ||
let next_event = self | ||
.last_increment | ||
.get() | ||
.checked_add_signed(Duration::seconds(1)) | ||
.unwrap(); | ||
|
||
Some(IntentEvent::new(None, next_event, TimerIntent::Increment)) | ||
Some((next_event, TimerIntent::Increment)) |
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.
Avoid potential panic by handling None
case in suspended_event
Using .unwrap()
after checked_add_signed
can cause a panic if the date arithmetic results in an overflow. It's safer to handle the Option
returned to prevent unexpected panics.
Consider handling the None
case explicitly:
fn suspended_event(&self) -> Option<(DateTime<Utc>, TimerIntent)> {
let next_event = self
.last_increment
.get()
- .checked_add_signed(Duration::seconds(1))
- .unwrap();
+ .checked_add_signed(Duration::seconds(1))?;
Some((next_event, TimerIntent::Increment))
}
This change ensures that if an overflow occurs, the function gracefully returns None
instead of panicking.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
fn suspended_event(&self) -> Option<(DateTime<Utc>, TimerIntent)> { | |
let next_event = self | |
.last_increment | |
.get() | |
.checked_add_signed(Duration::seconds(1)) | |
.unwrap(); | |
Some(IntentEvent::new(None, next_event, TimerIntent::Increment)) | |
Some((next_event, TimerIntent::Increment)) | |
fn suspended_event(&self) -> Option<(DateTime<Utc>, TimerIntent)> { | |
let next_event = self | |
.last_increment | |
.get() | |
.checked_add_signed(Duration::seconds(1))?; | |
Some((next_event, TimerIntent::Increment)) | |
} |
if let Some((_timestamp, intent)) = self.suspended_event.take() { | ||
let intent = bincode::serialize(&intent).unwrap(); | ||
self.process_message( | ||
MessageToServer::Intent { | ||
intent: event, | ||
intent, | ||
client_version: 0, | ||
metadata: IntentMetadata::new(None, Utc::now()), |
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.
Use the original timestamp when constructing IntentMetadata
Currently, IntentMetadata
is initialized with the current time using Utc::now()
. To accurately reflect the intended execution time of the suspended intent, consider using the original timestamp _timestamp
extracted from self.suspended_event
.
Apply this diff to use the scheduled timestamp:
metadata: IntentMetadata::new(None, Utc::now()),
+metadata: IntentMetadata::new(None, _timestamp),
Committable suggestion was skipped due to low confidence.
@@ -12,6 +12,7 @@ pub enum MessageToServer { | |||
Intent { | |||
intent: Vec<u8>, | |||
client_version: u64, | |||
metadata: IntentMetadata, |
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.
Ensure backward compatibility when adding metadata
to MessageToServer::Intent
Adding the metadata
field to the MessageToServer::Intent
enum variant may lead to deserialization issues with clients or servers that are not updated to handle this new field. This change can break compatibility with existing systems.
Consider implementing versioning for your messages or providing default values to maintain backward compatibility with older clients and servers.
self.player_map.teal_player.set(metadata.client); | ||
} else if self.player_map.brown_player.get().is_none() { | ||
self.player_map.brown_player.set(event.client); | ||
self.player_map.brown_player.set(metadata.client); |
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.
Handle potential None
values for metadata.client
When assigning metadata.client
to teal_player
and brown_player
, ensure that metadata.client
is Some(client_id)
to avoid assigning None
as a player ID, which may lead to unexpected behavior.
You can modify the code to check for Some(client_id)
before assignment:
if self.player_map.teal_player.get().is_none() {
+ if let Some(client_id) = metadata.client {
self.player_map.teal_player.set(Some(client_id));
+ } else {
+ return Err(()); // Handle None client ID appropriately
+ }
} else if self.player_map.brown_player.get().is_none() {
+ if let Some(client_id) = metadata.client {
self.player_map.brown_player.set(Some(client_id));
self.play_state.set(PlayState::Playing);
+ } else {
+ return Err(()); // Handle None client ID appropriately
+ }
}
Committable suggestion was skipped due to low confidence.
@@ -171,15 +171,15 @@ | |||
if self.winner.get().is_some() { | |||
return Ok(()); | |||
} // Someone has already won. | |||
if self.player_map.id_of_color(self.next_player.get()) != event.client { | |||
if self.player_map.id_of_color(self.next_player.get()) != metadata.client { |
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.
Ensure correct comparison of client IDs
The comparison between self.player_map.id_of_color(self.next_player.get())
and metadata.client
compares two Option<u32>
values. To avoid potential mismatches due to None
values, consider unwrapping both options safely before comparison.
You might adjust the code as follows:
- if self.player_map.id_of_color(self.next_player.get()) != metadata.client {
+ if let (Some(expected_id), Some(actual_id)) = (
+ self.player_map.id_of_color(self.next_player.get()),
+ metadata.client,
+ ) {
+ if expected_id != actual_id {
+ return Ok(()); // Play out of turn.
+ }
+ } else {
+ return Ok(()); // Missing player ID.
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if self.player_map.id_of_color(self.next_player.get()) != metadata.client { | |
if let (Some(expected_id), Some(actual_id)) = ( | |
self.player_map.id_of_color(self.next_player.get()), | |
metadata.client, | |
) { | |
if expected_id != actual_id { | |
return Ok(()); // Play out of turn. | |
} | |
} else { | |
return Ok(()); // Missing player ID. | |
} |
if let Some(insert_row) = self.board.lowest_open_row(*c as u32) { | ||
self.board | ||
.set(insert_row, c as u32, Some(self.next_player.get())); | ||
.set(insert_row, *c as u32, Some(self.next_player.get())); |
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.
Add bounds check for column index to prevent potential panics
When casting *c
from usize
to u32
, ensure that the column index is within valid bounds to prevent integer overflow or out-of-bounds access.
Apply this diff to add a bounds check:
+ if (*c as u32) >= BOARD_COLS {
+ return Err(()); // Column index is out of bounds.
+ }
if let Some(insert_row) = self.board.lowest_open_row(*c as u32) {
self.board
.set(insert_row, *c as u32, Some(self.next_player.get()));
Committable suggestion was skipped due to low confidence.
No description provided.