Skip to content

Commit eb8b0ca

Browse files
committed
Big 💥
0 parents  commit eb8b0ca

34 files changed

+1644
-0
lines changed

.ci/install_rdkafka.sh

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/sh
2+
3+
echo ${LIBRDKAFKA_VERSION}
4+
5+
git clone --depth 1 --branch "${LIBRDKAFKA_VERSION}" https://github.com/edenhill/librdkafka.git
6+
(
7+
cd librdkafka
8+
./configure
9+
make
10+
sudo make install
11+
)
12+
sudo ldconfig
13+
14+
pecl install rdkafka

.gitattributes

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Set the default behavior, in case people don't have core.autocrlf set.
2+
* text eol=lf
3+
/.ci export-ignore
4+
/tests export-ignore
5+
.gitattributes export-ignore
6+
.gitignore export-ignore
7+
.travis.yml export-ignore
8+
phpcs.xml.dist export-ignore
9+
phpstan.xml.dist export-ignore
10+
phpunit.xml.dist export-ignore

.github/stale.yml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Number of days of inactivity before an issue becomes stale
2+
daysUntilStale: 30
3+
# Number of days of inactivity before a stale issue is closed
4+
daysUntilClose: 7
5+
# Issues with these labels will never be considered stale
6+
exemptLabels:
7+
- pinned
8+
- security
9+
# Label to use when marking an issue as stale
10+
staleLabel: wontfix
11+
# Comment to post when marking an issue as stale. Set to `false` to disable
12+
markComment: >
13+
This issue has been automatically marked as stale because it has not had
14+
recent activity. It will be closed if no further activity occurs. Thank you
15+
for your contributions.
16+
# Comment to post when closing a stale issue. Set to `false` to disable
17+
closeComment: false

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/vendor/
2+
/composer.lock
3+
/.phpcs.xml
4+
/.phpunit.result.cache
5+
/.phpunit.xml
6+
/.phpcs-cache
7+
/phpstan.neon

.scrutinizer.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
build:
2+
nodes:
3+
analysis:
4+
environment:
5+
php:
6+
version: 7.2
7+
cache:
8+
disabled: false
9+
directories:
10+
- ~/.composer/cache
11+
project_setup:
12+
override: true
13+
tests:
14+
override:
15+
- php-scrutinizer-run
16+
- phpcs-run
17+
dependencies:
18+
before:
19+
- chmod +x .ci/install_rdkafka.sh
20+
-
21+
command: .ci/install_rdkafka.sh
22+
environment:
23+
LIBRDKAFKA_VERSION: v1.0.1
24+
25+
override:
26+
- composer install --no-interaction --prefer-dist
27+
28+
checks:
29+
php:
30+
code_rating: true
31+
32+
tools:
33+
external_code_coverage:
34+
timeout: 3600
35+
36+
build_failure_conditions:
37+
- 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse allowed
38+
- 'issues.severity(>= MAJOR).new.exists' # New issues of major or higher severity
39+
- 'project.metric_change("scrutinizer.test_coverage", < 0)' # Code Coverage decreased from previous inspection

.travis.yml

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
dist: trusty
2+
language: php
3+
sudo: required
4+
5+
php:
6+
- 7.2
7+
- 7.3
8+
- 7.4snapshot
9+
10+
env:
11+
global:
12+
- LIBRDKAFKA_VERSION=v1.0.1
13+
matrix:
14+
- DEPENDENCIES=--prefer-dist
15+
- DEPENDENCIES=--prefer-dist --prefer-lowest
16+
17+
before_install:
18+
- docker-compose --file tests/docker-compose.yml up -d
19+
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available"
20+
- chmod +x .ci/install_rdkafka.sh
21+
- .ci/install_rdkafka.sh
22+
23+
install:
24+
- travis_retry composer update --prefer-dist
25+
26+
script:
27+
- ./vendor/bin/phpunit
28+
29+
jobs:
30+
include:
31+
- stage: Test
32+
name: Coverage
33+
php: 7.2
34+
before_script:
35+
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{.disabled,}
36+
- if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi
37+
script:
38+
- ./vendor/bin/phpunit --coverage-clover ./build/logs/clover.xml
39+
after_script:
40+
- wget https://github.com/scrutinizer-ci/ocular/releases/download/1.5.2/ocular.phar
41+
- php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml
42+
43+
- stage: Code Quality
44+
name: Code Style
45+
script:
46+
- ./vendor/bin/phpcs
47+
48+
- stage: Code Quality
49+
name: Static Analysis
50+
script:
51+
- ./vendor/bin/phpstan analyse
52+
53+
cache:
54+
directories:
55+
- $HOME/.composer/cache
56+

