Skip to content

Commit 1ee7336

Browse files
authored
[FRAM-212] New pheanstalk compatibility (#24)
* ci: Add build for pheanstalk compatibility * ci: Try to launch beanstalkd on github action * ci: Try to launch beanstalkd on github action * ci: Try to launch beanstalkd on github action * ci: simplify beanstalkd launch * feat(pheanstalk): Compatibility with v4.0 * ci: fix psalm error * feat(pheanstalk): Compatibility with v5.0 * ci: ignore psalm for pheanstalk * feat(pheanstalk): Compatibility with v6 to v8 * chore(beanstalk): Drop support of pheanstalk v3
1 parent 20edbe7 commit 1ee7336

8 files changed

Lines changed: 340 additions & 52 deletions

File tree

.github/workflows/php.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,42 @@ jobs:
4040
- name: Run test suite
4141
run: composer run-script tests
4242

43+
pheanstalk_compatibility:
44+
runs-on: ubuntu-latest
45+
strategy:
46+
matrix:
47+
pheanstalk-versions: ['4.0', '5.0', '6.0', '7.0', '8.0']
48+
name: Pheanstalk ${{ matrix.pheanstalk-versions }}
49+
50+
steps:
51+
- uses: actions/checkout@v2
52+
53+
- name: Set Timezone
54+
uses: szenius/set-timezone@v1.0
55+
with:
56+
timezoneLinux: "Europe/Paris"
57+
58+
- name: Install PHP
59+
uses: shivammathur/setup-php@v2
60+
with:
61+
php-version: 8.4
62+
extensions: json
63+
ini-values: date.timezone=Europe/Paris
64+
65+
- name: Install & run Beanstalkd
66+
run: |
67+
sudo apt-get install -y beanstalkd
68+
sudo systemctl start beanstalkd.service
69+
70+
- name: Install dependencies
71+
run: composer install --prefer-dist --no-progress
72+
73+
- name: Require Pheanstalk version
74+
run: composer require --dev "pda/pheanstalk:~${{ matrix.pheanstalk-versions }}"
75+
76+
- name: Run test suite
77+
run: composer run-script tests
78+
4379
analysis:
4480
name: Analysis
4581
runs-on: ubuntu-latest

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"enqueue/fs": "~0.9",
3838
"league/container": "~3.0",
3939
"monolog/monolog": "~2.0",
40-
"pda/pheanstalk": "^3.1@dev",
40+
"pda/pheanstalk": "~4.0|~5.0|~6.0|~7.0|~8.0",
4141
"php-amqplib/php-amqplib": "~3.0",
4242
"phpbench/phpbench": "~0.0|~1.0",
4343
"phpunit/phpunit": "~9.6",
@@ -60,7 +60,8 @@
6060
"symfony/var-dumper": "VarDumper could be used for displaying failed message (~5.4|~6.0|~7.0)"
6161
},
6262
"conflict": {
63-
"enqueue/dsn": "0.10.25"
63+
"enqueue/dsn": "0.10.25",
64+
"pda/pheanstalk": "<4.0"
6465
},
6566
"scripts": {
6667
"tests": "phpunit",

psalm.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
<directory name="src" />
1313
<ignoreFiles>
1414
<directory name="vendor" />
15+
16+
<!-- Too much hack to get pheanstalk v3-5 works, so disable psalm until legacy is removed -->
17+
<directory name="src/Connection/Pheanstalk" />
1518
</ignoreFiles>
1619
</projectFiles>
1720

src/Connection/Pheanstalk/PheanstalkConnection.php

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,22 @@
1111
use Bdf\Queue\Message\MessageSerializationTrait;
1212
use Bdf\Queue\Serializer\SerializerInterface;
1313
use Bdf\Queue\Util\MultiServer;
14-
use Pheanstalk\Connection;
14+
use Pheanstalk\Contract\PheanstalkManagerInterface;
1515
use Pheanstalk\Pheanstalk;
16-
use Pheanstalk\PheanstalkInterface;
16+
use Pheanstalk\Contract\PheanstalkInterface;
17+
use Pheanstalk\Values\Timeout;
18+
19+
use function class_alias;
20+
use function class_exists;
21+
use function fclose;
22+
use function fsockopen;
23+
use function interface_exists;
24+
use function method_exists;
25+
26+
if (!interface_exists(PheanstalkInterface::class)) {
27+
// Support for Pheanstalk 5
28+
class_alias(PheanstalkManagerInterface::class, PheanstalkInterface::class);
29+
}
1730

1831
/**
1932
* PheanstalkConnection
@@ -23,6 +36,9 @@ class PheanstalkConnection implements ConnectionDriverInterface
2336
use ConnectionNamed;
2437
use MessageSerializationTrait;
2538

39+
public const DEFAULT_PORT = 11300;
40+
public const DEFAULT_TTR = 60; // 1 minute
41+
2642
/**
2743
* @var PheanstalkInterface
2844
*/
@@ -50,8 +66,8 @@ public function __construct(string $name, SerializerInterface $serializer)
5066
*/
5167
public function setConfig(array $config): void
5268
{
53-
$this->config = MultiServer::prepareMultiServers($config, '127.0.0.1', PheanstalkInterface::DEFAULT_PORT) + [
54-
'ttr' => PheanstalkInterface::DEFAULT_TTR,
69+
$this->config = MultiServer::prepareMultiServers($config, '127.0.0.1', self::DEFAULT_PORT) + [
70+
'ttr' => self::DEFAULT_TTR,
5571
'client-timeout' => null,
5672
];
5773
}
@@ -78,13 +94,20 @@ public function timeToRun(): ?int
7894
* @return PheanstalkInterface
7995
* @throws ServerNotAvailableException If no servers has been found
8096
*/
81-
public function pheanstalk(): PheanstalkInterface
97+
public function pheanstalk()
8298
{
8399
if ($this->pheanstalk === null) {
84100
// Set the first available server
85101
// Pheanstalk manage a lazy connection. We can instantiate the client here.
86102
foreach ($this->getActiveHost() as $host => $port) {
87-
$this->pheanstalk = new Pheanstalk($host, $port, $this->config['client-timeout']);
103+
$timeout = (int) ($this->config['client-timeout'] ?? 10);
104+
105+
if (class_exists(Timeout::class)) {
106+
// Pheanstalk 5
107+
$timeout = new Timeout($timeout);
108+
}
109+
110+
$this->pheanstalk = Pheanstalk::create($host, (int) $port, $timeout);
88111
break;
89112
}
90113
}
@@ -108,7 +131,11 @@ public function setPheanstalk(PheanstalkInterface $pheanstalk)
108131
public function close(): void
109132
{
110133
if ($this->pheanstalk !== null) {
111-
$this->pheanstalk->getConnection()->disconnect();
134+
if (method_exists($this->pheanstalk, 'disconnect')) {
135+
// Pheanstalk 7
136+
$this->pheanstalk->disconnect();
137+
}
138+
112139
$this->pheanstalk = null;
113140
}
114141
}
@@ -143,7 +170,10 @@ public function getActiveHost()
143170
$valid = [];
144171

145172
foreach ($this->config['hosts'] as $host => $port) {
146-
if ((new Connection($host, $port))->isServiceListening()) {
173+
$stream = @fsockopen($host, $port, $errno, $errstr, 0.1);
174+
175+
if ($stream !== false) {
176+
fclose($stream);
147177
$valid[$host] = $port;
148178
}
149179
}

0 commit comments

Comments
 (0)