Skip to content

✨ feat(config): add RabbitMQ configuration support#10

Open
safroalex wants to merge 2 commits intomasterfrom
feature/7C59-broker
Open

✨ feat(config): add RabbitMQ configuration support#10
safroalex wants to merge 2 commits intomasterfrom
feature/7C59-broker

Conversation

@safroalex
Copy link

@safroalex safroalex commented Apr 12, 2025

  • introduce RabbitMQ configuration in config struct
  • add default URL for RabbitMQ connection

✨ feat(service): implement RabbitMQ message consumption

  • create a method to start consuming messages from RabbitMQ
  • handle different request types for train routes, carriages, and station searches

📝 docs(README): update gRPC run command instruction

  • modify command to include configuration file path for server startup

💄 style(.gitignore): clean up ignored files

  • add .DS_Store to ignored files
  • ensure vendor directory is ignored

✅ test(queue): create test queue for RabbitMQ messages

  • implement a test program to send messages to RabbitMQ queue
  • include test cases for different request types and payloads

Summary by CodeRabbit

  • New Features

    • Integrated asynchronous messaging to handle various requests.
    • Added new configuration options for messaging support and updated server startup instructions.
  • Chores

    • Updated project ignore settings to exclude common system files and vendor directories.
    • Introduced a new dependency for RabbitMQ interactions.

- introduce RabbitMQ configuration in config struct
- add default URL for RabbitMQ connection

✨ feat(service): implement RabbitMQ message consumption

- create a method to start consuming messages from RabbitMQ
- handle different request types for train routes, carriages, and station searches

📝 docs(README): update gRPC run command instruction

- modify command to include configuration file path for server startup

💄 style(.gitignore): clean up ignored files

- add .DS_Store to ignored files
- ensure vendor directory is ignored

✅ test(queue): create test queue for RabbitMQ messages

- implement a test program to send messages to RabbitMQ queue
- include test cases for different request types and payloads
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 12, 2025

Walkthrough

This pull request updates configuration and service initialization while adding asynchronous RabbitMQ message handling. The changes modify the .gitignore and README.md files, update the gRPC server startup command, and adjust configuration values in the YAML and Go configuration files. The service now logs the RabbitMQ URL, is initialized with configuration parameters, and starts an asynchronous consumer to process messages from a RabbitMQ queue. Additionally, new files are introduced for testing RabbitMQ functionality and handling message consumption.

Changes

File(s) Change Summary
.gitignore Added .DS_Store entry; re-enabled the vendor directory by uncommenting the existing line.
README.md Updated the gRPC server start command from go run cmd/rzd-scraper/main.go to include the configuration file argument (-config=config.yml).
cmd/rzd-scraper/main.go
internal/service/service.go
Updated service initialization to accept a configuration object; added logging for RabbitMQ URL in main.go; modified service constructor signature in service.go.
config.yml
pkg/config/config.go
Modified configuration values (e.g., quoting LANGUAGE and PORT, increasing TIMEOUT); added a new RabbitMQ configuration section and corresponding struct field/type for RabbitMQ settings.
go.mod Added a new dependency: github.com/streadway/amqp v1.1.0 as an indirect requirement.
test_queue.go New file that establishes a RabbitMQ connection, declares a durable queue with priority support, and sends test messages with JSON payloads to simulate different request types.
internal/infrastructure/rzd/rabbitmq/consumer.go New file implementing a RabbitMQ consumer with connection handling, message consumption, and error logging.
internal/transports/rabbitmq/handler.go New file implementing a RabbitMQ message handler that processes incoming messages and invokes service methods based on the request type.

Sequence Diagram(s)

sequenceDiagram
    participant T as TestQueue
    participant R as RabbitMQ
    participant S as Service

    T->>R: Publish message (JSON with requestType)
    R->>S: Deliver message from "rzd_queue"
    S->>S: Parse JSON and determine request type
    alt requestType = getTrainRoutes
        S->>S: Process train routes request
    else requestType = getTrainCarriages
        S->>S: Process train carriages request
    else requestType = searchStation
        S->>S: Process station search request
    end
    S->>S: Log/send constructed response
Loading

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ Finishing Touches
  • 📝 Docstrings were successfully generated. (🔄 Check again to generate docstrings again)

🪧 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.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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.

@safroalex safroalex requested a review from Fascinat0r April 12, 2025 20:57
Copy link
Contributor

@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

🧹 Nitpick comments (7)
config.yml (2)

