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

[FEATURE] Implement Queue wrapper #82

Open
guibranco opened this issue Mar 19, 2024 · 2 comments · May be fixed by #238
Open

[FEATURE] Implement Queue wrapper #82

guibranco opened this issue Mar 19, 2024 · 2 comments · May be fixed by #238
Labels
📝 documentation Tasks related to writing or updating documentation enhancement New feature or request gitauto GitAuto label to trigger the app in a issue. good first issue Good for newcomers hacktoberfest Participation in the Hacktoberfest event help wanted Extra attention is needed 🕔 high effort A task that can be completed in a few days 🧪 tests Tasks related to testing 🛠 WIP Work in progress

Comments

@guibranco
Copy link
Owner

guibranco commented Mar 19, 2024

Description

Implement queue (AMQP) wrapper for basic features.

  • Send a message to the queue (explicit).
  • Receive a message from the queue (explicit).
  • Declare queue and DLX (implicit).
  • Change the snippet to allow consumption/sending without declaring the DLX queue (A new private method should be created, and an optional parameter to send/receive should be added).
  • Refactor the code to allow the usage of multiple servers (the send uses random, and the read loops through all of them).
  • The servers should be an array and injected at the constructor.
  • The consume method should receive optional parameters as the length of the QoS (on the snippet below, it is fixed in 10).

Tech notes

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;

class Queue implements IQueue
{
    private $connectionStrings;

    public function __construct()
    {
        // TODO: Remove this code from here, receive the configuration as a parameter.
        $configuration = new Configuration();
        $this->connectionStrings = $configuration->getRabbitMq();
    }

    private function getServers()
    {
        if (empty($this->connectionStrings)) {
            throw new QueueException("RabbitMQ connection strings not found");
        }

        $servers = [];
        foreach ($this->connectionStrings as $connectionString) {
            $url = parse_url($connectionString);
            $servers[] = [
                "host" => $url["host"],
                "port" => isset($url["port"]) ? $url["port"] : 5672,
                "user" => $url["user"],
                "password" => $url["pass"],
                "vhost" => ($url['path'] == '/' || !isset($url['path'])) ? '/' : substr($url['path'], 1)
            ];
        }

        return $servers;
    }

    private function getConnection()
    {
        $servers = $this->getServers();
        $options = [];
        if (count($servers) == 1) {
            $options = ['connection_timeout' => 10.0, 'read_write_timeout' => 10.0,];
        }

        return AMQPStreamConnection::create_connection($servers, $options);
    }

   private function declareQueueWIthoutDLX($channel, $queueName) 
   {
      // TODO: declare the queue without DLX.
   }

    // TODO: rename to declareQueueWithDLX
    private function declareQueueAndDLX($channel, $queueName)
    {
        $channel->queue_declare(
            $queueName,
            false,
            true,
            false,
            false,
            false,
            new AMQPTable(
                array(
                    'x-dead-letter-exchange' => '',
                    'x-dead-letter-routing-key' => $queueName . '-retry'
                )
            )
        );
        $channel->queue_declare(
            $queueName . '-retry',
            false,
            true,
            false,
            false,
            false,
            new AMQPTable(
                array(
                    'x-dead-letter-exchange' => '',
                    'x-dead-letter-routing-key' => $queueName,
                    'x-message-ttl' => 1000 * 60 * 60
                )
            )
        );
    }

    public function publish($queueName, $message)
    {
        $connection = $this->getConnection();
        $channel = $connection->channel();
        $this->declareQueueAndDLX($channel, $queueName);
        $msgOptions = array(
            'content_type' => 'application/json',
            'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT
        );
        $msg = new AMQPMessage($message, $msgOptions);
        $channel->basic_publish($msg, '', $queueName);
        $channel->close();
        $connection->close();
    }

    public function consume($timeout, $queueName, $callback, $resetTimeoutOnReceive = false)
    {
        $startTime = time();
        $fn = function ($msg) use ($callback, $timeout, $startTime, $resetTimeoutOnReceive) {
            if ($resetTimeoutOnReceive) {
                $startTime = time();
            }
            $callback($timeout, $startTime, $msg);
        };

        $connection = $this->getConnection();
        $channel = $connection->channel();
        // TODO: check which one to call - declareQueueWithDLX or declareQueueWithoutDLX
        $this->declareQueueAndDLX($channel, $queueName);
        // TODO: the 10 should be an optional parameter of this method with default value as 10.
        $channel->basic_qos(null, 10, null);
        $channel->basic_consume($queueName, '', false, false, false, false, $fn);

        while ($channel->is_consuming()) {
            $channel->wait(null, true);
            if ($startTime + $timeout < time()) {
                break;
            }
        }

        $channel->close();
        $connection->close();
    }
}

Additional information

⚠️ 🚨 Add documentation and tests

@guibranco guibranco added the enhancement New feature or request label Mar 19, 2024
@guibranco guibranco added the 📝 documentation Tasks related to writing or updating documentation label Jun 8, 2024
@guibranco guibranco added 🧠 backlog Items that are in the backlog for future work help wanted Extra attention is needed labels Jul 4, 2024
@gitauto-ai gitauto-ai bot added the gitauto GitAuto label to trigger the app in a issue. label Jul 9, 2024
Copy link
Contributor

gitauto-ai bot commented Jul 9, 2024

@guibranco Pull request completed! Check it out here #171 🚀

Note: I automatically create a pull request for an unassigned and open issue in order from oldest to newest once a day at 00:00 UTC, as long as you have remaining automation usage. Should you have any questions or wish to change settings or limits, please feel free to contact [email protected] or invite us to Slack Connect.

@guibranco guibranco added good first issue Good for newcomers hacktoberfest Participation in the Hacktoberfest event and removed 🧠 backlog Items that are in the backlog for future work gitauto GitAuto label to trigger the app in a issue. labels Jul 11, 2024
@gitauto-ai gitauto-ai bot added the gitauto GitAuto label to trigger the app in a issue. label Jul 22, 2024
@guibranco guibranco changed the title [FEATURE] Implement Queue wrapper [FEATURE] Implement Queue wrapper Oct 9, 2024
@guibranco guibranco removed the gitauto GitAuto label to trigger the app in a issue. label Oct 9, 2024
@guibranco guibranco added 🧪 tests Tasks related to testing 🕔 high effort A task that can be completed in a few days labels Oct 21, 2024
@gitauto-ai gitauto-ai bot added the gitauto GitAuto label to trigger the app in a issue. label Oct 22, 2024
Copy link
Contributor

gitauto-ai bot commented Oct 22, 2024

Hey, I'm a bit lost here! Not sure which file I should be fixing. Could you give me a bit more to go on? Maybe add some details to the issue or drop a comment with some extra hints? Thanks!

Have feedback or need help?
Feel free to email [email protected].

@gitauto-ai gitauto-ai bot linked a pull request Oct 22, 2024 that will close this issue
@gstraccini gstraccini bot added the 🛠 WIP Work in progress label Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📝 documentation Tasks related to writing or updating documentation enhancement New feature or request gitauto GitAuto label to trigger the app in a issue. good first issue Good for newcomers hacktoberfest Participation in the Hacktoberfest event help wanted Extra attention is needed 🕔 high effort A task that can be completed in a few days 🧪 tests Tasks related to testing 🛠 WIP Work in progress
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant