Skip to content
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

feat(torii-core): optimistically broadcast entity update #2466

Merged
merged 7 commits into from
Oct 8, 2024

Conversation

Larkooo
Copy link
Collaborator

@Larkooo Larkooo commented Sep 23, 2024

Summary by CodeRabbit

  • New Features

    • Introduced new structures: OptimisticEntityUpdate, OptimisticEntity, and OptimisticEventMessage, enhancing the entity and event message handling.
    • Updated service methods to work with OptimisticEntity and OptimisticEventMessage, improving message publishing and subscription management.
    • Enhanced the message broker to include a queuing mechanism for better message delivery management.
  • Bug Fixes

    • Adjusted conditions to clear children of updated models when applicable, ensuring data integrity.
  • Documentation

    • Added comments to clarify the purpose and usage of the new structures and their fields.

Copy link

coderabbitai bot commented Sep 23, 2024

Walkthrough

Ohayo, sensei! This pull request introduces the OptimisticEntityUpdate structure, integrating it into the Sql implementation and the Service struct in the entity.rs file. The new structure facilitates the handling of entity updates and enhances the publication mechanism. Instances of OptimisticEntityUpdate are created in SQL methods, and service methods are updated to accommodate this new type, reflecting a shift towards a more optimistic concurrency model across the codebase.

Changes

Files Change Summary
crates/torii/core/src/sql.rs Introduced OptimisticEntityUpdate structure; integrated into Sql methods, updating entity handling.
crates/torii/core/src/types.rs Added public structs: OptimisticEntityUpdate, OptimisticEntity, and OptimisticEventMessage with relevant fields and attributes.
crates/torii/core/src/executor.rs Enhanced Executor struct's query handling to include OptimisticEntity and OptimisticEventMessage for publishing updates.
crates/torii/grpc/src/server/subscriptions/entity.rs Updated Service struct to use OptimisticEntity instead of Entity in method signatures and broker initialization.
crates/torii/grpc/src/server/subscriptions/event_message.rs Updated Service struct to use OptimisticEventMessage instead of EventMessage in method signatures and broker initialization.
crates/torii/core/src/simple_broker.rs Enhanced Senders struct to include a message queue; modified publish method to queue messages before sending.

Possibly related PRs

Suggested reviewers

  • glihm

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 7e3fe7c and 37b5f60.

📒 Files selected for processing (2)
  • crates/torii/core/src/executor.rs (4 hunks)
  • crates/torii/core/src/types.rs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/torii/core/src/executor.rs
🧰 Additional context used
🔇 Additional comments (2)
crates/torii/core/src/types.rs (2)

49-64: 🛠️ Refactor suggestion

Ohayo, sensei! Let's revisit the OptimisticEntity structure.

While I understand the need for this structure due to SQLx requirements, there are still some concerns:

  1. The OptimisticEntity is identical to Entity, which violates the DRY principle. Consider using a type alias:
pub type OptimisticEntity = Entity;
  1. The updated_model field is still Option<Ty>, but the comment states it should never be None. If possible, consider changing it to:
pub updated_model: Ty,

If Option is necessary due to SQLx, please add a comment explaining this constraint.

  1. If there are specific reasons for keeping OptimisticEntity separate from Entity, please add a comment explaining the rationale.

What do you think about these suggestions, sensei?


81-94: 🛠️ Refactor suggestion

Ohayo again, sensei! Let's discuss the OptimisticEventMessage structure.

The OptimisticEventMessage structure is very similar to EventMessage, but with a key difference:

  1. The deleted field is missing in OptimisticEventMessage.

To improve this, consider the following options:

  1. If OptimisticEventMessage doesn't need the deleted field, use a type alias with a custom type:
pub struct OptimisticEventMessageData {
    pub event_message: EventMessage,
    // Add any additional fields specific to OptimisticEventMessage
}

pub type OptimisticEventMessage = OptimisticEventMessageData;
  1. If the deleted field should be present, add it to maintain consistency:
#[sqlx(skip)]
pub deleted: bool,
  1. If there's a specific reason for the current implementation, please add a comment explaining the rationale behind the differences between EventMessage and OptimisticEventMessage.

