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

0.1.0 #43

Merged
merged 2 commits into from
Dec 29, 2024
Merged

0.1.0 #43

merged 2 commits into from
Dec 29, 2024

Conversation

soulgarden
Copy link
Member

@soulgarden soulgarden commented Dec 29, 2024

Switching from rabbitmq to nats

Removed RabbitMQ and its related components (broker, publisher, subscriber, rmq) in favor of NATS for messaging. Simplified the codebase by replacing redundant queue handling logic, updated route handling, and improved error reporting and response handling with NATS integration. Updated versioning and build scripts accordingly.
Introduced tracking of request processing duration using `std::time::Instant`. The elapsed time is now logged alongside request details to improve performance monitoring and debugging.
Copy link

coderabbitai bot commented Dec 29, 2024

Walkthrough

This pull request represents a significant architectural shift in the microservice, transitioning from RabbitMQ to NATS for messaging, and rewriting the service from Go to Rust. The changes span multiple files, updating dependencies, configuration, and core implementation. The version has been incremented from 0.0.15 to 0.1.0, reflecting the substantial modifications to the service's messaging infrastructure and overall design.

Changes

File Change Summary
.github/workflows/main.yml Updated Docker image tag from http2-0.0.15 to http2-0.1.0
Cargo.toml - Version updated to 0.1.0
- Removed RabbitMQ-related dependencies
- Added async-nats and rmp-serde
Dockerfile Updated base images to Rust 1.83.0 and Alpine 3.21
Makefile - Added --allow-staged to lint target
- Updated Docker image tag to http2-0.1.0
config.json - Removed RabbitMQ configuration
- Added NATS configuration
- Disabled debug mode
readme.md Updated description to highlight Rust rewrite and NATS messaging
src/ - Removed broker.rs, publisher.rs, rmq.rs, subscriber.rs
- Modified conf.rs, handlers.rs, main.rs, routes.rs to use NATS

Sequence Diagram

sequenceDiagram
    participant Client
    participant WebServer
    participant NATS
    participant Backend

    Client->>WebServer: HTTP Request
    WebServer->>NATS: Publish Request
    NATS-->>Backend: Forward Request
    Backend-->>NATS: Send Response
    NATS-->>WebServer: Deliver Response
    WebServer->>Client: HTTP Response
Loading

Poem

🐰 Hop, hop, a rabbit's tale of code so bright,
From RabbitMQ to NATS, we take flight!
Rust rewrites with elegance and grace,
Messaging evolved at lightning pace
A microservice dancing, version point-one-oh! 🚀


🪧 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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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: 7

🔭 Outside diff range comments (1)
.github/workflows/main.yml (1)

Docker build cache strategy needs improvement for version management

The current configuration shows potential inefficiencies in the Docker build cache strategy:

  • The build is using a fixed http2-latest tag for both cache-from and cache-to, while building version http2-0.1.0
  • This means all versions share the same cache, which could lead to:
    • Cache pollution between different versions
    • Unnecessary cache invalidation when versions diverge
    • Increased storage usage as the cache grows without bounds

Recommendations:

  • Use version-specific cache tags: http2-0.1.x-cache for better isolation
  • Implement a cache cleanup job for older versions
  • Consider using Docker's build cache backend (like BuildKit) for more efficient caching
🔗 Analysis chain

Line range hint 49-62: Verify cache configuration for optimal build performance.

The cache configuration uses the http2-latest tag. For version-specific builds, consider:

  1. Using version-specific cache tags
  2. Implementing cache pruning strategy
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check current cache usage and tags
curl -s -H "Authorization: Bearer $DOCKER_TOKEN" \
  "https://hub.docker.com/v2/repositories/${{ secrets.DOCKER_HUB_USERNAME }}/swup/tags/" | \
  jq '.results[] | select(.name | contains("http2-")) | {name: .name, last_updated: .last_updated}'

Length of output: 273


Script:

#!/bin/bash
# Let's check the workflow file for cache configuration patterns
rg -A 5 "cache-from|cache-to" .github/workflows/main.yml

# Also check for any other Docker-related cache configurations
rg "docker.*cache" .github/workflows/main.yml

# Look for any version or tag patterns in the workflow
rg "tags:|version:" .github/workflows/main.yml

Length of output: 725

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dbeeb14 and 6d78107.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • .github/workflows/main.yml (2 hunks)
  • Cargo.toml (2 hunks)
  • Dockerfile (2 hunks)
  • Makefile (1 hunks)
  • config.json (2 hunks)
  • readme.md (1 hunks)
  • src/broker.rs (0 hunks)
  • src/conf.rs (1 hunks)
  • src/handlers.rs (4 hunks)
  • src/main.rs (3 hunks)
  • src/publisher.rs (0 hunks)
  • src/rmq.rs (0 hunks)
  • src/routes.rs (2 hunks)
  • src/subscriber.rs (0 hunks)
💤 Files with no reviewable changes (4)
  • src/publisher.rs
  • src/rmq.rs
  • src/broker.rs
  • src/subscriber.rs
🧰 Additional context used
🪛 LanguageTool
readme.md

[uncategorized] ~6-~6: This verb does not appear to agree with the subject. Consider using a different form.
Context: ...er to handle incoming HTTP requests and forward them for asynchronous processing by a b...

(AI_EN_LECTOR_REPLACEMENT_VERB_AGREEMENT)

🔇 Additional comments (36)
src/conf.rs (2)

22-22: New nats field complements the switch to NATS.
This line properly introduces a NATS configuration field, aligning with the removal of the RabbitMQ field.


34-34: Improved default value handling.
Using unwrap_or_else for CFG_PATH provides a clear fallback to ./config.json. Good simplification over the previous match statement approach.

src/main.rs (5)

1-1: Enforcing warnings as errors improves code quality.
#![deny(warnings)] ensures that all warnings must be resolved before build completion, preventing technical debt.


4-4: Importing SinkExt from futures.
This import is presumably used for advanced asynchronous functionality (e.g., sending messages). Ensure it’s utilized or remove if unused.


8-8: Expanded networking imports.
The introduction of Ipv4Addr and SocketAddr is consistent with explicit server address binding.


54-54: Passing NATS client to route builder.
This is a clear approach for centralizing resource usage in route handlers. Nicely done.


77-77: Graceful NATS client close.
Closing the NATS client when shutting down ensures clean disconnection. Confirm whether error outcomes from .close() need special handling/logging.

src/handlers.rs (15)

1-1: Imports for structured error handling.
Inclusion of Error and Errors fosters consistent error serialization. Ensure these error structures remain aligned with your JSON:API spec usage.


14-14: Using rmp_serde::Serializer.
MessagePack serialization can be efficient. Confirm that all consumers are compatible with this format.


45-50: Refactored not_found handler.
Using a centralized create_error_response consistently handles JSON:API error formatting. Good approach.


64-68: Gathering request context.
Capturing a new UUID and timestamp is an excellent approach for monitoring or tracing requests.


73-73: Optional token extraction with fallback.
map_or_else for the authorization token usage is concise and robust.


79-82: Setting up custom NATS HeaderMap.
Storing the request ID in headers can facilitate cross-service request traceability.


84-88: Serializing the request with MessagePack.
Combining Vec<u8> buffer allocation and rmp_serde::Serializer is a standard approach for NATS message encoding.


90-90: Explicit status_code variable.
Storing status code in a separate variable fosters consistent logging later in the flow.


92-101: NATS request usage.
Requests with headers allow for passing custom metadata (like a status code). Great usage of request_with_headers.


103-107: Timeout error handling.
Uses StatusCode::REQUEST_TIMEOUT upon NATS error, plus logging. Good practice for debugging message flow issues.


111-118: Logging to capture performance metrics.
Logging elapsed_time can help gauge performance hotspots. This is beneficial for monitoring.


123-128: Centralized JSON:API error response builder.
Encapsulating error response creation clarifies error handling.


131-133: Populating JSON:API error fields.
Ensures a structured error output for clients.


142-142: Setting the status code on the builder.
Combines data serialization with the correct HTTP status. Straightforward approach.


151-154: Centralized JSON:API success response builder.
Similarly, create_response fosters uniform success responses with minimal repetition in your handlers.

src/routes.rs (5)

