PHPackages                             sconcur/sconcur - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. sconcur/sconcur

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

sconcur/sconcur
===============

PHP concurrency library backed by an extension written in Go

0.6.0(5d ago)151MITPHPPHP ^8.4CI passing

Since Nov 27Pushed 1w agoCompare

[ Source](https://github.com/sprust/sconcur)[ Packagist](https://packagist.org/packages/sconcur/sconcur)[ RSS](/packages/sconcur-sconcur/feed)WikiDiscussions master Synced today

READMEChangelog (6)Dependencies (10)Versions (30)Used By (0)

SConcur
=======

[](#sconcur)

> ⚠️ Экспериментальный проект, пока не готов к продакшену. Очередная попытка сделать PHP асинхронным, но без расширения на C: на Go — языке, который всё шире распространяется среди PHP-разработчиков.

Библиотека конкурентности для PHP поверх собственного расширения на Go. PHP-фаза (Fiber) приостанавливается, пока Go-расширение выполняет задачу (операции MongoDB, sleep и т.п.) конкурентно в горутинах. Обмен между PHP и Go идёт через MessagePack.

Содержание
----------

[](#содержание)

- [Идея](#%D0%B8%D0%B4%D0%B5%D1%8F)
- [Применение и ограничения](#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8-%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D1%8F)
- [Как это работает](#%D0%BA%D0%B0%D0%BA-%D1%8D%D1%82%D0%BE-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82)
- [Версии, на которых тестировалось](#%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B8-%D0%BD%D0%B0-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D1%85-%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB%D0%BE%D1%81%D1%8C)
- [Документация](#%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%86%D0%B8%D1%8F)
- [Build](#build)
- [echo test](#echo-test)
- [example](#example)
- [Планы](#%D0%BF%D0%BB%D0%B0%D0%BD%D1%8B)

Идея
----

[](#идея)

Идея SConcur — вынести I/O-операции (MongoDB, sleep и т.п.) в Go-часть и выполнять их параллельно. PHP по своей природе синхронен: запросы к БД блокируют процесс по очереди. Здесь каждая I/O-операция уходит в Go и исполняется в отдельной горутине, поэтому десятки запросов летят веером, и общее время ограничено самой медленной операцией, а не их суммой. PHP остаётся тонким слоем-оркестратором, вся конкурентность живёт в Go.

Почему именно Go:

- Удобная модель конкурентности: горутины и каналы дают дешёвый параллелизм. Одна задача — одна горутина, результаты собираются через канал. Не нужны внешний event-loop, пул потоков или callback-ад.
- Простота добавления фич: чтобы подключить новую I/O-операцию, достаточно написать обычный синхронный Go-обработчик, рантайм сам выполнит его конкурентно. Блокирующий драйвер (например, официальный MongoDB) используется как есть.
- Зрелая экосистема: драйверы и библиотеки Go переиспользуются напрямую.

Применение и ограничения
------------------------

[](#применение-и-ограничения)

- Только CLI. Библиотека рассчитана на долгоживущие CLI-процессы (воркеры, демоны, скрипты, консольные команды). С PHP-FPM использовать нельзя: расширение держит Go-рантайм и горутины на уровне процесса, а модель FPM (короткий запрос-ответ, общие процессы пула) этому противоречит.
- Нельзя `pcntl_fork` после загрузки расширения. Go-рантайм и его горутины не переживают `fork`: дочерний процесс получит неработоспособный рантайм (зависания, падения). Если нужен пул воркеров — форкайтесь до первого обращения к расширению либо запускайте отдельные процессы (`exec`), а расширение инициализируйте уже в потомке.
- Только NTS (non-thread-safe). ZTS-сборка PHP не поддерживается.
- Только Linux. Расширение и библиотека используют специфику Linux (определение числа ядер, сигналы/`posix`, `SO_REUSEPORT`, `flock` мастера и т.д.). Другие ОС не поддерживаются.
- Не вызывайте `exit()`/`die()` при активных задачах. Если оборвать процесс, пока в Go выполняются задачи (незавершённый `WaitGroup`, открытый курсор), поведение не определено: результаты и освобождение ресурсов не гарантируются. Сначала доведите задачи до конца или остановите их (`WaitGroup::stop()`), затем завершайте процесс.
- Конкурентный режим необязателен. Любую фичу, которая ходит в Go-часть (`Sleeper`, `MongoDB` и т.д.), можно вызывать и вне `WaitGroup` — как обычный синхронный вызов. Вне Fiber `FeatureExecutor` определяет неасинхронный контекст и просто дожидается результата (`Extension::wait`), возвращая его сразу. Удобно, когда конкурентность не нужна, а единый API хочется сохранить.

```
// синхронно, без WaitGroup — вернёт результат сразу
$collection->insertOne(['name' => 'example']);
```

Как это работает
----------------

[](#как-это-работает)

Коротко: `WaitGroup` оборачивает каждое замыкание в `Fiber`. При вызове асинхронной фичи корутина приостанавливается, а задача уходит в Go и исполняется в отдельной горутине. Единый процессный `Scheduler` ждёт расширение (`waitAny`), получает первый готовый результат любого флоу и возобновляет нужную корутину по `taskKey`. Результаты приходят в порядке завершения задач, а не в порядке `add()`.

Подробный разбор — со схемами «PHP Fiber ↔ Go goroutine», слоями и жизненным циклом задачи — в [docs/architecture.ru.md](docs/architecture.ru.md).

Версии, на которых тестировалось
--------------------------------

[](#версии-на-которых-тестировалось)

Точные версии окружения (Docker-образы и зависимости), на которых проект собирается и проходит тесты в CI:

КомпонентВерсияPHP8.4.15 (NTS, cli)Go (сборка расширения)1.26.1MongoDB (сервер)8.0.5ext-mongodb (PHP-расширение)1.21.5mongodb/mongodb (composer-пакет)1.21.3ext-msgpack3.0.1MySQL (сервер)8.4go-sql-driver/mysql1.8.1PostgreSQL (сервер)16jackc/pgx/v55.7.2go.mongodb.org/mongo-driver/v22.6.0Документация
------------

[](#документация)

- [Консольные команды](docs/cli.ru.md) — `bin/sconcur-load` (скачать собранное расширение нужной версии), `bin/sconcur-status` (проверить установку и версию, с `--json`), `bin/sconcur-server` (мастер воркеров, кратко со ссылкой).
- [Архитектура](docs/architecture.ru.md) — устройство изнутри: связка Fiber ↔ goroutine, планировщик, слои, жизненный цикл задачи.
- [MongoDB](docs/mongodb.ru.md) — операции коллекции (CRUD, агрегация, индексы, bulkWrite), курсоры со стримингом, результаты, типы BSON, конкурентность, таймауты и внутреннее устройство.
- [HTTP-сервер](docs/http-server.ru.md) — долгоживущий демон, запрос в корутине: быстрый старт, параметры, стриминг, graceful shutdown, внутреннее устройство и ограничения в отличие от типовых серверов.
- [Сокет-сервер (TCP)](docs/socket-server.ru.md) — долгоживущий TCP-сервер с фреймингом length-prefix, модель «сообщение → ответ»: быстрый старт, обработчик, параметры, конкурентность, graceful shutdown / `SO_REUSEPORT`, ограничения.
- [Мастер воркеров](docs/worker-master.ru.md) — супервизор пула процессов-воркеров (CLI `bin/sconcur-server` `start`/`status`/`reload`/`stop`): масштаб на ядра через `SO_REUSEPORT`, перезапуск упавших и исчерпавших `maxRequests`, graceful shutdown, лог и state-файл, единственный инстанс, самозавершение осиротевших воркеров.
- [Статистика сервера](docs/admin-stats.ru.md) — воркеры пушат снапшоты в мастер по unix-сокету, мастер на своём порту отдаёт агрегат по пулу `SO_REUSEPORT` (HTTP или socket): ручка `GET /api/stats` (метрики/JSON/HTML), живая панель, SSE, Bearer-токен.
- [HTTP-клиент](docs/http-client.ru.md) — асинхронный PSR-18 клиент со стримингом ответа: быстрый старт, конкурентность веером, параметры/таймауты, обработка ошибок PSR-18, внутреннее устройство.
- [Сокет-клиент (TCP)](docs/socket-client.ru.md) — асинхронный TCP-клиент с фреймингом length-prefix (зеркало сокет-сервера): `connect()` → `Connection`(read/write/close), конкурентность веером, параметры/таймауты, обработка ошибок, внутреннее устройство.
- [WebSocket-сервер](docs/websocket-server.ru.md) — долгоживущий WS-сервер (гибрид HTTP-Upgrade листенера и push-модели сокет-сервера): text/binary сообщения, `Connection` read/write/close, keepalive-ping, параметры, graceful shutdown / `SO_REUSEPORT`, ограничения.
- [WebSocket-клиент](docs/websocket-client.ru.md) — асинхронный WS-клиент (зеркало WS-сервера): `connect()` → `Connection` (read/write/close, text/binary), конкурентность веером, параметры/таймауты, обработка ошибок, внутреннее устройство.
- [MySQL (универсальная SQL-фича)](docs/mysql.ru.md) — запросы с биндингами, стриминг SELECT, транзакции; пул соединений и устройство.
- [PostgreSQL](docs/pgsql.ru.md) — второй драйвер той же SQL-фичи; отличия PG (плейсхолдеры `$1`, `RETURNING`, `BOOLEAN`).
- [Как добавить новую фичу верхнего уровня](docs/adding-a-feature.ru.md) — пошагово (со стримингом и без), с обязательными требованиями: отмена контекста и передача предельного времени выполнения.
- [Как добавить новый сервер](docs/adding-a-server.ru.md) — долгоживущий сетевой сервер (как `HttpServer`): паттерн Serve/Respond, цикл обслуживания, graceful shutdown и `SO_REUSEPORT`, интеграция с мастером воркеров.
- [Нагрузочное тестирование](docs/load-testing.ru.md) — поведение сервера под нагрузкой всеми I/O-фичами сразу (ручка `/all` + `bench-http-load-stats`): результаты по памяти/CPU и выводы.

Build
-----

[](#build)

```
rm -f build/sconcur.so build/sconcur.h && \
  CGO_CFLAGS=$(php-config --includes) \
  go build -buildmode=c-shared -o build/sconcur.so .
```

echo test
---------

[](#echo-test)

```
php -d extension=./build/sconcur.so -r "echo \SConcur\Extension\ping('hello') . PHP_EOL;"
```

example
-------

[](#example)

```
$collection = new \SConcur\Features\Mongodb\Connection\Client('mongodb://localhost:27017')
    ->selectDatabase('example')
    ->selectCollection('example');

$waitGroup = \SConcur\WaitGroup::create();

$waitGroup->add(
    function () {
        \SConcur\Features\Sleeper\Sleeper::sleep(seconds: 1);

        return 1;
    }
);

$waitGroup->add(
    function () {
        \SConcur\Features\Sleeper\Sleeper::usleep(microseconds: 11_000);

        return 2;
    }
);

$waitGroup->add(
    function () use ($collection) {
        $collection->insertOne(['name' => 'example']);

        return 3;
    }
);

$waitGroup->add(
    function () use ($collection) {
        $iterator = $collection->aggregate([
            [
                '$match' => ['name' => 'example'],
            ],
        ]);

        foreach ($iterator as $item) {
            echo $item['name'] . PHP_EOL;
        }

        return 4;
    }
);

$iterator = $waitGroup->iterate();

foreach ($iterator as $key => $item) {
    echo "result: $item" . PHP_EOL;
}
```

Планы
-----

[](#планы)

Краткий список направлений развития.

- Авто-восстановление зависших воркеров — watchdog мастера по heartbeat: `SIGKILL` и respawn воркера, у которого завис PHP-поток (нативный блок/CPU-цикл).
- Разнести ядро и фичи по отдельным пакетам — core отдельно, фичи плагинами поверх.
- Остановка отдельной корутины из любой точки (а не только всего флоу).
- Лимит параллелизма группы — `WaitGroup::create(maxConcurrency: N)`, backpressure для пула задач.

###  Health Score

25

—

LowBetter than 35% of packages

Maintenance64

Regular maintenance activity

Popularity8

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity19

Early-stage or recently created project

 Bus Factor1

Top contributor holds 99.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

5d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/eb5944a5bfd39c64f072b6c43fc6a315e4eea4d14c409538d1fd6de61a234847?d=identicon)[spp28rus](/maintainers/spp28rus)

---

Top Contributors

[![sprust](https://avatars.githubusercontent.com/u/57857525?v=4)](https://github.com/sprust "sprust (394 commits)")[![sprust28](https://avatars.githubusercontent.com/u/190169196?v=4)](https://github.com/sprust28 "sprust28 (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/sconcur-sconcur/health.svg)

```
[![Health](https://phpackages.com/badges/sconcur-sconcur/health.svg)](https://phpackages.com/packages/sconcur-sconcur)
```

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k15](/packages/tempest-framework)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

85036.3k](/packages/flow-php-flow)[cakephp/cakephp

The CakePHP framework

8.9k19.5M1.8k](/packages/cakephp-cakephp)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

35789.4k2](/packages/telnyx-telnyx-php)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[anthropic-ai/sdk

Anthropic PHP SDK

163583.3k17](/packages/anthropic-ai-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