LICENCE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2018 Šimon Podlipský <[email protected]>
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the "Software"), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7+
of the Software, and to permit persons to whom the Software is furnished to do
8+
so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# PHP Kafka boilerplate wrapper around RdKafka
2+
3+
[![Build Status](https://travis-ci.org/simPod/Kafka.svg)](https://travis-ci.org/simPod/Kafka)
4+
[![Downloads](https://poser.pugx.org/simpod/kafka/d/total.svg)](https://packagist.org/packages/simpod/kafka)
5+
[![Packagist](https://poser.pugx.org/simpod/kafka/v/stable.svg)](https://packagist.org/packages/simpod/kafka)
6+
[![Licence](https://poser.pugx.org/simpod/kafka/license.svg)](https://packagist.org/packages/simpod/kafka)
7+
[![Quality Score](https://scrutinizer-ci.com/g/simPod/Kafka/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/simPod/Kafka)
8+
[![Code Coverage](https://scrutinizer-ci.com/g/simPod/Kafka/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/simPod/Kafka)
9+
10+
## Installation
11+
12+
Add as [Composer](https://getcomposer.org/) dependency:
13+
14+
```sh
15+
composer require simpod/kafka
16+
```
17+
18+
## Config Constants
19+
20+
Some config constants are provided like `ConsumerConfig`, `ProducerConfig` or `CommonClientConfigs`.
21+
22+
However, they are copied from Java API and not all are applicable to librdkafka. Consult with librdkafka documentation before use.
23+
24+
## Clients
25+
26+
### Consumer
27+
28+
`KafkaConsumer` boilerplate is available with `startBatch()` method ([(to suplement this example in librdkafka)](https://github.com/edenhill/librdkafka/blob/master/examples/rdkafka_consume_batch.cpp#L97)) and with `start()`.
29+
They also handle termination signals for you.
30+
31+
```php
32+
<?php
33+
34+
declare(strict_types=1);
35+
36+
namespace Your\AppNamespace;
37+
38+
use RdKafka\Message;
39+
use SimPod\Kafka\Clients\Consumer\ConsumerConfig;
40+
use SimPod\Kafka\Clients\Consumer\ConsumerRecords;
41+
use SimPod\Kafka\Clients\Consumer\KafkaConsumer;
42+
43+
final class ExampleBatchConsumer
44+
{
45+
public function run() : void
46+
{
47+
$kafkaConsumer = new KafkaConsumer($this->getConfig());
48+
49+
$kafkaConsumer->subscribe(['topic1']);
50+
51+
$kafkaConsumer->startBatch(
52+
static function (Message $message) : void {
53+
// Process record
54+
},
55+
static function (ConsumerRecords $consumerRecords) use ($kafkaConsumer) : void {
56+
// Process records batch
57+
58+
$kafkaConsumer->commit($consumerRecords->getLast());
59+
},
60+
200000,
61+
120 * 1000
62+
);
63+
}
64+
65+
private function getConfig() : ConsumerConfig
66+
{
67+
$config = new ConsumerConfig();
68+
69+
$config->set(ConsumerConfig::BOOTSTRAP_SERVERS_CONFIG, '127.0.0.1:9092');
70+
$config->set(ConsumerConfig::ENABLE_AUTO_COMMIT_CONFIG, false);
71+
$config->set(ConsumerConfig::CLIENT_ID_CONFIG, gethostname());
72+
$config->set(ConsumerConfig::AUTO_OFFSET_RESET_CONFIG, 'earliest');
73+
$config->set(ConsumerConfig::GROUP_ID_CONFIG, 'consumer_group_name');
74+
75+
return $config;
76+
}
77+
}
78+
```
79+
80+
```php
81+
<?php
82+
83+
declare(strict_types=1);
84+
85+
namespace Your\AppNamespace;
86+
87+
use RdKafka\Message;
88+
use SimPod\Kafka\Clients\Consumer\ConsumerConfig;
89+
use SimPod\Kafka\Clients\Consumer\KafkaConsumer;
90+
91+
final class ExampleConsumer
92+
{
93+
public function run() : void
94+
{
95+
$kafkaConsumer = new KafkaConsumer($this->getConfig(), Logger::get());
96+
97+
$kafkaConsumer->subscribe(['topic1']);
98+
99+
$kafkaConsumer->start(
100+
120 * 1000,
101+
static function (Message $message) use ($kafkaConsumer) : void {
102+
// Process message here
103+
104+
$kafkaConsumer->commit($message); // Autocommit is disabled
105+
}
106+
);
107+
}
108+
109+
private function getConfig() : ConsumerConfig
110+
{
111+
$config = new ConsumerConfig();
112+
113+
$config->set(ConsumerConfig::BOOTSTRAP_SERVERS_CONFIG, '127.0.0.1:9092');
114+
$config->set(ConsumerConfig::ENABLE_AUTO_COMMIT_CONFIG, false);
115+
$config->set(ConsumerConfig::CLIENT_ID_CONFIG, gethostname());
116+
$config->set(ConsumerConfig::AUTO_OFFSET_RESET_CONFIG, 'earliest');
117+
$config->set(ConsumerConfig::GROUP_ID_CONFIG, 'consumer_group_name');
118+
119+
return $config;
120+
}
121+
}
122+
```
123+
124+
### Development
125+
126+
There is `kwn/php-rdkafka-stubs` listed as a dev dependency so it properly integrates php-rdkafka extension with IDE.

composer.json

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "simpod/kafka",
3+
"description": "PHP Kafka boilerplate wrapper around RdKafka",
4+
"type": "library",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Simon Podlipsky",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"config": {
13+
"sort-packages": true
14+
},
15+
"require": {
16+
"php": "^7.2",
17+
"ext-pcntl": "*",
18+
"ext-rdkafka": "*",
19+
"psr/log": "^1.1",
20+
"symfony/polyfill-php73": "^1.11"
21+
},
22+
"require-dev": {
23+
"doctrine/coding-standard": "^6.0",
24+
"kwn/php-rdkafka-stubs": "^1.0",
25+
"phpstan/extension-installer": "^1.0",
26+
"phpstan/phpstan": "^0.11.8",
27+
"phpstan/phpstan-phpunit": "^0.11.2",
28+
"phpstan/phpstan-strict-rules": "^0.11.1",
29+
"phpunit/phpunit": "^8.0"
30+
},
31+
"suggest": {
32+
"kwn/php-rdkafka-stubs": "Support and autocompletion for RDKafka in IDE | require as dev dependency"
33+
},
34+
"autoload": {
35+
"psr-4": {
36+
"SimPod\\Kafka\\": "src/"
37+
}
38+
},
39+
"autoload-dev": {
40+
"psr-4": {
41+
"SimPod\\Kafka\\Tests\\": "tests/"
42+
}
43+
}
44+
}

phpcs.xml.dist

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0"?>
2+
<ruleset>
3+
<arg name="basepath" value="."/>
4+
<arg name="extensions" value="php"/>
5+
<arg name="parallel" value="80"/>
6+
<arg name="cache" value=".phpcs-cache"/>
7+
<arg name="colors"/>
8+
9+
<!-- Ignore warnings, show progress of the run and show sniff names -->
10+
<arg value="nps"/>
11+
12+
<file>src</file>
13+
14+
<rule ref="Doctrine"/>
15+
16+
17+
<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFallbackGlobalName">
18+
<severity>5</severity>
19+
</rule>
20+
21+
<rule ref="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses">
22+
<properties>
23+
<property name="psr12Compatible" type="bool" value="true"/>
24+
</properties>
25+
</rule>
26+
</ruleset>

phpstan.neon.dist

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
parameters:
2+
level: max
3+
paths:
4+
- %currentWorkingDirectory%/src
5+
- %currentWorkingDirectory%/tests

phpunit.xml.dist

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
4+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
6+
beStrictAboutChangesToGlobalState="true"
7+
beStrictAboutOutputDuringTests="true"
8+
beStrictAboutTodoAnnotatedTests="true"
9+
bootstrap="tests/bootstrap.php"
10+
colors="true"
11+
executionOrder="random"
12+
>
13+
<testsuites>
14+
<testsuite name="Test Suite">
15+
<directory>tests</directory>
16+
</testsuite>
17+
</testsuites>
18+
<filter>
19+
<whitelist processUncoveredFilesFromWhitelist="true">
20+
<directory suffix=".php">src</directory>
21+
</whitelist>
22+
</filter>
23+
</phpunit>

0 commit comments

Comments
 (0)