1-1: Introducing async_nats::Client for router-level injection.
This replacement signals the removal of RabbitMQ-based services in favor of direct NATS usage.


8-8: Shared NATS usage.
Using Arc<RwLock<>> ensures concurrency across routes, matching the approach in main.rs.


15-15: Defining API_V1 constant.
This adds clarity and consistency for versioned routes.


19-19: Passing NATS client to router builder.
Swapping out the old broker/publisher references for the NATS client aligns with the broader message system transition.


32-79: Refactored routes referencing API_V1.
Replacing hardcoded endpoints with format!("{}/...", API_V1) fosters easy versioning changes. Each route calls the unified proxy method or dedicated handlers, consistent with the newly introduced NATS-based flow.

Makefile (2)

5-5: Refined Clippy lint command.
--allow-staged can help ensure that partially committed changes are properly linted while in development.


8-9: Docker build and push version bump.
Upgrading from http2-0.0.15 to http2-0.1.0 aligns with the semver jump. Remember to update references down the line.

config.json (2)

17-17: Confirm impact of disabling debug mode

The debug mode has been disabled. Ensure proper logging and monitoring are in place for production troubleshooting.


4-6: 🧹 Nitpick (assertive)

Verify NATS configuration completeness

The NATS configuration appears minimal. Consider whether authentication credentials are required for your NATS setup. Also, the hardcoded internal domain might need to be configurable for different environments.

Consider:

  1. Using environment variables for the host value
  2. Adding authentication if required
  3. Adding connection options like timeout, max reconnects, etc.
readme.md (1)

6-6: 🧹 Nitpick (assertive)

Fix grammar in service description

The verb agreement needs correction in this sentence.

-It acts as a web server to handle incoming HTTP requests and forward them for asynchronous processing by a backend service.
+It acts as a web server to handle incoming HTTP requests and forwards them for asynchronous processing by a backend service.

Likely invalid or redundant comment.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~6-~6: This verb does not appear to agree with the subject. Consider using a different form.
Context: ...er to handle incoming HTTP requests and forward them for asynchronous processing by a b...

(AI_EN_LECTOR_REPLACEMENT_VERB_AGREEMENT)

Dockerfile (2)

11-11: 🧹 Nitpick (assertive)

Verify Alpine base image security

The Alpine base image has been updated to 3.21. Ensure there are no known vulnerabilities in this version.

Consider implementing container scanning in your CI/CD pipeline to regularly check for security vulnerabilities in base images.


1-1: Verify Rust version compatibility

The Rust version has been updated to 1.83.0. Ensure all dependencies are compatible with this version.

Run the following to check dependency compatibility:

✅ Verification successful

Rust 1.83.0 update appears compatible with the project

Based on the verification:

  • No explicit MSRV (Minimum Supported Rust Version) is specified in Cargo.toml or through rust-toolchain files
  • All dependencies use semantic versioning with caret requirements (^), which ensures compatibility with minor version updates
  • No complex build scripts or toolchain-specific configurations were found
  • The project uses standard dependencies (tokio, axum, uuid) that are well-maintained and compatible with Rust 1.83.0
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if Cargo.toml exists and contains version constraints
if [ -f "Cargo.toml" ]; then
    echo "Checking Rust version requirements in dependencies..."
    rg 'rust-version' Cargo.toml -A 2
    
    echo "Checking for version-specific features or dependencies..."
    rg '^\[.*\]' Cargo.toml -A 5
fi

Length of output: 738


Script:

#!/bin/bash
# Let's check for any Rust-specific configuration files and MSRV indicators
echo "Checking for rust-toolchain.toml..."
if [ -f "rust-toolchain.toml" ]; then
    cat rust-toolchain.toml
fi

echo -e "\nChecking for rust-toolchain file..."
if [ -f "rust-toolchain" ]; then
    cat rust-toolchain
fi

echo -e "\nChecking for .cargo/config.toml..."
if [ -f ".cargo/config.toml" ]; then
    cat ".cargo/config.toml"
fi

# Let's also check if there are any build.rs files that might have version-specific code
echo -e "\nChecking for build.rs files..."
fd "build.rs$"

Length of output: 439

