Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
hollodotme committed Jul 29, 2019
2 parents 5922ee7 + f2b0403 commit e518c0f
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 17 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a CHANGELOG](http://keepachangelog.com).

## [3.0.0] - 2019-07-29

**Please take notice of the backwards incompatible changes (BC breaks) documented below
in the changelog of [3.0.0-alpha](#300-alpha---2019-04-30) & [3.0.0-beta](#300-beta---2019-06-24).**

### Added

* Reserved private constant for ABORT_REQUEST instruction for future use
* Socket ID is now represented and generated by a proper type class

### Improved

* Import of root namespace functions
* Dependency injection for socket implementation

## [3.0.0-beta] - 2019-06-24

### Backwards incompatible changes (BC breaks)
Expand Down Expand Up @@ -276,6 +291,7 @@ Based on [Pierrick Charron](https://github.com/adoy)'s [PHP-FastCGI-Client](http
* Getters/Setters for connect timeout, read/write timeout, keep alive, socket persistence from `Client` (now part of the socket connection)
* Method `Client->getValues()`

[3.0.0]: https://github.com/hollodotme/fast-cgi-client/compare/v3.0.0-beta...v3.0.0
[3.0.0-beta]: https://github.com/hollodotme/fast-cgi-client/compare/v3.0.0-alpha...v3.0.0-beta
[3.0.0-alpha]: https://github.com/hollodotme/fast-cgi-client/compare/v2.7.2...v3.0.0-alpha
[2.7.2]: https://github.com/hollodotme/fast-cgi-client/compare/v2.7.1...v2.7.2
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Please see the following links for earlier releases:

* PHP >= 7.0 (EOL) [v1.0.0], [v1.0.1], [v1.1.0], [v1.2.0], [v1.3.0], [v1.4.0], [v1.4.1], [v1.4.2]
* PHP >= 7.1 [v2.0.0], [v2.0.1], [v2.1.0], [v2.2.0], [v2.3.0], [v2.4.0], [v2.4.1], [v2.4.2], [v2.4.3], [v2.5.0], [v2.6.0], [v2.7.0], [v2.7.1],
[v2.7.2], [v3.0.0-alpha]
[v2.7.2], [v3.0.0-alpha], [v3.0.0-beta]

Read more about the journey to and changes in `v2.6.0` in [this blog post](https://hollo.me/php/background-info-fast-cgi-client-v2.6.0.html).

Expand Down Expand Up @@ -777,6 +777,7 @@ Run a call through a Unix Domain Socket
This shows the response of the php-fpm status page.


[v3.0.0-beta]: https://github.com/hollodotme/fast-cgi-client/blob/v3.0.0-beta/README.md
[v3.0.0-alpha]: https://github.com/hollodotme/fast-cgi-client/blob/v3.0.0-alpha/README.md
[v2.7.2]: https://github.com/hollodotme/fast-cgi-client/blob/v2.7.2/README.md
[v2.7.1]: https://github.com/hollodotme/fast-cgi-client/blob/v2.7.1/README.md
Expand Down
29 changes: 18 additions & 11 deletions src/Sockets/Socket.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
use function is_resource;
use function microtime;
use function ord;
use function random_int;
use function str_repeat;
use function stream_get_meta_data;
use function stream_select;
Expand All @@ -61,6 +60,8 @@ final class Socket
{
private const BEGIN_REQUEST = 1;

private const ABORT_REQUEST = 2;

private const END_REQUEST = 3;

private const PARAMS = 4;
Expand Down Expand Up @@ -93,7 +94,7 @@ final class Socket

public const STREAM_SELECT_USEC = 200000;

/** @var int */
/** @var SocketId */
private $id;

/** @var ConfiguresSocketConnection */
Expand Down Expand Up @@ -127,19 +128,21 @@ final class Socket
private $status;

/**
* @param SocketId $socketId
* @param ConfiguresSocketConnection $connection
* @param EncodesPacket $packetEncoder
* @param EncodesNameValuePair $nameValuePairEncoder
*
* @throws Exception
*/
public function __construct(
SocketId $socketId,
ConfiguresSocketConnection $connection,
EncodesPacket $packetEncoder,
EncodesNameValuePair $nameValuePairEncoder
)
{
$this->id = random_int( 1, (1 << 16) - 1 );
$this->id = $socketId;
$this->connection = $connection;
$this->packetEncoder = $packetEncoder;
$this->nameValuePairEncoder = $nameValuePairEncoder;
Expand All @@ -151,7 +154,7 @@ public function __construct(

public function getId() : int
{
return $this->id;
return $this->id->getValue();
}

public function usesConnection( ConfiguresSocketConnection $connection ) : bool
Expand Down Expand Up @@ -331,17 +334,21 @@ private function getRequestPackets( ProvidesRequestData $request ) : string
$requestPackets = $this->packetEncoder->encodePacket(
self::BEGIN_REQUEST,
chr( 0 ) . chr( self::RESPONDER ) . chr( 1 ) . str_repeat( chr( 0 ), 5 ),
$this->id
$this->id->getValue()
);

$paramsRequest = $this->nameValuePairEncoder->encodePairs( $request->getParams() );

if ( $paramsRequest )
{
$requestPackets .= $this->packetEncoder->encodePacket( self::PARAMS, $paramsRequest, $this->id );
$requestPackets .= $this->packetEncoder->encodePacket(
self::PARAMS,
$paramsRequest,
$this->id->getValue()
);
}

$requestPackets .= $this->packetEncoder->encodePacket( self::PARAMS, '', $this->id );
$requestPackets .= $this->packetEncoder->encodePacket( self::PARAMS, '', $this->id->getValue() );

if ( $request->getContent() )
{
Expand All @@ -355,14 +362,14 @@ private function getRequestPackets( ProvidesRequestData $request ) : string
$offset,
self::REQ_MAX_CONTENT_SIZE
),
$this->id
$this->id->getValue()
);
$offset += self::REQ_MAX_CONTENT_SIZE;
}
while ( $offset < $request->getContentLength() );
}

$requestPackets .= $this->packetEncoder->encodePacket( self::STDIN, '', $this->id );
$requestPackets .= $this->packetEncoder->encodePacket( self::STDIN, '', $this->id->getValue() );

return $requestPackets;
}
Expand Down Expand Up @@ -429,7 +436,7 @@ public function fetchResponse( ?int $timeoutMs = null ) : ProvidesResponseData
continue;
}

if ( self::END_REQUEST === $packetType && $packet['requestId'] === $this->id )
if ( self::END_REQUEST === $packetType && $packet['requestId'] === $this->id->getValue() )
{
break;
}
Expand Down Expand Up @@ -577,7 +584,7 @@ public function collectResource( array &$resources ) : void
{
if ( null !== $this->resource )
{
$resources[ (string)$this->id ] = $this->resource;
$resources[ (string)$this->id->getValue() ] = $this->resource;
}
}
}
13 changes: 9 additions & 4 deletions src/Sockets/SocketCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,21 @@ public function new(
{
for ( $i = 0; $i < 10; $i++ )
{
$socket = new Socket( $connection, $packetEncoder, $nameValuePairEncoder );
$socketId = SocketId::new();

if ( $this->exists( $socket->getId() ) )
if ( $this->exists( $socketId->getValue() ) )
{
continue;
}

$this->sockets[ $socket->getId() ] = $socket;
$this->sockets[ $socketId->getValue() ] = new Socket(
$socketId,
$connection,
$packetEncoder,
$nameValuePairEncoder
);

return $socket;
return $this->sockets[ $socketId->getValue() ];
}

throw new WriteFailedException( 'Could not allocate a new socket ID' );
Expand Down
69 changes: 69 additions & 0 deletions src/Sockets/SocketId.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php declare(strict_types=1);

namespace hollodotme\FastCGI\Sockets;

use Exception;
use InvalidArgumentException;
use function random_int;

final class SocketId
{
/** @var int */
private $id;

/**
* @param int $id
*
* @throws InvalidArgumentException
*/
private function __construct( int $id )
{
$this->guardValueIsValid( $id );

$this->id = $id;
}

/**
* @param int $value
*
* @throws InvalidArgumentException
*/
private function guardValueIsValid( int $value ) : void
{
if ( $value < 1 || $value > ((1 << 16) - 1) )
{
throw new InvalidArgumentException( 'Invalid socket ID (out of range): ' . $value );
}
}

/**
* @return SocketId
* @throws InvalidArgumentException
* @throws Exception
*/
public static function new() : self
{
return new self( random_int( 1, (1 << 16) - 1 ) );
}

/**
* @param int $id
*
* @return SocketId
* @throws InvalidArgumentException
*/
public static function fromInt( int $id ) : self
{
return new self( $id );
}

public function getValue() : int
{
return $this->id;
}

public function equals( SocketId $other ) : bool
{
return $this->id === $other->id;
}
}
1 change: 1 addition & 0 deletions tests/Integration/NetworkSocketTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use RuntimeException;
use SebastianBergmann\RecursionContext\InvalidArgumentException;
use Throwable;
use function http_build_query;

final class NetworkSocketTest extends TestCase
{
Expand Down
106 changes: 106 additions & 0 deletions tests/Unit/Sockets/SocketIdTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php declare(strict_types=1);

namespace hollodotme\FastCGI\Tests\Unit\Sockets;

use hollodotme\FastCGI\Sockets\SocketId;
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use SebastianBergmann\RecursionContext\InvalidArgumentException;

final class SocketIdTest extends TestCase
{
/**
* @throws \InvalidArgumentException
* @throws ExpectationFailedException
* @throws InvalidArgumentException
*/
public function testCanGetNewInstance() : void
{
for ( $i = 0; $i < 100; $i++ )
{
$socketId = SocketId::new();

$this->assertGreaterThanOrEqual( 1, $socketId->getValue() );
$this->assertLessThanOrEqual( (1 << 16) - 1, $socketId->getValue() );
}
}

/**
* @throws ExpectationFailedException
* @throws InvalidArgumentException
* @throws \InvalidArgumentException
*/
public function testGetValue() : void
{
$socketId = SocketId::new();

$this->assertGreaterThanOrEqual( 1, $socketId->getValue() );
$this->assertLessThanOrEqual( (1 << 16) - 1, $socketId->getValue() );
}

/**
* @throws ExpectationFailedException
* @throws InvalidArgumentException
* @throws \InvalidArgumentException
*/
public function testCanGetNewInstanceFromInt() : void
{
for ( $i = 1; $i < 10; $i++ )
{
$socketId = SocketId::fromInt( $i );

$this->assertSame( $i, $socketId->getValue() );
}
}

/**
* @param int $socketIdValue
*
* @throws \InvalidArgumentException
* @dataProvider outOfRangeSocketIdValueProvider
*/
public function testThrowsExceptionIfSocketIdValueIsOutOfRange( int $socketIdValue ) : void
{
$this->expectException( \InvalidArgumentException::class );
$this->expectExceptionMessage( 'Invalid socket ID (out of range): ' . $socketIdValue );

SocketId::fromInt( $socketIdValue );
}

public function outOfRangeSocketIdValueProvider() : array
{
return [
[
'socketIdValue' => 0,
],
[
'socketIdValue' => 1 << 16,
],
];
}

/**
* @throws ExpectationFailedException
* @throws InvalidArgumentException
* @throws \InvalidArgumentException
*/
public function testEquals() : void
{
$socketId = SocketId::fromInt( 123 );
$otherEquals = SocketId::fromInt( 123 );
$otherEqualsNot = SocketId::fromInt( 321 );

$this->assertNotSame( $socketId, $otherEquals );
$this->assertNotSame( $socketId, $otherEqualsNot );
$this->assertNotSame( $otherEquals, $otherEqualsNot );

$this->assertTrue( $socketId->equals( $otherEquals ) );
$this->assertTrue( $otherEquals->equals( $socketId ) );

$this->assertFalse( $socketId->equals( $otherEqualsNot ) );
$this->assertFalse( $otherEqualsNot->equals( $socketId ) );

$this->assertFalse( $otherEquals->equals( $otherEqualsNot ) );
$this->assertFalse( $otherEqualsNot->equals( $otherEquals ) );
}
}
Loading

0 comments on commit e518c0f

Please sign in to comment.