What are your thoughts on these suggestions, sensei?


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Outside diff range and nitpick comments (2)
crates/torii/core/src/types.rs (1)

32-44: Ohayo, sensei! Consider adding documentation to clarify the relationship with Entity struct.

The new OptimisticEntityUpdate struct shares many similarities with the existing Entity struct. To improve code clarity and maintainability, it would be beneficial to add documentation explaining the relationship between these two structs and their specific use cases.

Consider adding a doc comment above the struct definition, like this:

/// Represents an optimistic update to an entity.
/// This struct is used for [explain specific use case], while the `Entity` struct is used for [explain Entity use case].
#[derive(FromRow, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct OptimisticEntityUpdate {
    // ... fields ...
}
crates/torii/grpc/src/server/subscriptions/entity.rs (1)

86-89: Ohayo, sensei! LGTM with a small suggestion.

The Service struct initialization now correctly uses OptimisticEntityUpdate, which aligns with the new optimistic concurrency model. Great job!

Consider adjusting the indentation for better readability:

 Self {
     subs_manager,
-    simple_broker: Box::pin(SimpleBroker::<OptimisticEntityUpdate>::subscribe()),
+    simple_broker: Box::pin(
+        SimpleBroker::<OptimisticEntityUpdate>::subscribe()
+    ),
 }
Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 60c1575 and 03b3307.

Files selected for processing (3)
  • crates/torii/core/src/sql.rs (3 hunks)
  • crates/torii/core/src/types.rs (1 hunks)
  • crates/torii/grpc/src/server/subscriptions/entity.rs (2 hunks)
Additional comments not posted (6)
crates/torii/core/src/types.rs (2)

32-44: Ohayo, sensei! The new struct looks good overall.

The OptimisticEntityUpdate struct is well-defined and consistent with the existing coding style. Nice work!


42-43: Ohayo! Can you clarify the implications of skipping the 'deleted' field in SQLx?

The deleted field is marked with #[sqlx(skip)]. This means it won't be included in database operations by default.

Could you explain how this field is intended to be used and updated? If it's meant to be handled separately from regular CRUD operations, a comment explaining this would be helpful.

To verify the usage of this field, let's run the following script:

Verification successful

Ohayo, sensei! 🌸 It looks like we need to explore a bit more to uncover how the deleted field is being used. Let's run a broader search to ensure we're not missing anything.


Ohayo, sensei! 🌸

Clarification on the deleted Field Handling

It appears that the deleted field is managed within the application logic rather than through direct SQLx operations. This aligns with the usage patterns observed in the codebase.

  • The field is utilized in various parts of the application, such as:
    • crates/torii/graphql/src/tests/models_test.rs for testing deleted records.
    • crates/torii/grpc/src/server/subscriptions/entity.rs to check deletion status.
    • crates/torii/core/src/query_queue.rs for managing entity updates and deletions.

Recommendation:

  • Consider adding a comment in crates/torii/core/src/types.rs to explain that the deleted field is handled separately from regular CRUD operations. This will aid in understanding its purpose and usage within the application.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any custom handling of the 'deleted' field in SQL queries or database operations

# Search for SQL queries or database operations involving 'deleted'
rg --type rust -i 'deleted.*sql' crates/torii

Length of output: 47


Script:

#!/bin/bash
# Description: Search for any usage of the 'deleted' field across all Rust files in crates/torii

# Perform a case-insensitive search for 'deleted' in Rust files
rg --type rust -i 'deleted' crates/torii

Length of output: 1004

crates/torii/grpc/src/server/subscriptions/entity.rs (2)

17-17: Ohayo, sensei! LGTM: New import for OptimisticEntityUpdate.

The import statement for OptimisticEntityUpdate is correctly added and aligns with the existing import style.


Line range hint 1-238: Ohayo, sensei! Overall great implementation of OptimisticEntityUpdate.

The changes in this file consistently implement the transition to OptimisticEntityUpdate, which should improve the concurrency model. The modifications are well-structured and maintain the existing code style. Great work on this update!

crates/torii/core/src/sql.rs (2)

20-23: Ohayo, sensei! Appropriate Import of SimpleBroker and OptimisticEntityUpdate

