PHPackages                             sbooker/persistent-pointer - 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. sbooker/persistent-pointer

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

sbooker/persistent-pointer
==========================

1.0.1(5y ago)04.6k2MITPHPPHP ^7.4 || ^8.0CI failing

Since Feb 2Pushed 10mo ago1 watchersCompare

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

READMEChangelogDependencies (1)Versions (3)Used By (2)

[Read in English](README.EN.MD)

Persistent Pointer (`sbooker/persistent-pointer`)
=================================================

[](#persistent-pointer-sbookerpersistent-pointer)

[![Latest Version](https://camo.githubusercontent.com/ed84113054c18049f1c65c76d273843ea330760ff657ef188aa9a648f0af83fb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73626f6f6b65722f70657273697374656e742d706f696e7465722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/sbooker/persistent-pointer)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/sbooker/persistent-pointer/blob/master/LICENSE)[![PHP Version](https://camo.githubusercontent.com/984a8d1ffc4768332b0f93353fc5f6650e4559b02983f48696a2a5b55c344acf/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f73626f6f6b65722f70657273697374656e742d706f696e7465722e7376673f7374796c653d666c61742d737175617265)](https://php.net)[![Total Downloads](https://camo.githubusercontent.com/38866999ca895f56eda0b5efbc79872039f6c938cb8aae7e5d301277a9757ef8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73626f6f6b65722f70657273697374656e742d706f696e7465722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/sbooker/persistent-pointer)

Простая библиотека для создания и управления именованными, персистентными "указателями" — счетчиками, которые могут только увеличиваться.

Назначение библиотеки
---------------------

[](#назначение-библиотеки)

При создании фоновых обработчиков (воркеров, консьюмеров) часто возникает задача: **как надежно сохранить позицию, на которой остановился обработчик в прошлый раз?**

Эта библиотека решает данную задачу, предоставляя `Pointer` — простой объект, который хранит именованный целочисленный счетчик в базе данных.

Ключевые особенности
--------------------

[](#ключевые-особенности)

- **Персистентность:** Состояние указателя сохраняется в хранилище (например, в базе данных).
- **Безопасность при конкурентном доступе:** Метод `getLocked()` гарантирует, что только один процесс может работать с указателем в один момент времени.
- **Монотонное возрастание:** Значение указателя можно только увеличить с помощью метода `increaseTo()`. Это защищает от случайного "отката" прогресса.
- **Абстракция над хранилищем:** Библиотека не зависит от конкретной ORM благодаря интерфейсу `PointerStorage`.

Установка
---------

[](#установка)

```
composer require sbooker/persistent-pointer
```

Быстрый старт
-------------

[](#быстрый-старт)

### Шаг 1: Реализуйте `PointerStorage`

[](#шаг-1-реализуйте-pointerstorage)

Вам нужно создать "мост" к вашей ORM. Этот адаптер будет использоваться "под капотом" `TransactionManager`.

```
// src/Infrastructure/Persistence/PointerStorage.php

use Sbooker\PersistentPointer\Pointer;
use Sbooker\PersistentPointer\PointerStorage;
use Sbooker\TransactionManager\TransactionManager;

final class DoctrinePointerStorage implements PointerStorage
{
    private TransactionManager $transactionManager;

    public function __construct(TransactionManager $transactionManager)
    {
        $this->transactionManager = $transactionManager;
    }

    public function add(Pointer $pointer): void
    {
        // Делегируем всю работу TransactionManager
        $this->transactionManager->persist($pointer);
    }

    public function getAndLock(string $name): ?Pointer
    {
        // Делегируем всю работу TransactionManager
        return $this->transactionManager->getLocked(Pointer::class, $name);
    }
}
```

### Шаг 2: Соберите `Repository`

[](#шаг-2-соберите-repository)

Соберите репозиторий, передав в него вашу реализацию `PointerStorage`.

```
// bootstrap.php или ваш DI-контейнер

/** @var TransactionManager $transactionManager */
$pointerStorage = new PointerStorage($transactionManager);
$pointerRepository = new Sbooker\PersistentPointer\Repository($pointerStorage);
```

### Шаг 3: Используйте в фоновом обработчике

[](#шаг-3-используйте-в-фоновом-обработчике)

`Pointer` идеально раскрывает себя внутри транзакции, управляемой `sbooker/transaction-manager`. Это гарантирует, что и обработка данных, и обновление указателя произойдут атомарно.

```
// src/Worker/EventProcessor.php
final class EventProcessor
{
    private const POINTER_NAME = 'event_processor';

    private Repository $pointerRepository;
    private TransactionManager $transactionManager;
    private EventRepository $eventRepository; // Репозиторий для ваших событий

    // ... constructor ...

    public function processBatch(): void
    {
        $this->transactionManager->transactional(function (): void {
            // 1. Получаем указатель с блокировкой.
            // Этот вызов будет использовать getLocked() из TransactionManager,
            // обеспечивая блокировку внутри общей транзакции.
            $pointer = $this->pointerRepository->getLocked(self::POINTER_NAME);
            $lastPosition = $pointer->getValue();

            // 2. Получаем новую порцию данных
            $events = $this->eventRepository->findSince($lastPosition);

            if (empty($events)) {
                return;
            }

            // 3. Обрабатываем данные...
            foreach ($events as $event) {
                // ... do some work ...
                $lastPosition = $event->getPosition();
            }

            // 4. Передвигаем указатель на новую позицию
            $pointer->increaseTo($lastPosition);

            // TransactionManager атомарно сохранит и новое значение указателя,
            // и любые другие изменения, сделанные в этой транзакции.
        });
    }
}
```

License
-------

[](#license)

See [LICENSE](https://github.com/sbooker/persistent-pointer/blob/master/LICENSE) file.

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~99 days

Total

2

Last Release

1878d ago

### Community

Maintainers

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

---

Top Contributors

[![sbooker](https://avatars.githubusercontent.com/u/3658174?v=4)](https://github.com/sbooker "sbooker (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/sbooker-persistent-pointer/health.svg)

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

PHPackages © 2026

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