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

Add C++17 UDPServer ID handling #260

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Conversation

PioLing
Copy link
Contributor

@PioLing PioLing commented Dec 6, 2024

No description provided.

Copy link
Member

Choose a reason for hiding this comment

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

AI Review for src/Network/UdpServer.cpp:

Code Review: Patch to src/Network/UdpServer.cpp

Summary

This patch modifies the UdpServer class in the ZLToolKit project to improve UDP session ID handling using C++17 features. The primary changes involve using std::array instead of std::string for PeerIdType and using std::unordered_map with a custom type alias for better type safety.

Detailed Feedback

Code Overview

The patch refactors the PeerIdType to use std::array<uint8_t, PEERTYPELEN> which is more efficient and type-safe than the previous std::string. It also introduces a type alias SessionMapType for std::unordered_map<PeerIdType, SessionHelper::Ptr>, improving readability and maintainability. The changes aim to enhance performance and code clarity.

Strengths

  • Improved Type Safety: Using std::array for PeerIdType eliminates potential issues related to string manipulation and improves type safety.
  • Enhanced Readability: The SessionMapType alias makes the code easier to read and understand.
  • Potential Performance Improvement: std::array might offer slight performance gains compared to std::string in this context, especially for memory allocation and access.

Areas for Improvement

1. makeSockId Function

  • Issue: The assert(0) in the default case of the switch statement is not ideal. While it indicates an error, it abruptly terminates the program. A more robust approach would be to throw an exception or return an error code.
  • Suggestion: Replace assert(0) with a more graceful error handling mechanism. For example, throw a std::runtime_error exception with a descriptive message.
  • Example:
static UdpServer::PeerIdType makeSockId(sockaddr *addr, int) {
    UdpServer::PeerIdType ret(PEERTYPELEN, ' ');
    switch (addr->sa_family) {
        case AF_INET: {
            // ... existing code ...
            return ret;
        }
        case AF_INET6: {
            // ... existing code ...
            return ret;
        }
        default:
            throw std::runtime_error("Unsupported address family in makeSockId");
    }
}

2. Error Handling and Logging

  • Issue: While the code includes some logging, more detailed error handling and logging would improve debugging and troubleshooting. Specifically, consider logging the address family when an unsupported address family is encountered.
  • Suggestion: Add more informative log messages, especially in error scenarios. Consider using different log levels (e.g., ErrorL, WarnL) to categorize messages.

3. Const Correctness

  • Issue: The makeSockId function takes sockaddr *addr as a non-const parameter, even though it doesn't modify the address.
  • Suggestion: Change the parameter to const sockaddr *addr to improve const correctness.

4. SessionMapType Scope

  • Issue: The SessionMapType alias is defined locally within the UdpServer class. If this type is used elsewhere, it might be better to define it in a more accessible location (e.g., a header file).
  • Suggestion: Consider moving the SessionMapType alias to a header file if it's used outside of UdpServer.cpp.

Conclusion

The patch is a positive step towards improving the codebase. The use of std::array and the SessionMapType alias enhances type safety and readability. However, addressing the suggested improvements in error handling, logging, and const correctness will further enhance the robustness and maintainability of the code. The suggestion to potentially move SessionMapType depends on its usage elsewhere in the project.

TRANS_BY_GITHUB_AI_ASSISTANT

Copy link
Member

Choose a reason for hiding this comment

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

AI Review for src/Network/UdpServer.h:

Code Review: Patch to UdpServer.h

Summary

This patch modifies the UdpServer class to improve its handling of peer IDs, leveraging C++17 features for better performance and type safety. It's a patch review focusing on the changes introduced.

Detailed Feedback

Code Overview

The patch introduces a PeerIdType class, using std::array for C++17-compatible systems and std::string otherwise. It also adds a custom hash function for PeerIdType to improve the performance of the _session_map. The _session_map itself is updated to use the new PeerIdType and the custom hash function.

Strengths

  • Improved Type Safety: Using std::array for PeerIdType provides better type safety compared to std::string when C++17 is available.
  • Potential Performance Improvement: The custom hash function for PeerIdType should improve the performance of lookups in the _session_map, especially with a large number of sessions.
  • C++17 Compatibility: The code gracefully handles both C++17 and pre-C++17 environments.
  • Clearer Code Structure: The use of std::array and the custom hash function makes the code more readable and maintainable.

Areas for Improvement

1. PeerIdType Comparison

  • Issue: The operator== in PeerIdType performs a piecemeal comparison of the underlying data as uint64_t and uint16_t. This is less efficient and less readable than a direct memory comparison. It also assumes a specific memory layout which might be compiler-dependent.
  • Suggestion: Use std::memcmp for a more efficient and portable comparison. This avoids potential issues related to endianness and compiler-specific optimizations.
  • Example:
bool operator==(const PeerIdType &that) const {
    return std::memcmp(data(), that.data(), size()) == 0;
}

2. Error Handling in PeerIdType Constructor

  • Issue: The constructor of PeerIdType truncates the input length if it exceeds the array size, but it doesn't provide any indication of this truncation.
  • Suggestion: Consider adding a check and throwing an exception or returning an error code if the input length is invalid. This would make the code more robust.

3. Documentation

  • Issue: The comments in the code are mostly in English and Chinese. While the Chinese comments might be helpful for some developers, it's generally better to stick to a single language for better maintainability and internationalization.
  • Suggestion: Remove the Chinese comments and improve the English comments to be more concise and informative. Focus on explaining the why behind the code, not just the what.

4. PeerIdHash

  • Issue: The PeerIdHash uses std::string_view which might involve unnecessary copying.
  • Suggestion: If performance is critical, consider using a custom hash function that directly operates on the std::array data without creating a temporary std::string_view. This would avoid the overhead of constructing a std::string_view.

Conclusion

This patch is a significant improvement to the UdpServer class, enhancing type safety and potentially improving performance. Addressing the suggested improvements in PeerIdType comparison, error handling, documentation, and the custom hash function would further enhance the code's robustness, readability, and efficiency. The overall approach is well-structured and demonstrates good understanding of C++17 features.

TRANS_BY_GITHUB_AI_ASSISTANT

@wasphin
Copy link
Member

wasphin commented Dec 6, 2024

Can this be done in a separate file with related abstract definitions?

这个是不是可以单独一个文件做相关抽象定义?

TRANS_BY_GITHUB_AI_ASSISTANT

}
PeerIdType(size_t len, char fillChar) {
if (len > size()) {
len = size();
Copy link
Member

@xia-chu xia-chu Dec 6, 2024

Choose a reason for hiding this comment

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

I suggest removing the PeerIdType(size_t len, char fillChar) constructor,
In the case of C++11, let PeerIdType inherit from std::string,
In its default constructor, call resize(18) directly.

我建议删除PeerIdType(size_t len, char fillChar) 这个构造函数,
在c++11的情况下,让PeerIdType派生于std::string即可,
在他的默认构造函数中调用下resize(18)即可

TRANS_BY_GITHUB_AI_ASSISTANT

@PioLing
Copy link
Contributor Author

PioLing commented Dec 7, 2024

Can this be done in a separate file with related abstract definitions?

这个是不是可以单独一个文件做相关抽象定义?

TRANS_BY_GITHUB_AI_ASSISTANT

底层函数,又高频调用,不太适合抽象?

@wasphin
Copy link
Member

wasphin commented Dec 7, 2024

Can this be done in a separate file with related abstract definitions?

这个是不是可以单独一个文件做相关抽象定义?

TRANS_BY_GITHUB_AI_ASSISTANT

底层函数,又高频调用,不太适合抽象?

PeerIdType 本身已经是抽象了,主要是可以减少在 UdpServer 中的各种编译条件检查,简化这里的代码。

@PioLing
Copy link
Contributor Author

PioLing commented Dec 9, 2024

Can this be done in a separate file with related abstract definitions?

这个是不是可以单独一个文件做相关抽象定义?

TRANS_BY_GITHUB_AI_ASSISTANT

底层函数,又高频调用,不太适合抽象?

PeerIdType 本身已经是抽象了,主要是可以减少在 UdpServer 中的各种编译条件检查,简化这里的代码。

把SessionMapType 前移,然后UdpServer就只有一次 编译条件检查了

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.

4 participants