14-15: RabbitMQ configuration looks appropriate.
Explicitly specifying the RabbitMQ URL here is clear, but confirm that sensitive credentials are not exposed in production. Using environment variables or a secret management mechanism is often safer for production deployments.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 15-15: no new line character at the end of file

(new-line-at-end-of-file)


15-15: Missing newline at the end of the file.
Some tools and editors may flag the lack of a trailing newline. Consider adding a newline to align with YAML best practices.

Apply this diff to add a newline at EOF:

 RabbitMQ:
   URL: "amqp://guest:guest@localhost:5672/"
+ 
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 15-15: no new line character at the end of file

(new-line-at-end-of-file)

pkg/config/config.go (1)

34-37: New RabbitMQ struct introduced.
The default URL and environment variable mapping look correct. Consider externalizing credentials if this service is deployed in production or if multiple environments need different credentials.

test_queue.go (1)

1-95: Consider graceful exits and durability.
This file effectively demonstrates sending test messages to RabbitMQ with a durable queue and priority. However, note the following potential improvements:

  1. Replace log.Fatalf with gentler error handling if you anticipate partial failures and want the program to proceed in certain situations.
  2. Use a context or signal handling to gracefully shut down the connection instead of abruptly terminating after a log.Fatalf.
  3. Evaluate whether you need additional acknowledgment flags or publisher confirm modes to ensure message delivery.
internal/service/service.go (3)

43-113: Add reconnection and shutdown logic in startConsuming.
Currently, select {} keeps the consumer running indefinitely. If RabbitMQ goes down or a network fault occurs, the channel won’t reconnect. A robust production approach often includes:

  1. Reconnection attempts after channel/connection failures.
  2. Cancelation or shutdown signals that can close channels and connections gracefully.

163-181: Optional validation for handleSearchStation fields.
Likewise, ensuring the presence and correct type of query and compactMode can safeguard against malformed messages.


183-186: Design a real return path for responses.
sendResponse currently logs the response. If you need further downstream processing (e.g., replying to another queue), now is the time to outline that approach.

Would you like help implementing a full reply queue mechanism or another delivery option?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 53c294d and 2278270.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (8)
  • .gitignore (1 hunks)
  • README.md (1 hunks)
  • cmd/rzd-scraper/main.go (1 hunks)
  • config.yml (2 hunks)
  • go.mod (1 hunks)
  • internal/service/service.go (3 hunks)
  • pkg/config/config.go (2 hunks)
  • test_queue.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
internal/service/service.go (4)
pkg/config/config.go (2)
  • Config (11-15)
  • RabbitMQ (35-37)
internal/service/interface.go (1)
  • Service (11-18)
internal/domain/models.go (4)
  • Service (68-72)
  • GetTrainRoutesParams (80-88)
  • GetTrainCarriagesParams (91-97)
  • SearchStationParams (100-103)
internal/domain/enums.go (3)
  • Direction (5-5)
  • TrainType (34-34)
  • TrainSearchType (13-13)
cmd/rzd-scraper/main.go (3)
pkg/config/config.go (2)
  • RabbitMQ (35-37)
  • RZD (18-27)
internal/infrastructure/rzd/rzd_client.go (1)
  • NewRzdClient (38-77)
internal/service/service.go (1)
  • New (23-27)
🪛 YAMLlint (1.35.1)
config.yml

[error] 15-15: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (8)
.gitignore (2)

111-111: Good practice for dependency management

Uncommenting the vendor directory in .gitignore is a good practice for Go projects using modules, as it prevents the vendor directory from being committed to the repository.


113-113: Proper exclusion of system files

Adding .DS_Store to the gitignore is a good practice to prevent macOS system files from being committed to the repository.

README.md (1)

53-53: Documentation updated correctly

The README has been properly updated to include the -config=config.yml flag, which matches the command-line flag support added in the application.

cmd/rzd-scraper/main.go (1)

50-51: Correctly updated service initialization

The service initialization has been properly updated to pass the configuration object, which is required for the new RabbitMQ functionality. This change correctly enables the service to access RabbitMQ configuration parameters.

config.yml (2)

2-3: Validate the updated timeout value carefully.
Changing the TIMEOUT from a small integer to 2000 (presumably milliseconds) is a substantial increase. Verify that this value reflects the desired behavior for your requests and does not unintentionally cause extremely delayed timeouts.


12-12: Port string usage is acceptable.
Converting the port into a quoted string is fine since YAML can interpret numeric or string values for ports. This change does not introduce any functional issues.

pkg/config/config.go (1)

12-14: Configuration structure expanded with RabbitMQ field.
Adding a RabbitMQ field is consistent with your YAML configuration. Ensure all references to cfg.RabbitMQ are handled gracefully throughout the codebase.

internal/service/service.go (1)

6-14: New imports for RabbitMQ and JSON handling.
These additions are appropriate for message consuming and payload unmarshalling. No issues here.

github.com/spf13/viper v1.12.0 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect
github.com/streadway/amqp v1.1.0 // indirect
Copy link
Contributor

@coderabbitai coderabbitai bot Apr 12, 2025

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify the RabbitMQ client library choice

The addition of the github.com/streadway/amqp package is appropriate for implementing RabbitMQ functionality. However, it's worth noting that this library is no longer actively maintained.


🌐 Web query:

Is github.com/streadway/amqp still actively maintained? What are the current recommended Go libraries for RabbitMQ?

💡 Result:

The github.com/streadway/amqp library is no longer actively maintained[1][4]. The repository explicitly warns users to consider alternatives like rabbitmq/amqp091-go, which is now the official successor maintained by the RabbitMQ core team[1][3][7].


Recommended Go Libraries for RabbitMQ

  1. rabbitmq/amqp091-go

    • Official fork of streadway/amqp, maintained by the RabbitMQ team[3][7].
    • Retains most API elements from the original but open to reasonable breaking changes[3].
    • Supports modern Go versions and RabbitMQ server releases[7][10].
    • Example usage:
      import amqp "github.com/rabbitmq/amqp091-go"
  2. wagslane/go-rabbitmq

    • A higher-level wrapper around amqp091-go with built-in reconnection logic and easier abstractions[2].
    • Ideal for applications requiring automatic recovery from network failures[2].
    • Example consumer setup:
      consumer, err := rabbitmq.NewConsumer(
        conn, 
        "my_queue",
        rabbitmq.WithConsumerOptionsExchangeDeclare,
      )

Key Differences Between Libraries

Feature streadway/amqp amqp091-go go-rabbitmq
Maintenance Status Unmaintained[1][4] Actively maintained[3] Actively maintained[2]
Reconnection Logic Manual implementation Manual implementation Built-in[2]
API Stability Frozen Evolving[3][7] Wrapper with defaults
Recommended Use Case Legacy systems New projects Simplified workflows

For most new projects, rabbitmq/amqp091-go is the baseline recommendation[3][5], while go-rabbitmq offers convenience for common patterns like pub/sub with resilience[2].

Citations:


Action Required: Update RabbitMQ Client Library

  • Location: go.mod (Line 191)
  • Current Dependency: github.com/streadway/amqp v1.1.0 (indirect)
  • Issue: This library is no longer actively maintained.
  • Recommendation: Consider migrating to the officially supported rabbitmq/amqp091-go, which is maintained by the RabbitMQ team. Alternatively, if higher-level abstractions or built-in reconnection support are desired, explore options like wagslane/go-rabbitmq.

Please update the dependency accordingly to ensure long-term maintenance and compatibility.

Copy link
Member

Choose a reason for hiding this comment

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

Да, используй rabbitmq/amqp091-go

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

I'll search for where the AMQP library is actually used in the code:

Let me also check the test_queue.go file which seems to be using RabbitMQ:

flowchart TB
    A(["Migrate to rabbitmq/amqp091-go"])
    A --o B["Update go.mod dependency"]
    A --o C["Update import in service.go"]
    A --o D["Update import in test_queue.go (if exists)"]
    
    B --o E["Remove streadway/amqp"]
    B --o F["Add rabbitmq/amqp091-go"]
    
    C --o G["Change import path"]
    C --o H["Verify API compatibility"]
    
    D --o I["Locate test_queue.go"]
    D --o J["Change import path"]
Loading

@Fascinat0r Я подготовил план для перехода на библиотеку rabbitmq/amqp091-go. Миграция должна быть довольно простой, поскольку API обеих библиотек почти идентичны. Основные изменения:

  1. Обновите зависимость в go.mod:

    - github.com/streadway/amqp v1.1.0 // indirect
    + github.com/rabbitmq/amqp091-go v1.8.1 // indirect
  2. Измените импорт в internal/service/service.go:

    - import "github.com/streadway/amqp"
    + import "github.com/rabbitmq/amqp091-go"

    Или с псевдонимом для сохранения совместимости с существующим кодом:

    - import "github.com/streadway/amqp"
    + import amqp "github.com/rabbitmq/amqp091-go"
  3. Если файл test_queue.go существует, обновите импорт аналогичным образом.

