Skip to content

Commit 1b85ec2

Browse files
authored
feat: add disconnect() method to release resources deterministically
This release adds a `disconnect()` method. It is a breaking change for custom implementations of the interfaces, which now require a `disconnect()` method. If you do not have custom implementations this change should not affect you. If you have properly set up static analysis it will warn you if you need to do anything. If you don't, then you should set up PHPStan! BREAKING CHANGE: Adds methods to interfaces that are part of the public API
2 parents 24e24eb + 0ede631 commit 1b85ec2

9 files changed

+63
-3
lines changed
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Pheanstalk\Contract;
6+
7+
interface PheanstalkClientInterface
8+
{
9+
/**
10+
* Closes the current connection and releases all associated resources.
11+
*
12+
* This method ensures that after the call, no resources are held by the client,
13+
* allowing garbage collection to safely reclaim memory. If no connection is open,
14+
* this method does nothing (noop). Future command dispatches will automatically
15+
* establish a new connection if needed.
16+
*
17+
* Note: If the client has any reserved jobs at the time of disconnection, beanstalkd
18+
* will automatically release them back into the ready queue.
19+
*/
20+
public function disconnect(): void;
21+
}

src/Contract/PheanstalkManagerInterface.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use Pheanstalk\Values\TubeName;
1212
use Pheanstalk\Values\TubeStats;
1313

14-
interface PheanstalkManagerInterface
14+
interface PheanstalkManagerInterface extends PheanstalkClientInterface
1515
{
1616
/**
1717
* Kicks buried or delayed jobs into a 'ready' state.

src/Contract/PheanstalkPublisherInterface.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use Pheanstalk\Values\TubeName;
88

9-
interface PheanstalkPublisherInterface
9+
interface PheanstalkPublisherInterface extends PheanstalkClientInterface
1010
{
1111
public const int DEFAULT_DELAY = 0; // no delay
1212
public const int DEFAULT_PRIORITY = 1024; // most urgent: 0, least urgent: 4294967295

src/Contract/PheanstalkSubscriberInterface.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Pheanstalk\Values\TubeList;
99
use Pheanstalk\Values\TubeName;
1010

11-
interface PheanstalkSubscriberInterface
11+
interface PheanstalkSubscriberInterface extends PheanstalkClientInterface
1212
{
1313
/**
1414
* Permanently deletes a job.

src/Pheanstalk.php

+5
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ public function stats(): ServerStats
118118
return $this->manager->stats();
119119
}
120120

121+
public function disconnect(): void
122+
{
123+
$this->manager->disconnect();
124+
}
125+
121126
public function bury(JobIdInterface $job, int $priority = self::DEFAULT_PRIORITY): void
122127
{
123128
$this->subscriber->bury($job, $priority);

src/PheanstalkManager.php

+5
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,9 @@ public function stats(): ServerStats
114114
$command = new Command\StatsCommand();
115115
return $command->interpret($this->dispatch($command));
116116
}
117+
118+
public function disconnect(): void
119+
{
120+
$this->connection->disconnect();
121+
}
117122
}

src/PheanstalkPublisher.php

+5
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,9 @@ public function put(
4040
$command = new PutCommand($data, $priority, $delay, $timeToRelease);
4141
return $command->interpret($this->connection->dispatchCommand($command));
4242
}
43+
44+
public function disconnect(): void
45+
{
46+
$this->connection->disconnect();
47+
}
4348
}

src/PheanstalkSubscriber.php

+5
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,9 @@ public function reserveJob(JobIdInterface $job): Job
102102
$command = new ReserveJobCommand($job);
103103
return $command->interpret($this->dispatch($command));
104104
}
105+
106+
public function disconnect(): void
107+
{
108+
$this->connection->disconnect();
109+
}
105110
}

tests/Unit/ConnectionTest.php

+19
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,25 @@ public function testDisconnect(): void
3838
$connection->disconnect();
3939
}
4040

41+
public function testReconnectAfterDispatch(): void
42+
{
43+
$socket = $this->getMockBuilder(SocketInterface::class)->getMock();
44+
$socket->expects(self::once())->method('disconnect');
45+
$socket->expects(self::once())
46+
->method('getLine')
47+
->willReturn(ResponseType::Using->value);
48+
49+
$factory = $this->getMockBuilder(SocketFactoryInterface::class)->getMock();
50+
$factory->expects(self::exactly(2))
51+
->method('create')
52+
->willReturn($socket);
53+
54+
$connection = new Connection($factory);
55+
$connection->connect();
56+
$connection->disconnect();
57+
$connection->dispatchCommand(new UseCommand(new TubeName('foo')));
58+
}
59+
4160
private function getCommand(): CommandInterface
4261
{
4362
return new UseCommand(new TubeName('tube5'));

0 commit comments

Comments
 (0)