Skip to content

Commit

Permalink
queue provider
Browse files Browse the repository at this point in the history
  • Loading branch information
vjik committed Nov 1, 2024
1 parent fdbf137 commit a268694
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 0 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"psr/log": "^2.0|^3.0",
"symfony/console": "^5.4|^6.0",
"yiisoft/definitions": "^1.0|^2.0|^3.0",
"yiisoft/factory": "dev-strict",
"yiisoft/friendly-exception": "^1.0",
"yiisoft/injector": "^1.0"
},
Expand Down
22 changes: 22 additions & 0 deletions src/Provider/ChannelNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Provider;

use LogicException;
use Throwable;

use function sprintf;

final class ChannelNotFoundException extends LogicException implements QueueProviderException
{
public function __construct(string $channel, int $code = 0, ?Throwable $previous = null)
{
parent::__construct(
sprintf('Channel "%s" not found.', $channel),
$code,
$previous,
);
}
}
41 changes: 41 additions & 0 deletions src/Provider/CompositeQueueProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Provider;

use Yiisoft\Queue\QueueInterface;

final class CompositeQueueProvider implements QueueProviderInterface
{
/**
* @var QueueProviderInterface[]
*/
private readonly array $providers;

public function __construct(
QueueProviderInterface ...$providers
) {
$this->providers = $providers;
}

public function get(string $channel): QueueInterface
{
foreach ($this->providers as $provider) {
if ($provider->has($channel)) {
return $provider->get($channel);
}
}
throw new ChannelNotFoundException($channel);
}

public function has(string $channel): bool
{
foreach ($this->providers as $provider) {
if ($provider->has($channel)) {
return true;
}
}
return false;
}
}
69 changes: 69 additions & 0 deletions src/Provider/FactoryQueueProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Provider;

use Psr\Container\ContainerInterface;
use Yiisoft\Definitions\Exception\InvalidConfigException;
use Yiisoft\Factory\StrictFactory;
use Yiisoft\Queue\QueueInterface;

use function array_key_exists;

final class FactoryQueueProvider implements QueueProviderInterface
{
/**
* @psalm-var array<string, QueueInterface|null>
*/
private array $queues = [];

private readonly StrictFactory $factory;

/**
* @throws InvalidConfigException
*/
public function __construct(
private readonly array $definitions = [],
?ContainerInterface $container = null,
bool $validate = true,
) {
$this->factory = new StrictFactory($definitions, $container, $validate);
}

public function get(string $channel): QueueInterface
{
$queue = $this->getOrTryCreate($channel);
if ($queue === null) {
throw new ChannelNotFoundException($channel);
}
return $queue;
}

public function has(string $channel): bool
{
return array_key_exists($channel, $this->definitions);
}

/**
* @throws InvalidQueueConfigException
*/
private function getOrTryCreate(string $channel): QueueInterface|null
{
if (array_key_exists($channel, $this->queues)) {
return $this->queues[$channel];
}

if ($this->factory->has($channel)) {
try {
$this->queues[$channel] = $this->factory->create($channel);
} catch (InvalidConfigException $exception) {
throw new InvalidQueueConfigException($exception->getMessage(), previous: $exception);
}
} else {
$this->queues[$channel] = null;
}

return $this->queues[$channel];
}
}
11 changes: 11 additions & 0 deletions src/Provider/InvalidQueueConfigException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Provider;

use LogicException;

final class InvalidQueueConfigException extends LogicException implements QueueProviderException
{
}
25 changes: 25 additions & 0 deletions src/Provider/PrototypeQueueProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Provider;

use Yiisoft\Queue\QueueInterface;

final class PrototypeQueueProvider implements QueueProviderInterface
{
public function __construct(
private readonly QueueInterface $baseQueue,
) {
}

public function get(string $channel): QueueInterface
{
return $this->baseQueue->withChannelName($channel);
}

public function has(string $channel): bool
{
return true;
}
}
11 changes: 11 additions & 0 deletions src/Provider/QueueProviderException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Provider;

use Throwable;

interface QueueProviderException extends Throwable
{
}
19 changes: 19 additions & 0 deletions src/Provider/QueueProviderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Provider;

use Yiisoft\Queue\QueueInterface;

interface QueueProviderInterface
{
/**
* @throws InvalidQueueConfigException
* @throws ChannelNotFoundException
* @throws QueueProviderException
*/
public function get(string $channel): QueueInterface;

public function has(string $channel): bool;
}

0 comments on commit a268694

Please sign in to comment.