После этих изменений ваш код должен работать без дополнительных модификаций, так как rabbitmq/amqp091-go — это официальный форк streadway/amqp с сохранением API.


🏁 Script executed:

#!/bin/bash
# Search for imports of streadway/amqp in the codebase
rg "import.*streadway/amqp" -A 3

Length of output: 34


🏁 Script executed:

#!/bin/bash
# Search for "amqp" usage in the codebase
rg "amqp\." -A 3

Length of output: 1682


🏁 Script executed:

#!/bin/bash
# Check the content of test_queue.go
cat test_queue.go

Length of output: 2725


🏁 Script executed:

#!/bin/bash
# Search for RabbitMQ related code
rg -i "rabbit|amqp" --no-filename

Length of output: 1796


🏁 Script executed:

#!/bin/bash
# Check the internal/service/service.go file mentioned in the AI summary
cat internal/service/service.go

Length of output: 1263


🏁 Script executed:

#!/bin/bash
# Check if test_queue.go exists in the root directory
find . -name "test_queue.go"

Length of output: 44


🏁 Script executed:

#!/bin/bash
# Let's look at the AI summary for test_queue.go again
cat test_queue.go 2>/dev/null || echo "File not found, checking in other directories"
find . -type f -exec grep -l "streadway/amqp" {} \;

Length of output: 2865


🏁 Script executed:

# Search for test_queue.go file in the repository
find . -type f -name "test_queue.go" -o -name "*test*queue*.go"

Length of output: 79


🌐 Web query:

Are there API differences between streadway/amqp and rabbitmq/amqp091-go?

💡 Result:

The streadway/amqp and rabbitmq/amqp091-go libraries are both Go clients for AMQP 0.9.1, but they differ in maintenance, API evolution philosophy, and minor implementation details. Here are the key differences:


Summary of Differences

  • Maintenance Status: streadway/amqp is unmaintained, while rabbitmq/amqp091-go is actively developed by the RabbitMQ team.
  • API Stability: rabbitmq/amqp091-go allows breaking changes for improvements, unlike streadway/amqp, which prioritizes strict API stability.
  • Package Name: The import path differs, requiring code adjustments during migration.

Key API and Usage Differences

1. Package Name and Import

  • streadway/amqp:
    import "github.com/streadway/amqp"
  • rabbitmq/amqp091-go:
    amqp "github.com/rabbitmq/amqp091-go"  // Aliasing for easier migration

2. Context-Aware Methods

rabbitmq/amqp091-go introduces context support in methods like PublishWithContext[3][6], while streadway/amqp uses older conventions:

// rabbitmq/amqp091-go
err = ch.PublishWithContext(ctx, exchange, routingKey, mandatory, immediate, amqp.Publishing{...})

// streadway/amqp (no context)
err = ch.Publish(exchange, routingKey, mandatory, immediate, amqp.Publishing{...})

3. Public API Evolution

  • rabbitmq/amqp091-go is open to breaking changes for long-term improvements, such as optimizations or ergonomic adjustments[1][6].
  • streadway/amqp strictly avoids breaking changes, even at the cost of stagnation[4][8].

4. Error Handling and Features

Both libraries share core functionality (e.g., queue declaration, message publishing), but differences include:

  • Authentication Mechanisms: rabbitmq/amqp091-go explicitly restricts support to PLAIN and EXTERNAL auth[1][6], while streadway/amqp leaves room for community extensions[8].
  • Protocol Events: rabbitmq/amqp091-go acknowledges limitations in ordering guarantees for events like basic.return and basic.ack due to Go channel semantics[1][6].

Migration Considerations

  • Use an import alias to minimize code changes[1][6].
  • Update method calls to use context-aware variants where applicable.
  • Review error-handling logic, as reconnection strategies remain the caller’s responsibility in both libraries[1][4].

Recommendation

For new projects, rabbitmq/amqp091-go is the preferred choice due to active maintenance and modern API practices. Existing projects using streadway/amqp should migrate for long-term support[4][8].

Citations:


@Fascinat0r По результатам анализа кода, я обнаружил, что библиотека streadway/amqp используется в следующих файлах:

  1. test_queue.go (в корневой директории)
  2. internal/infrastructure/rzd/rabbitmq/consumer.go

Вот подробный план миграции на rabbitmq/amqp091-go:

1. Обновите зависимость в go.mod

- github.com/streadway/amqp v1.1.0 // indirect
+ github.com/rabbitmq/amqp091-go v1.8.1 // indirect

2. Обновите импорт в test_queue.go

import (
    "log"
    "time"
-   "github.com/streadway/amqp"
+   amqp "github.com/rabbitmq/amqp091-go"
    "encoding/json"
)

3. Обновите импорт в internal/infrastructure/rzd/rabbitmq/consumer.go

import (
    "log"
-   "github.com/streadway/amqp"
+   amqp "github.com/rabbitmq/amqp091-go"
)

Код должен продолжать работать без дополнительных изменений, так как API практически идентичен. В будущем вы можете рассмотреть возможность использования новых возможностей rabbitmq/amqp091-go, таких как методы с поддержкой контекста (например, PublishWithContext вместо Publish).

После выполнения этих изменений выполните go mod tidy для обновления go.sum и загрузки новой зависимости.

✏️ Learnings added
Learnt from: Fascinat0r
PR: Chaika-Team/ChaikaRzdScraper#10
File: go.mod:191-191
Timestamp: 2025-04-13T16:07:28.193Z
Learning: Следует использовать библиотеку `github.com/rabbitmq/amqp091-go` вместо `github.com/streadway/amqp` для работы с RabbitMQ, так как последняя больше не поддерживается.

Learnt from: Fascinat0r
PR: Chaika-Team/ChaikaRzdScraper#10
File: go.mod:191-191
Timestamp: 2025-04-13T16:07:28.193Z
Learning: При работе с RabbitMQ в Go следует использовать библиотеку `github.com/rabbitmq/amqp091-go` вместо устаревшей `github.com/streadway/amqp`, так как первая активно поддерживается командой RabbitMQ и является официальным преемником.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

---

⏳ Preparing changes...

Copy link
Contributor

Choose a reason for hiding this comment

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

A summary of the edits CodeRabbit can apply:

We will update the go.mod file to replace the dependency on github.com/streadway/amqp v1.1.0 with github.com/rabbitmq/amqp091-go v1.8.1.

We will update the import statement in internal/service/service.go to use the officially supported RabbitMQ library.

We will update the import in test_queue.go to replace the deprecated RabbitMQ library with the new one.

The dependency in go.mod will be updated to replace github.com/streadway/amqp with github.com/rabbitmq/amqp091-go.

The import in internal/service/service.go will be updated to use github.com/rabbitmq/amqp091-go instead of github.com/streadway/amqp.

If the file test_queue.go exists, its import will be updated to use github.com/rabbitmq/amqp091-go.

The import in internal/infrastructure/rzd/rabbitmq/consumer.go will be updated to use github.com/rabbitmq/amqp091-go.

This change will update the RabbitMQ client dependency in go.mod to use rabbitmq/amqp091-go for long-term maintenance.

This update will modify the RabbitMQ client import in internal/service/service.go to use rabbitmq/amqp091-go instead of streadway/amqp.

This update will modify test_queue.go to change the RabbitMQ client import to use rabbitmq/amqp091-go, ensuring consistent dependency usage across the codebase.

We will update the go.mod file to replace the unmaintained dependency

github.com/streadway/amqp v1.1.0 // indirect

with the maintained

github.com/rabbitmq/amqp091-go v1.8.1 // indirect

.

We will update the import statements in

internal/service/service.go

to use

github.com/rabbitmq/amqp091-go

instead of the deprecated

github.com/streadway/amqp

.

We will update the import in

test_queue.go

to use

github.com/rabbitmq/amqp091-go

instead of

github.com/streadway/amqp

.

A plan of each step that CodeRabbit will take in order to execute the edits for each file (with inline rough draft snippets):

✏️ go.mod

Locate the dependency declaration:

github.com/streadway/amqp v1.1.0 // indirect


Replace it with:

github.com/rabbitmq/amqp091-go v1.8.1 // indirect


Run

go mod tidy

to update and clean the module dependencies.

✏️ internal/service/service.go

Locate the current import:

"github.com/streadway/amqp"


Replace it with the new import:

"github.com/rabbitmq/amqp091-go"

(Optionally, you can alias it as

amqp

by writing

amqp "github.com/rabbitmq/amqp091-go"

).


Verify that all usages of the AMQP library are compatible with the new package.

✏️ test_queue.go

Locate the existing import:

import "github.com/streadway/amqp"


Replace it with:

import amqp "github.com/rabbitmq/amqp091-go"


Confirm that the rest of the file uses the RabbitMQ API correctly and that the tests pass.

✏️ go.mod

Replace the line:

- github.com/streadway/amqp v1.1.0 // indirect

with:

+ github.com/rabbitmq/amqp091-go v1.8.1 // indirect


Run

go mod tidy

to update go.sum and ensure all dependencies are correctly resolved.

✏️ internal/service/service.go

Locate the import line:

- "github.com/streadway/amqp"

and replace it with:

+ "github.com/rabbitmq/amqp091-go"


Verify that the alias "amqp" remains used consistently in the file.

✏️ test_queue.go

Find the import statement:

- import "github.com/streadway/amqp"

or

- import amqp "github.com/streadway/amqp"

and replace it with:

+ import "github.com/rabbitmq/amqp091-go"

or with an alias:

+ import amqp "github.com/rabbitmq/amqp091-go"

✏️ internal/infrastructure/rzd/rabbitmq/consumer.go

Replace the import:

"github.com/streadway/amqp"

with:

"github.com/rabbitmq/amqp091-go"


Confirm that the types (e.g., amqp.Connection, amqp.Channel) are still used correctly and require no additional changes.

✏️ go.mod

Locate the dependency line for

github.com/streadway/amqp

and replace it with

github.com/rabbitmq/amqp091-go v1.8.1 // indirect

.


After modifying go.mod, run

go mod tidy

to update the dependency graph.

✏️ internal/service/service.go

Replace the line

"github.com/streadway/amqp"

with

"github.com/rabbitmq/amqp091-go"

. Optionally, use an alias for compatibility, for example:

import amqp "github.com/rabbitmq/amqp091-go"

.


Verify that all subsequent usages of the

amqp

package remain valid.

✏️ test_queue.go

Change the import line from

"github.com/streadway/amqp"

to

"github.com/rabbitmq/amqp091-go"

. Optionally, use an alias if required, for example:

import amqp "github.com/rabbitmq/amqp091-go"

.

✏️ go.mod

Replace

github.com/streadway/amqp v1.1.0 // indirect

with

github.com/rabbitmq/amqp091-go v1.8.1 // indirect

.


Run

go mod tidy

to update the dependency graph.

✏️ internal/service/service.go

Change the import line:


- "github.com/streadway/amqp"


+ import amqp "github.com/rabbitmq/amqp091-go"


Verify that all AMQP API usages in the file remain compatible with the new package.

✏️ test_queue.go

Replace the import line:


- import "github.com/streadway/amqp"


+ import amqp "github.com/rabbitmq/amqp091-go"


Confirm that any usage of the AMQP functions in this file is valid with the new dependency.

A summary of the context that CodeRabbit is considering across the codebase:

The RabbitMQ client library "github.com/streadway/amqp" is deprecated and unmaintained.
We need to update our dependency in go.mod and in all code files that import it so that we use the maintained
"github.com/rabbitmq/amqp091-go" library instead. This change ensures long-term support and compatibility.

This update is required because the streadway/amqp package is no longer maintained. Migrating to rabbitmq/amqp091-go ensures long-term support and compatibility.

This change ensures that the code in internal/service/service.go uses the actively maintained RabbitMQ client library, thereby reducing future technical debt.

Updating test_queue.go ensures that tests and other RabbitMQ interactions in the codebase utilize the new, supported library, guaranteeing consistency.

The shell search results confirmed that the deprecated dependency

github.com/streadway/amqp v1.1.0 // indirect

is referenced in the repository
(in both go.mod, internal/infrastructure/rzd/rabbitmq/consumer.go, and test_queue.go).
We will update all these references to the maintained version

github.com/rabbitmq/amqp091-go v1.8.1 // indirect

.

  • ✅ Create PR with these edits

  • 📋 Get copyable edits

  • 📌 Create commit in current branch

  • 🔄 Try a different approach

Comment on lines +42 to +43
log.Printf("RabbitMQ URL: %s", cfg.RabbitMQ.URL)

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider sensitive information exposure in logs

While logging the RabbitMQ URL is helpful for debugging, it may expose sensitive credentials if they're embedded in the URL. Consider masking passwords in logs.

-log.Printf("RabbitMQ URL: %s", cfg.RabbitMQ.URL)
+// Create a sanitized URL for logging (hide credentials)
+parsedURL, err := url.Parse(cfg.RabbitMQ.URL)
+if err == nil && parsedURL.User != nil {
+    parsedURL.User = url.UserPassword(parsedURL.User.Username(), "***")
+    log.Printf("RabbitMQ URL: %s", parsedURL.String())
+} else {
+    log.Printf("RabbitMQ enabled (URL parsing failed)")
+}

Don't forget to import "net/url" if you implement this change.

📝 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.

Suggested change
log.Printf("RabbitMQ URL: %s", cfg.RabbitMQ.URL)
// Create a sanitized URL for logging (hide credentials)
parsedURL, err := url.Parse(cfg.RabbitMQ.URL)
if err == nil && parsedURL.User != nil {
parsedURL.User = url.UserPassword(parsedURL.User.Username(), "***")
log.Printf("RabbitMQ URL: %s", parsedURL.String())
} else {
log.Printf("RabbitMQ enabled (URL parsing failed)")
}

- integrate RabbitMQ for message processing
- implement consumer and message handling logic
- support multiple concurrent workers for efficient processing

♻️ refactor(service): remove deprecated RabbitMQ logic

- eliminate old RabbitMQ handling from service
- prepare service for new RabbitMQ integration
github.com/spf13/viper v1.12.0 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect
github.com/streadway/amqp v1.1.0 // indirect
Copy link
Member

Choose a reason for hiding this comment

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

Да, используй rabbitmq/amqp091-go

@@ -0,0 +1,54 @@
package rabbitmq
Copy link
Member

Choose a reason for hiding this comment

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

тут папка rzd нужна для тех кто приходит от ржд, лучше просто в инфре реббит держать

func New(rzdClient *rzd.Client, cfg *config.Config) Service {
svc := &mainService{rzdClient: rzdClient}
// Передаем URL из конфигурации
return svc
Copy link
Member

Choose a reason for hiding this comment

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

Что поменялось?

log.Println("Waiting for messages...")

// Количество горутин в зависимости от числа ядер процессора
numWorkers := runtime.NumCPU() * 2
Copy link
Member

Choose a reason for hiding this comment

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

Их лучше указывать в конфигурации. Я посмотрю на этот сервис когда он будет запущен на 0.25 ядра по конфигу, вот будет умора, ноль воркеров.

}
defer consumer.Close()

msgs, err := consumer.Consume("rzd_queue")
Copy link
Member

Choose a reason for hiding this comment

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

Хардкод, айайай

"github.com/streadway/amqp"
)

type Consumer struct {
Copy link
Member

Choose a reason for hiding this comment

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

Раз это чистый консьюмер, он является входной точной, а не выходной. Так что лучше его держать там-же где ты его и используешь - в презентационном слое. Это у меня в Chaika Route Adapter он лежит в инфе, потому что у меня там Client, а не Consumer.

}

params := domain.GetTrainRoutesParams{
FromCode: int(message["payload"].(map[string]interface{})["fromCode"].(float64)),
Copy link
Member

Choose a reason for hiding this comment

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

Можно выделить в мапперы, но это не критично пока

}

func sendResponse(response map[string]interface{}) {
// Здесь вы можете реализовать отправку ответа обратно в очередь или другой механизм доставки
Copy link
Member

Choose a reason for hiding this comment

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

Можешь, конечно можешь. Я в тебя верю.


// RabbitMQ содержит конфигурацию для подключения к RabbitMQ.
type RabbitMQ struct {
URL string `yaml:"URL" env:"RABBITMQ_URL,default=amqp://guest:guest@localhost:5672/"`
Copy link
Member

Choose a reason for hiding this comment

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

Да, отлично. Добавь сюда ещё всё то что было в ревью выше. Таймауты, название очереди, и т.д.

@@ -0,0 +1,95 @@
package main
Copy link
Member

Choose a reason for hiding this comment

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

Ну знаешь, есть папочка test....

Copy link
Member

Choose a reason for hiding this comment

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

Или клади рядом с тестируемым модулем, но только не в корень пж

@Fascinat0r
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 13, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

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

♻️ Duplicate comments (2)
internal/transports/rabbitmq/handler.go (2)

22-25: Parameterize or configure queue name instead of hardcoding.
Hardcoding "rzd_queue" makes queue changes require code edits. Moving this to a config or environment variable is typically more flexible.


31-33: Move worker concurrency settings to configuration.
Specifying the concurrency based on runtime CPU can be surprising in certain environments. Allowing override in config or via environment variable provides more control.

🧹 Nitpick comments (7)
internal/infrastructure/rzd/rabbitmq/consumer.go (4)

1-2: Consider renaming or relocating the package to avoid nesting under rzd.
This file is currently placed in internal/infrastructure/rzd/rabbitmq, but it doesn’t appear to reference RZD-specific logic. Placing it under something like internal/infrastructure/rabbitmq or internal/transports/rabbitmq might be more appropriate and reduce confusion.


14-32: Consider providing more contextual logging or standardized error handling.
While this code is functional, you could enhance its maintainability by:

  • Standardizing your logs (e.g., using structured logging libraries) to include error metadata.
  • Minimizing log.Printfs in favor of returning well-defined error types up the chain, or standardizing them in your error handling approach.

34-44: Reconsider using auto-ack to prevent message loss.
With autoAck = true, messages are acknowledged immediately, so any processing error will not re-trigger consumption. You might want to use manual acknowledgment and re-queue or handle failed processing attempts.

-false,     // auto-ack
+false,     // auto-ack replaced with manual ack usage

46-54: Ensure the Close() method integrates with ongoing message consumption.
If a worker is still processing a message, closing connections concurrently may lead to unexpected errors. Consider a shutdown workflow (e.g., wait groups, graceful shutdown signals) to ensure messages finish processing before teardown.

internal/transports/rabbitmq/handler.go (3)

15-20: Avoid terminating the entire process with log.Fatalf.
Using log.Fatalf will kill the application immediately, denying a graceful exit strategy. Consider returning the error or using a more controlled shutdown.

-if err != nil {
-   log.Fatalf("Failed to create RabbitMQ consumer: %v", err)
-}
+if err != nil {
+   log.Printf("Failed to create RabbitMQ consumer: %v", err)
+   // return or handle gracefully without abrupt exit
+}

48-135: Extract request handlers into separate methods.
This switch block is readable but fairly long. Splitting each case into a dedicated function can simplify testing and improve maintainability.


144-147: Implement a real response-delivery mechanism.
The placeholder logic sends the response to logs. If you intend to respond to a RabbitMQ queue, consider implementing a publish or RPC-style correlation mechanism here.

Would you like help creating a follow-up implementation to send responses back via RabbitMQ?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2278270 and e9a7f70.

📒 Files selected for processing (4)
  • cmd/rzd-scraper/main.go (3 hunks)
  • internal/infrastructure/rzd/rabbitmq/consumer.go (1 hunks)
  • internal/service/service.go (2 hunks)
  • internal/transports/rabbitmq/handler.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/rzd-scraper/main.go
  • internal/service/service.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
internal/transports/rabbitmq/handler.go (3)
internal/infrastructure/rzd/rabbitmq/consumer.go (1)
  • NewConsumer (14-32)
internal/domain/models.go (3)
  • GetTrainRoutesParams (80-88)
  • GetTrainCarriagesParams (91-97)
  • SearchStationParams (100-103)
internal/domain/enums.go (3)
  • Direction (5-5)
  • TrainType (34-34)
  • TrainSearchType (13-13)
🔇 Additional comments (1)
internal/infrastructure/rzd/rabbitmq/consumer.go (1)

9-12: Struct fields look good.
The Consumer struct clearly holds the connection and channel. This is straightforward and maintainable.

Comment on lines +38 to +46
for i := 0; i < numWorkers; i++ {
go func(workerID int) {
for d := range msgs {
log.Printf("Worker %d: Received a message: %s", workerID, d.Body)
var message map[string]interface{}
if err := json.Unmarshal(d.Body, &message); err != nil {
log.Printf("Worker %d: Error decoding JSON: %v", workerID, err)
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider a robust error-handling strategy for parsing failures.
Currently, a failed JSON parse simply logs and continues. Because auto-ack is on, the message is lost. If critical, consider manual acknowledgments and error-handling logic to re-queue or store the failed message for later reprocessing.

coderabbitai bot added a commit that referenced this pull request Apr 13, 2025
Docstrings generation was requested by @Fascinat0r.

* #10 (comment)

The following files were modified:

* `cmd/rzd-scraper/main.go`
* `internal/infrastructure/rzd/rabbitmq/consumer.go`
* `internal/service/service.go`
* `internal/transports/rabbitmq/handler.go`
* `pkg/config/config.go`
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 13, 2025

Note

Generated docstrings for this pull request at #11

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