Merge pull request #963 from acelaya-forks/feature/mezzio-swoole-3

Feature/mezzio swoole 3
This commit is contained in:
Alejandro Celaya 2021-01-17 13:31:04 +01:00 committed by GitHub
commit 1309290a2f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 111 additions and 55 deletions

View file

@ -21,3 +21,4 @@ infection*
**/test*
build*
**/.*
bin/helper

View file

@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
### Changed
* [#912](https://github.com/shlinkio/shlink/issues/912) Changed error templates to be plain html files, removing the dependency on `league/plates` package.
* [#875](https://github.com/shlinkio/shlink/issues/875) Updated to `mezzio/mezzio-swoole` v3.1.
### Deprecated
* [#917](https://github.com/shlinkio/shlink/issues/917) Deprecated `/{shortCode}/qr-code/{size}` URL, in favor of providing the size in the query instead, `/{shortCode}/qr-code?size={size}`.

View file

@ -130,7 +130,7 @@ Once Shlink is configured, you need to expose it to the web, either by using a t
First you need to install the swoole PHP extension with [pecl](https://pecl.php.net/package/swoole), `pecl install swoole`.
Once installed, it's actually pretty easy to get shlink up and running with swoole. Run `./vendor/bin/mezzio-swoole start -d` and you will get shlink running on port 8080.
Once installed, it's actually pretty easy to get shlink up and running with swoole. Run `./vendor/bin/laminas mezzio:swoole:start -d` and you will get shlink running on port 8080.
However, by doing it this way, you are loosing all the access logs, and the service won't be automatically run if the server has to be restarted.
@ -147,7 +147,7 @@ Once Shlink is configured, you need to expose it to the web, either by using a t
# Description: Shlink non-blocking server with swoole
### END INIT INFO
SCRIPT=/path/to/shlink/vendor/bin/mezzio-swoole\ start
SCRIPT=/path/to/shlink/vendor/bin/laminas\ mezzio:swoole:start
RUNAS=root
PIDFILE=/var/run/shlink_swoole.pid

51
bin/helper/mezzio-swoole Executable file
View file

@ -0,0 +1,51 @@
#!/usr/bin/env php
<?php
/**
* @deprecated To be removed with Shlink 3.0.0
* This script is provided to keep backwards compatibility on how to run shlink with swoole while being still able to
* update to mezzio/mezzio-swoole 3.x
*/
declare(strict_types=1);
namespace Mezzio\Swoole\Command;
use Laminas\ServiceManager\ServiceManager;
use PackageVersions\Versions;
use Symfony\Component\Console\Application as CommandLine;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use function explode;
use function Functional\filter;
use function str_starts_with;
use function strstr;
/** @var ServiceManager $container */
$container = require __DIR__ . '/../../config/container.php';
$version = strstr(Versions::getVersion('mezzio/mezzio-swoole'), '@', true);
$commandsPrefix = 'mezzio:swoole:';
$commands = filter(
$container->get('config')['laminas-cli']['commands'] ?? [],
fn ($c, string $command) => str_starts_with($command, $commandsPrefix),
);
$registeredCommands = [];
foreach ($commands as $newName => $commandServiceName) {
[, $oldName] = explode($commandsPrefix, $newName);
$registeredCommands[$oldName] = $commandServiceName;
$container->addDelegator($commandServiceName, static function ($c, $n, callable $factory) use ($oldName) {
/** @var Command $command */
$command = $factory();
$command->setAliases([$oldName]);
return $command;
});
}
$commandLine = new CommandLine('Mezzio web server', $version);
$commandLine->setAutoExit(true);
$commandLine->setCommandLoader(new ContainerCommandLoader($container, $registeredCommands));
$commandLine->run();

View file

@ -4,16 +4,16 @@ export DB_DRIVER=mysql
export TEST_ENV=api
# Try to stop server just in case it hanged in last execution
vendor/bin/mezzio-swoole stop
vendor/bin/laminas mezzio:swoole:stop
echo 'Starting server...'
vendor/bin/mezzio-swoole start -d
vendor/bin/laminas mezzio:swoole:start -d
sleep 2
vendor/bin/phpunit --order-by=random -c phpunit-api.xml --testdox --colors=always --log-junit=build/coverage-api/junit.xml $*
testsExitCode=$?
vendor/bin/mezzio-swoole stop
vendor/bin/laminas mezzio:swoole:stop
# Exit this script with the same code as the tests. If tests failed, this script has to fail
exit $testsExitCode

View file

@ -28,6 +28,9 @@ echo "Installing dependencies with $composerBin..."
${composerBin} self-update
${composerBin} install --no-dev --optimize-autoloader --prefer-dist --no-progress --no-interaction
# Copy mezzio helper script to vendor (deprecated - Remove with Shlink 3.0.0)
cp "${projectdir}/bin/helper/mezzio-swoole" "./vendor/bin"
# Delete development files
echo 'Deleting dev files...'
rm composer.*

View file

@ -39,7 +39,7 @@
"mezzio/mezzio-fastroute": "^3.1",
"mezzio/mezzio-helpers": "^5.3",
"mezzio/mezzio-problem-details": "^1.1",
"mezzio/mezzio-swoole": "^2.6.4",
"mezzio/mezzio-swoole": "^3.1",
"monolog/monolog": "^2.0",
"nikolaposa/monolog-factory": "^3.1",
"ocramius/proxy-manager": "^2.11",
@ -49,7 +49,7 @@
"ramsey/uuid": "^3.9",
"shlinkio/shlink-common": "dev-main#1311861 as 3.4",
"shlinkio/shlink-config": "^1.0",
"shlinkio/shlink-event-dispatcher": "^1.6",
"shlinkio/shlink-event-dispatcher": "^2.0",
"shlinkio/shlink-importer": "^2.1",
"shlinkio/shlink-installer": "^5.3",
"shlinkio/shlink-ip-geolocation": "^1.5",

View file

@ -8,7 +8,7 @@
# Description: Shlink non-blocking server with swoole
### END INIT INFO
SCRIPT=/path/to/shlink/vendor/bin/mezzio-swoole\ start
SCRIPT=/path/to/shlink/vendor/bin/laminas\ mezzio:swoole:start
RUNAS=root
PIDFILE=/var/run/shlink_swoole.pid

View file

@ -95,4 +95,4 @@ CMD \
if [[ ! -d "./vendor" ]]; then /usr/local/bin/composer install ; fi && \
# When restarting the container, swoole might think it is already in execution
# This forces the app to be started every second until the exit code is 0
until php ./vendor/bin/mezzio-swoole start; do sleep 1 ; done
until php ./vendor/bin/laminas mezzio:swoole:start; do sleep 1 ; done

View file

@ -17,4 +17,4 @@ php vendor/doctrine/orm/bin/doctrine.php orm:clear-cache:metadata -n -q
# When restarting the container, swoole might think it is already in execution
# This forces the app to be started every second until the exit code is 0
until php vendor/mezzio/mezzio-swoole/bin/mezzio-swoole start; do sleep 1 ; done
until php vendor/bin/laminas mezzio:swoole:start; do sleep 1 ; done

View file

@ -14,13 +14,13 @@ return [
'events' => [
'regular' => [
EventDispatcher\VisitLocated::class => [
EventDispatcher\Event\VisitLocated::class => [
EventDispatcher\NotifyVisitToMercure::class,
EventDispatcher\NotifyVisitToWebHooks::class,
],
],
'async' => [
EventDispatcher\ShortUrlVisited::class => [
EventDispatcher\Event\ShortUrlVisited::class => [
EventDispatcher\LocateShortUrlVisit::class,
],
],

View file

@ -2,13 +2,13 @@
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\EventDispatcher;
namespace Shlinkio\Shlink\Core\EventDispatcher\Event;
use JsonSerializable;
final class VisitLocated implements JsonSerializable
abstract class AbstractVisitEvent implements JsonSerializable
{
private string $visitId;
protected string $visitId;
public function __construct(string $visitId)
{

View file

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\EventDispatcher\Event;
final class ShortUrlVisited extends AbstractVisitEvent
{
private ?string $originalIpAddress;
public function __construct(string $visitId, ?string $originalIpAddress = null)
{
parent::__construct($visitId);
$this->originalIpAddress = $originalIpAddress;
}
public function originalIpAddress(): ?string
{
return $this->originalIpAddress;
}
}

View file

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\EventDispatcher\Event;
final class VisitLocated extends AbstractVisitEvent
{
}

View file

@ -11,6 +11,8 @@ use Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException;
use Shlinkio\Shlink\CLI\Util\GeolocationDbUpdaterInterface;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlVisited;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException;
use Shlinkio\Shlink\IpGeolocation\Model\Location;
use Shlinkio\Shlink\IpGeolocation\Resolver\IpLocationResolverInterface;

View file

@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\Core\EventDispatcher;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\Core\Mercure\MercureUpdatesGeneratorInterface;
use Symfony\Component\Mercure\PublisherInterface;
use Throwable;

View file

@ -13,6 +13,7 @@ use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\RequestOptions;
use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\Core\Options\AppOptions;
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
use Throwable;

View file

@ -1,34 +0,0 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\EventDispatcher;
use JsonSerializable;
final class ShortUrlVisited implements JsonSerializable
{
private string $visitId;
private ?string $originalIpAddress;
public function __construct(string $visitId, ?string $originalIpAddress = null)
{
$this->visitId = $visitId;
$this->originalIpAddress = $originalIpAddress;
}
public function visitId(): string
{
return $this->visitId;
}
public function originalIpAddress(): ?string
{
return $this->originalIpAddress;
}
public function jsonSerialize(): array
{
return ['visitId' => $this->visitId, 'originalIpAddress' => $this->originalIpAddress];
}
}

View file

@ -10,7 +10,7 @@ use Psr\EventDispatcher\EventDispatcherInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Tag;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\ShortUrlVisited;
use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlVisited;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
use Shlinkio\Shlink\Core\Exception\TagNotFoundException;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;

View file

@ -17,9 +17,9 @@ use Shlinkio\Shlink\Common\Util\IpAddress;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlVisited;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\Core\EventDispatcher\LocateShortUrlVisit;
use Shlinkio\Shlink\Core\EventDispatcher\ShortUrlVisited;
use Shlinkio\Shlink\Core\EventDispatcher\VisitLocated;
use Shlinkio\Shlink\Core\Model\Visitor;
use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException;
use Shlinkio\Shlink\IpGeolocation\Model\Location;

View file

@ -13,8 +13,8 @@ use Psr\Log\LoggerInterface;
use RuntimeException;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\Core\EventDispatcher\NotifyVisitToMercure;
use Shlinkio\Shlink\Core\EventDispatcher\VisitLocated;
use Shlinkio\Shlink\Core\Mercure\MercureUpdatesGeneratorInterface;
use Shlinkio\Shlink\Core\Model\Visitor;
use Symfony\Component\Mercure\PublisherInterface;

View file

@ -19,8 +19,8 @@ use Prophecy\Prophecy\ObjectProphecy;
use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\Core\EventDispatcher\NotifyVisitToWebHooks;
use Shlinkio\Shlink\Core\EventDispatcher\VisitLocated;
use Shlinkio\Shlink\Core\Model\Visitor;
use Shlinkio\Shlink\Core\Options\AppOptions;

View file

@ -15,7 +15,7 @@ use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Tag;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\ShortUrlVisited;
use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlVisited;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
use Shlinkio\Shlink\Core\Exception\TagNotFoundException;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;