The addition of SimpleBroker and OptimisticEntityUpdate is necessary for implementing the optimistic concurrency model.


244-253: Ohayo, sensei! Correct Integration of OptimisticEntityUpdate in set_entity

The implementation of OptimisticEntityUpdate and publishing it via SimpleBroker in the set_entity method enhances the entity update mechanism effectively.

crates/torii/core/src/types.rs Outdated Show resolved Hide resolved
crates/torii/grpc/src/server/subscriptions/entity.rs Outdated Show resolved Hide resolved
Comment on lines 366 to 382

let optimistic_entity_update = OptimisticEntityUpdate {
id: entity_id.clone(),
keys: keys_str.unwrap_or("").to_string(),
event_id: event_id.to_string(),
updated_model: Some(entity),
deleted: false,
};
match optimistic_entity_update.updated_model {
Some(Ty::Struct(ref mut struct_)) => {
struct_.children.clear();
}
_ => {}
}

SimpleBroker::publish(optimistic_entity_update);

Copy link

Choose a reason for hiding this comment

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

Ohayo, sensei! Fix Undefined keys_str and Correct the deleted Flag in delete_entity

There are issues in this code segment:

  • Undefined Variable: keys_str is used but not defined in this scope, which will cause a compile-time error.
  • Incorrect deleted Flag: The deleted flag is set to false during an entity deletion. It should be set to true to accurately represent the entity's deletion status.

To resolve these issues, consider making the following changes:

  • Pass keys_str as an argument to the delete_entity function.
  • Set the deleted flag to true to indicate the entity has been deleted.

