Skip to content

Commit

Permalink
Create v1.0.0 (#64)
Browse files Browse the repository at this point in the history
* default value for read and write timeout at least 2x heartbeat

* add facade signatures (#55)

* add documentation link to readme

* Feature/message headers (#60)

* Added headers to ResolverContract

* Apply fixes from StyleCI (#58)

* add advanced and headers documentation

* rename phpunit.xml to phpunit.xml.dist

* add unix signals handler (#61)

* add unix signals handler

* Apply fixes from StyleCI (#62)

* Fix closure to container

* Update changelog
  • Loading branch information
kauanslr authored Sep 3, 2019
1 parent 97a296f commit 5ac4093
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 10 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
## [1.0.0]
### Added
- Added headers to publisher
- Added `headers` to `ResolverContract`
- Added `assertEmitted` to `Pigeon::fake()`
- Added `assertConsumingEvent` to `Pigeon::fake()`
- Added `dispatchListener` to `Pigeon::fake()`
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
[![Build Status](https://travis-ci.org/convenia/Pigeon.svg?branch=develop)](https://travis-ci.org/convenia/Pigeon)
[![StyleCI](https://github.styleci.io/repos/201348189/shield?branch=develop)](https://github.styleci.io/repos/201348189)

Pigeon is a Laravel package for dealing with AMQP messaging messaging with easy syntax on top of php-amqplib.
[Documentation](https://convenia.github.io/Pigeon)

Pigeon is a Laravel package for dealing with AMQP messaging messaging with easy syntax on top of php-amqplib.

## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"php": ">=7.1.3",
"ext-json": "*",
"ext-sockets": "*",
"php-amqplib/php-amqplib": ">=2.8",
"php-amqplib/php-amqplib": ">=2.9",
"laravel/framework": "5.6.*|5.7.*|5.8.*",
"webpatser/laravel-uuid": "^3.0"
},
Expand Down
6 changes: 3 additions & 3 deletions config/pigeon.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
'vhost' => env('PIGEON_VHOST'),
],
'keepalive' => env('PIGEON_KEEPALIVE', true),
'heartbeat' => env('PIGEON_HEARTBEAT', 10),
'read_timeout' => env('PIGEON_READ_TIMEOUT', 130),
'write_timeout' => env('PIGEON_WRITE_TIMEOUT', 130),
'heartbeat' => $heartbeat = env('PIGEON_HEARTBEAT', 10),
'read_timeout' => env('PIGEON_READ_TIMEOUT', $heartbeat * 2.5),
'write_timeout' => env('PIGEON_WRITE_TIMEOUT', $heartbeat * 2.5),
],
'exchange' => env('PIGEON_EXCHANGE', 'pigeon'),
'exchange_type' => env('PIGEON_EXCHANGE_TYPE', 'direct'),
Expand Down
35 changes: 35 additions & 0 deletions docs/ADVANCED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ADVANCED USAGE
## Table of Contents {docsify-ignore}
1. [Introducing](#introducing)
1. [Headers](#headers)

## Introducing
Let's see some advanced uses of Pigeon

## Headers
You can easily add `application_headers` to message when publishing one with `header` method

```php
use Pigeon;

Pigeon::routing($routing)
->header($key, $value);
```

?> You can also pass **associative array** as value for header, it will be converted to dot notation

You can also capture all message headers with the resolver in your callback with `headers` method
```php
use Pigeon;

$callback = function ($data, $resolver) {
$resolver->headers();
};
Pigeon::queue($queue)
->callback($callback);
```

?> If you want a specific header you can pass it key to headers and it'll return only the header you asked for

!> In the opposite of publishing message, when consuming headers will not return only the **application_headers**
but all AMQPMessage internal headers
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
* [Home](/)
* [Installation](INSTALLATION.md)
* [Basics](BASICS.md)
* [Advanced](ADVANCED.md)
* [Testing](TESTING.md)
File renamed without changes.
43 changes: 42 additions & 1 deletion src/Drivers/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
abstract class Driver implements DriverContract
{
public const EVENT_EXCHANGE = 'event';

public const EVENT_EXCHANGE_TYPE = 'topic';

public $app;
Expand All @@ -23,9 +24,17 @@ abstract class Driver implements DriverContract
public function __construct(Application $app)
{
$this->app = $app;
$this->setup();
}

abstract public function getConnection();
public function setup()
{
if (extension_loaded('pcntl')) {
$this->listenSignals();
}

$this->app->terminating(\Closure::fromCallable([$this, 'quitHard']));
}

public function queue(string $name, array $properties = []): ConsumerContract
{
Expand Down Expand Up @@ -88,4 +97,36 @@ public function getProps(array $userProps = [])

return new AMQPTable(array_merge($dead, $userProps));
}

protected function listenSignals(): void
{
defined('AMQP_WITHOUT_SIGNALS') ?: define('AMQP_WITHOUT_SIGNALS', false);

pcntl_async_signals(true);

pcntl_signal(SIGTERM, [$this, 'signalHandler']);
pcntl_signal(SIGINT, [$this, 'signalHandler']);
pcntl_signal(SIGQUIT, [$this, 'signalHandler']);
}

public function signalHandler($signalNumber)
{
switch ($signalNumber) {
case SIGTERM: // 15 : supervisor default stop
$this->quitHard();
break;
case SIGQUIT: // 3 : kill -s QUIT
$this->quitHard();
break;
case SIGINT: // 2 : ctrl+c
$this->quit();
break;
}
}

abstract public function quitHard();

abstract public function quit();

abstract public function getConnection();
}
10 changes: 10 additions & 0 deletions src/Drivers/RabbitDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,14 @@ public function makeConnection()
$heartbeat = (int) $this->app['config']['pigeon.connection.heartbeat']
);
}

public function quitHard()
{
$this->getConnection()->close();
}

public function quit()
{
$this->quitHard();
}
}
8 changes: 6 additions & 2 deletions src/Facade/Pigeon.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
namespace Convenia\Pigeon\Facade;

use Illuminate\Support\Facades\Facade;
use Convenia\Pigeon\Consumer\ConsumerContract;
use Convenia\Pigeon\Support\Testing\PigeonFake;

/**
* Class Pigeon.
*
* @method static ConsumerContract queue(string $name)
* @method static \Convenia\Pigeon\Drivers\Driver driver(string $driver)
* @method static \Convenia\Pigeon\Publisher\PublisherContract routing(string $name = null)
* @method static \Convenia\Pigeon\Publisher\PublisherContract exchange(string $name, string $type = 'direct')
* @method static \Convenia\Pigeon\Publisher\PublisherContract emmit(string $event, array $data)
* @method static \Convenia\Pigeon\Consumer\ConsumerContract queue(string $name, array $properties = [])
* @method static \Convenia\Pigeon\Consumer\ConsumerContract events(string $name = '#')
*/
class Pigeon extends Facade
{
Expand Down
7 changes: 7 additions & 0 deletions src/Resolver/Resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,11 @@ private function responseProps()

return $message_props;
}

public function headers(string $key = null)
{
return is_null($key)
? $this->message->get_properties()
: $this->message->get($key);
}
}
2 changes: 2 additions & 0 deletions src/Resolver/ResolverContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ public function ack();
public function reject(bool $requeue = true);

public function response(array $data);

public function headers(string $key = null);
}
19 changes: 19 additions & 0 deletions tests/Integration/Consumer/ConsumerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ public function test_it_should_throw_timeout_with_multiple()
$consumer->callback($callback)->consume(1);
}

/**
* @requires extension pcntl
* @
*/
public function test_it_should_handle_sigterm_signal()
{
// should create queue
$consumer = $this->pigeon->queue($this->queue);
$msg = new AMQPMessage(json_encode(['some' => 'data']));
$this->channel->basic_publish($msg, '', $this->queue);

$callback = function () {
posix_kill(posix_getpid(), SIGTERM);
};

$consumer->callback($callback)->consume(30, true);
$this->assertTrue(true, 'It should not throw error.');
}

protected function tearDown(): void
{
$this->channel->queue_delete($this->queue);
Expand Down
20 changes: 20 additions & 0 deletions tests/Unit/ResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Convenia\Pigeon\Tests\Unit;

use Mockery;
use PhpAmqpLib\Wire\AMQPTable;
use Convenia\Pigeon\Tests\TestCase;
use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Message\AMQPMessage;
Expand Down Expand Up @@ -101,4 +102,23 @@ public function test_it_should_respond_a_message()
// act
$resolver->response(['foo' => 'fighters']);
}

public function test_it_should_return_message_headers()
{
// setup
$definedHeaders = [
'reply_to' => 'some.queue',
'application_headers' => new AMQPTable($appHeaders = [
'my' => 'header',
]),
];
$message = new AMQPMessage([], $definedHeaders);

// act
$resolver = new Resolver($message);

// assert
$this->assertEquals($definedHeaders, $resolver->headers());
$this->assertEquals($definedHeaders['reply_to'], $resolver->headers('reply_to'));
}
}

0 comments on commit 5ac4093

Please sign in to comment.