Cargo.toml (2)

3-3: Version bump appropriately reflects breaking changes.

The increment to 0.1.0 correctly follows semantic versioning for the architectural changes (Go to Rust, RabbitMQ to NATS).


25-26: Verify NATS client version compatibility.

The async-nats dependency is pinned to 0.38.0 while other dependencies use caret requirements. Consider using a caret requirement for consistency unless there's a specific reason for version pinning.

pub allowed_origins: Vec<String>,
pub is_debug: bool,
}

#[derive(Deserialize, Clone)]
pub struct RmqConf {
pub struct NatsConf {
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider naming clarity or additional NATS configuration.
Currently, NatsConf includes only a host field. For potential expansion (e.g., credentials, port, or TLS settings), consider clarifying the field name (like url) or adding more fields.

Comment on lines +46 to +52
let nats_client = Arc::new(RwLock::new(
async_nats::ConnectOptions::new()
.ping_interval(std::time::Duration::from_secs(10))
.request_timeout(Some(std::time::Duration::from_secs(10)))
.connect(conf.nats.host)
.await?,
));
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Establishing concurrent-safe NATS client.
Wrapping the NATS client in Arc<RwLock<>> ensures safe concurrent access and straightforward usage across async functions. Check if you need the extra overhead of RwLock or if Arc<Mutex<>> would suffice, given usage patterns.

tokio::task::spawn(async move { broker.run(router_shutdown_notify).await }),
tokio::task::spawn(async move { sub_svc.run(sub_svc_shutdown_notify).await }),
);
let result = tokio::try_join!(tokio::task::spawn(server),);
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Excessive usage of tokio::try_join! for a single future.
We’re awaiting only one task. If there’s no intention to add more concurrency soon, consider using .await directly for readability.


use super::events::HttpReq;
use super::responses::statuses::{Attributes, Statuses, StatusesData};

const TIMEOUT: u64 = 30;
const SUBJECT: &str = "http";
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Defining a static subject for NATS.
Hardcoding "http" as the subject may be enough for your architecture. If more subjects are needed later, consider enumerations or config.

@@ -79,119 +59,102 @@
Path(user_values): Path<HashMap<String, String>>,
Query(query_args): Query<HashMap<String, String>>,
authorization: Option<TypedHeader<Authorization<Bearer>>>,
Extension(pub_svc): Extension<Arc<RwLock<Publisher>>>,
Extension(broker): Extension<Arc<Broker>>,
Extension(nats): Extension<Arc<RwLock<Client>>>,
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Accepting the NATS client in proxy.
Passing in Arc<RwLock<Client>> allows flexible messaging calls within handlers. Ensure lock usage is minimized to avoid performance overhead.

Comment on lines +5 to +7
The second version of a lightweight microservice, rewritten from Go to Rust.
It acts as a web server to handle incoming HTTP requests and forward them for asynchronous processing by a backend service.
This version uses NATS for messaging, ensuring high performance, scalability, and reliability.
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider enhancing documentation

While the current description effectively communicates the architectural changes, consider adding:

  1. Configuration guide for NATS setup
  2. Migration guide from v1 (Go/RabbitMQ) to v2 (Rust/NATS)
  3. Performance comparison between old and new versions
🧰 Tools
🪛 LanguageTool

[uncategorized] ~6-~6: This verb does not appear to agree with the subject. Consider using a different form.
Context: ...er to handle incoming HTTP requests and forward them for asynchronous processing by a b...

(AI_EN_LECTOR_REPLACEMENT_VERB_AGREEMENT)

@@ -46,7 +46,7 @@ jobs:
context: .
file: Dockerfile
push: false
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/swup:http2-0.0.15
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/swup:http2-0.1.0
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Docker image tags are consistent with package version.

The Docker image tags have been correctly updated to match the 0.1.0 version bump.

Consider the following improvements to the CI/CD pipeline:

  1. Add multi-architecture support using matrix builds
  2. Include automated testing step before building
  3. Consider using Docker image digest pinning for better reproducibility

Also applies to: 60-60

@soulgarden soulgarden merged commit 1cf533b into main Dec 29, 2024
5 checks passed
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.

1 participant