Apply this diff:

 pub async fn delete_entity(
     &mut self,
     entity_id: Felt,
     model_id: Felt,
     entity: Ty,
+    keys_str: Option<&str>,
     event_id: &str,
     block_timestamp: u64,
 ) -> Result<()> {

     let entity_id = format!("{:#x}", entity_id);
     let path = vec![entity.name()];

     let optimistic_entity_update = OptimisticEntityUpdate {
         id: entity_id.clone(),
-        keys: keys_str.unwrap_or("").to_string(),
+        keys: keys_str.unwrap_or("").to_string(),
         event_id: event_id.to_string(),
         updated_model: Some(entity),
-        deleted: false,
+        deleted: true,
     };

     match optimistic_entity_update.updated_model {
         Some(Ty::Struct(ref mut struct_)) => {
             struct_.children.clear();
         }
         _ => {}
     }

     SimpleBroker::publish(optimistic_entity_update);

Committable suggestion was skipped due to low confidence.

pub keys: String,
pub event_id: String,

// this should never be None
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why using an option is it should never be none?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because we have a "FromRow" from sqlx. The row doesn't have that field so we put an option to then inject that fields value

@Larkooo Larkooo force-pushed the optimisti-entity-update branch from 03b3307 to 5550d4b Compare October 4, 2024 19:35
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (1)
crates/torii/grpc/src/server/subscriptions/entity.rs (1)

Line range hint 151-158: Potential panic due to use of unwrap() on Option

Using unwrap() on Option types can cause a panic if the value is None. Even though the comment mentions that updated_model should never be None, it's safer to handle this explicitly. Consider using expect() with a descriptive message or gracefully handling the None case to prevent potential runtime panics.

Apply this diff to improve error handling:

- let model = entity.updated_model.as_ref().unwrap().as_struct().unwrap().clone();
+ let model = entity
+     .updated_model
+     .as_ref()
+     .expect("updated_model should not be None")
+     .as_struct()
+     .expect("Failed to convert updated_model to struct")
+     .clone();
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 03b3307 and 5550d4b.

📒 Files selected for processing (4)
  • crates/torii/core/src/executor.rs (4 hunks)
  • crates/torii/core/src/types.rs (2 hunks)
  • crates/torii/grpc/src/server/subscriptions/entity.rs (2 hunks)
  • crates/torii/grpc/src/server/subscriptions/event_message.rs (2 hunks)
🔇 Additional comments (7)
crates/torii/grpc/src/server/subscriptions/event_message.rs (4)

17-17: Import of OptimisticEventMessage is correct

Ohayo, sensei! The addition of use torii_core::types::OptimisticEventMessage; is appropriate for the updated implementation.


75-75: Update simple_broker to stream OptimisticEventMessage

Ohayo, sensei! The simple_broker now correctly streams OptimisticEventMessage. Ensure that any logic consuming this stream handles the new message type appropriately.


80-83: Initialize simple_broker with OptimisticEventMessage

Ohayo, sensei! Confirm that SimpleBroker::<OptimisticEventMessage>::subscribe() properly returns a stream of OptimisticEventMessage instances, and that this aligns with the expected behavior of your service.


88-88: Verify compatibility of OptimisticEventMessage fields in publish_updates

Ohayo, sensei! Please ensure that OptimisticEventMessage provides the fields used within publish_updates, such as id, keys, and updated_model, and that their data types and usages remain consistent with the previous EventMessage.

Run the following script to confirm the presence and structure of these fields:

crates/torii/grpc/src/server/subscriptions/entity.rs (2)

81-89: Ohayo, sensei! Updated simple_broker to use OptimisticEntity correctly

The changes to simple_broker in the Service::new method now utilize OptimisticEntity, which is consistent with the shift towards the optimistic concurrency model. This ensures that the service broadcasts updates using the new entity type.


92-95: Ohayo, sensei! Updated publish_updates to accept OptimisticEntity

The publish_updates function now accepts a reference to OptimisticEntity, aligning with the updated data model across the codebase. This change ensures that entity updates are handled optimistically as intended.

crates/torii/core/src/executor.rs (1)

18-18: Ohayo, sensei! Importing new types for optimistic handling

The addition of OptimisticEntity and OptimisticEventMessage to the imports aligns with their usage in the code.

Comment on lines +49 to +64
#[derive(FromRow, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct OptimisticEntity {
pub id: String,
pub keys: String,
pub event_id: String,
pub executed_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,

// this should never be None
#[sqlx(skip)]
pub updated_model: Option<Ty>,
#[sqlx(skip)]
pub deleted: bool,
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ohayo, sensei! Consider refactoring to avoid duplication.

The OptimisticEntity structure appears to be identical to the existing Entity structure. To maintain DRY (Don't Repeat Yourself) principles, consider using a type alias instead:

pub type OptimisticEntity = Entity;

This approach would reduce code duplication and make maintenance easier. If there are specific reasons for keeping them separate, please add a comment explaining the rationale.

Also, the updated_model field is still using Option<Ty>. If it should never be None as per the comment, consider changing it to:

pub updated_model: Ty,

If Option is necessary due to SQLx requirements, please add a comment explaining this constraint.

Comment on lines +81 to +94
#[derive(FromRow, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct OptimisticEventMessage {
pub id: String,
pub keys: String,
pub event_id: String,
pub executed_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,

// this should never be None
#[sqlx(skip)]
pub updated_model: Option<Ty>,
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ohayo again, sensei! Let's discuss the OptimisticEventMessage structure.

The OptimisticEventMessage structure is nearly identical to the EventMessage structure, with one key difference: it's missing the deleted field. Here are some suggestions:

  1. If OptimisticEventMessage doesn't need the deleted field, consider using a type alias with a custom type:
pub struct OptimisticEventMessageData {
    pub event_message: EventMessage,
    // Add any additional fields specific to OptimisticEventMessage
}

pub type OptimisticEventMessage = OptimisticEventMessageData;
  1. If the deleted field should be present, add it to maintain consistency:
#[sqlx(skip)]
pub deleted: bool,
  1. If there's a specific reason for the current implementation, please add a comment explaining the rationale behind the differences between EventMessage and OptimisticEventMessage.

These changes would improve code clarity and maintainability. What do you think, sensei?

Comment on lines 189 to 199
let optimistic_entity = OptimisticEntity {
id: entity_updated.id.clone(),
keys: entity_updated.keys.clone(),
event_id: entity_updated.event_id.clone(),
executed_at: entity_updated.executed_at.clone(),
created_at: entity_updated.created_at.clone(),
updated_at: entity_updated.updated_at.clone(),
updated_model: entity_updated.updated_model.clone(),
deleted: entity_updated.deleted,
};
SimpleBroker::publish(optimistic_entity);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring to reduce code duplication when creating OptimisticEntity

This block duplicates field cloning from entity_updated to create OptimisticEntity. To improve maintainability and reduce code duplication, consider implementing the From trait to convert EntityUpdated into OptimisticEntity.

Implement the From trait for OptimisticEntity:

impl From<&EntityUpdated> for OptimisticEntity {
    fn from(entity_updated: &EntityUpdated) -> Self {
        Self {
            id: entity_updated.id.clone(),
            keys: entity_updated.keys.clone(),
            event_id: entity_updated.event_id.clone(),
            executed_at: entity_updated.executed_at.clone(),
            created_at: entity_updated.created_at.clone(),
            updated_at: entity_updated.updated_at.clone(),
            updated_model: entity_updated.updated_model.clone(),
            deleted: entity_updated.deleted,
        }
    }
}

Then, you can simplify the code to:

let optimistic_entity = OptimisticEntity::from(&entity_updated);

Comment on lines 241 to 251
let optimistic_entity = OptimisticEntity {
id: entity_updated.id.clone(),
keys: entity_updated.keys.clone(),
event_id: entity_updated.event_id.clone(),
executed_at: entity_updated.executed_at.clone(),
created_at: entity_updated.created_at.clone(),
updated_at: entity_updated.updated_at.clone(),
updated_model: entity_updated.updated_model.clone(),
deleted: entity_updated.deleted,
};
SimpleBroker::publish(optimistic_entity);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring to reduce code duplication when creating OptimisticEntity

This block repeats the same cloning logic as before. Using the From trait implementation suggested earlier will reduce code duplication and improve maintainability.

Comment on lines 269 to 279
let optimistic_event_message = OptimisticEventMessage {
id: event_message.id.clone(),
keys: event_message.keys.clone(),
event_id: event_message.event_id.clone(),
executed_at: event_message.executed_at.clone(),
created_at: event_message.created_at.clone(),
updated_at: event_message.updated_at.clone(),
updated_model: event_message.updated_model.clone(),
};
SimpleBroker::publish(optimistic_event_message);

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring to reduce code duplication when creating OptimisticEventMessage

This block duplicates field cloning from event_message to create OptimisticEventMessage. To improve maintainability and reduce code duplication, consider implementing the From trait to convert EventMessageUpdated into OptimisticEventMessage.

Implement the From trait for OptimisticEventMessage:

impl From<&EventMessageUpdated> for OptimisticEventMessage {
    fn from(event_message: &EventMessageUpdated) -> Self {
        Self {
            id: event_message.id.clone(),
            keys: event_message.keys.clone(),
            event_id: event_message.event_id.clone(),
            executed_at: event_message.executed_at.clone(),
            created_at: event_message.created_at.clone(),
            updated_at: event_message.updated_at.clone(),
            updated_model: event_message.updated_model.clone(),
        }
    }
}

Then, you can simplify the code to:

let optimistic_event_message = OptimisticEventMessage::from(&event_message);

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 5550d4b and 7f43a45.

📒 Files selected for processing (1)
  • crates/torii/core/src/executor.rs (4 hunks)
🔇 Additional comments (2)
crates/torii/core/src/executor.rs (2)

18-18: Ohayo, sensei! LGTM!

The addition of OptimisticEntity and OptimisticEventMessage to the imports is correct and necessary for their usage in the file.


Line range hint 1-338: Ohayo, sensei! Let's wrap up this review!

Great job implementing optimistic updates for entities and event messages! The changes effectively introduce OptimisticEntity and OptimisticEventMessage to support this feature. To further enhance your code, consider implementing the From trait for both types as suggested in the previous comments. This will reduce code duplication and improve maintainability.

Overall, the changes look solid and will contribute to a more responsive and efficient system. Keep up the excellent work, sensei!

Comment on lines +189 to +200
let optimistic_entity = OptimisticEntity {
id: entity_updated.id.clone(),
keys: entity_updated.keys.clone(),
event_id: entity_updated.event_id.clone(),
executed_at: entity_updated.executed_at,
created_at: entity_updated.created_at,
updated_at: entity_updated.updated_at,
updated_model: entity_updated.updated_model.clone(),
deleted: entity_updated.deleted,
};
SimpleBroker::publish(optimistic_entity);

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ohayo, sensei! Consider implementing From trait for OptimisticEntity

The creation of OptimisticEntity duplicates field assignments from entity_updated. To reduce code duplication and improve maintainability, consider implementing the From trait for OptimisticEntity as suggested in a previous review comment.

Example implementation:

impl From<&EntityUpdated> for OptimisticEntity {
    fn from(entity: &EntityUpdated) -> Self {
        Self {
            id: entity.id.clone(),
            keys: entity.keys.clone(),
            event_id: entity.event_id.clone(),
            executed_at: entity.executed_at,
            created_at: entity.created_at,
            updated_at: entity.updated_at,
            updated_model: entity.updated_model.clone(),
            deleted: entity.deleted,
        }
    }
}

Then, you can simplify the code to:

let optimistic_entity = OptimisticEntity::from(&entity_updated);
SimpleBroker::publish(optimistic_entity);

This change will make the code more concise and easier to maintain, sensei!

Comment on lines +241 to +251
let optimistic_entity = OptimisticEntity {
id: entity_updated.id.clone(),
keys: entity_updated.keys.clone(),
event_id: entity_updated.event_id.clone(),
executed_at: entity_updated.executed_at,
created_at: entity_updated.created_at,
updated_at: entity_updated.updated_at,
updated_model: entity_updated.updated_model.clone(),
deleted: entity_updated.deleted,
};
SimpleBroker::publish(optimistic_entity);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ohayo again, sensei! Let's use that From trait here too!

This block is almost identical to the one in the QueryType::SetEntity branch. Once you've implemented the From trait for OptimisticEntity as suggested earlier, you can simplify this code in the same way:

let optimistic_entity = OptimisticEntity::from(&entity_updated);
SimpleBroker::publish(optimistic_entity);

This change will maintain consistency across the codebase and reduce duplication, making it easier to maintain and understand. Keep up the great work, sensei!

Comment on lines +269 to +279
let optimistic_event_message = OptimisticEventMessage {
id: event_message.id.clone(),
keys: event_message.keys.clone(),
event_id: event_message.event_id.clone(),
executed_at: event_message.executed_at,
created_at: event_message.created_at,
updated_at: event_message.updated_at,
updated_model: event_message.updated_model.clone(),
};
SimpleBroker::publish(optimistic_event_message);

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ohayo once more, sensei! Let's complete the trifecta with From for OptimisticEventMessage!

To maintain consistency and reduce code duplication, let's apply the same pattern we used for OptimisticEntity to OptimisticEventMessage. Consider implementing the From trait for OptimisticEventMessage:

impl From<&EventMessageUpdated> for OptimisticEventMessage {
    fn from(event: &EventMessageUpdated) -> Self {
        Self {
            id: event.id.clone(),
            keys: event.keys.clone(),
            event_id: event.event_id.clone(),
            executed_at: event.executed_at,
            created_at: event.created_at,
            updated_at: event.updated_at,
            updated_model: event.updated_model.clone(),
        }
    }
}

Then, simplify the code to:

let optimistic_event_message = OptimisticEventMessage::from(&event_message);
SimpleBroker::publish(optimistic_event_message);

This change will complete the refactoring trifecta, making your code more consistent, maintainable, and elegant. You're doing great work, sensei!

Copy link

codecov bot commented Oct 4, 2024

Codecov Report

Attention: Patch coverage is 86.27451% with 7 lines in your changes missing coverage. Please review.

Please upload report for BASE (main@771639c). Learn more about missing BASE report.
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ates/torii/grpc/src/server/subscriptions/entity.rs 50.00% 4 Missing ⚠️
crates/torii/core/src/types.rs 0.00% 2 Missing ⚠️
...rii/grpc/src/server/subscriptions/event_message.rs 80.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2466   +/-   ##
=======================================
  Coverage        ?   68.82%           
=======================================
  Files           ?      377           
  Lines           ?    48930           
  Branches        ?        0           
=======================================
  Hits            ?    33677           
  Misses          ?    15253           
  Partials        ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants