Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php: ['8.4']
php: ['8.4', '8.5']
steps:
- uses: actions/checkout@v4

Expand All @@ -33,14 +33,18 @@ jobs:
run: vendor/bin/phpunit

soak:
name: Flat-memory soak (5k request cycles)
name: Flat-memory soak (5k request cycles, PHP ${{ matrix.php }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['8.4', '8.5']
steps:
- uses: actions/checkout@v4

- uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
php-version: ${{ matrix.php }}
extensions: ffi
ini-values: ffi.enable=1, opcache.jit=off
coverage: none
Expand All @@ -52,14 +56,18 @@ jobs:
run: php -d ffi.enable=1 tools/soak.php 5000

soak-drop:
name: Reclaiming soak (5k persist/drop cycles)
name: Reclaiming soak (5k persist/drop cycles, PHP ${{ matrix.php }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['8.4', '8.5']
steps:
- uses: actions/checkout@v4

- uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
php-version: ${{ matrix.php }}
extensions: ffi
ini-values: ffi.enable=1, opcache.jit=off
coverage: none
Expand All @@ -71,14 +79,18 @@ jobs:
run: php -d ffi.enable=1 tools/soak-drop.php 5000

request-boundary:
name: True multi-request gate (php-cgi/FastCGI)
name: True multi-request gate (php-cgi/FastCGI, PHP ${{ matrix.php }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['8.4', '8.5']
steps:
- uses: actions/checkout@v4

- uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
php-version: ${{ matrix.php }}
extensions: ffi
ini-values: ffi.enable=1, opcache.jit=off
coverage: none
Expand Down
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![CI](https://github.com/lisachenko/php-shared-data-extension/actions/workflows/ci.yml/badge.svg)](https://github.com/lisachenko/php-shared-data-extension/actions/workflows/ci.yml)
[![Latest Version](https://img.shields.io/packagist/v/lisachenko/php-shared-data-extension?include_prereleases)](https://packagist.org/packages/lisachenko/php-shared-data-extension)
[![PHP 8.4](https://img.shields.io/badge/php-8.4-777BB3.svg?logo=php&logoColor=white)](composer.json)
[![PHP 8.4 | 8.5](https://img.shields.io/badge/php-8.4%20%7C%208.5-777BB3.svg?logo=php&logoColor=white)](composer.json)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

**PHP objects that survive the request boundary. In pure PHP.**
Expand Down Expand Up @@ -263,9 +263,7 @@ CI runs all of the above on every push and pull request.

## Requirements

- PHP ~8.4 (NTS) with `ext-ffi`
- `lisachenko/z-engine` — temporarily pinned to the
`claude/shared-objects-dag-memory-nq462w` branch, which adds the persistent
free primitives (`Core::persistentFree()`, `PersistentHashTable::destroy()`,
`HashTable::deleteIndex()`) this release needs; back to `dev-master` (or the
`8.4` release line once tagged) as soon as that lands
- PHP 8.4 or 8.5 (NTS) with `ext-ffi`
- `lisachenko/z-engine` — required as `8.4.x-dev || 8.5.x-dev`; z-engine tracks
one PHP minor per line, and Composer resolves the line matching the running
PHP (the `8.4` branch on PHP 8.4, `master` — aliased `8.5.x-dev` — on PHP 8.5)
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"description": "Shared data extension for PHP: persistent memory and request-surviving objects",
"type": "library",
"require": {
"lisachenko/z-engine": "dev-master || ^8.4",
"php": "~8.4.0",
"lisachenko/z-engine": "8.4.x-dev || 8.5.x-dev",
"php": "^8.4",
"ext-ffi": "*"
},
"require-dev": {
Expand Down
11 changes: 8 additions & 3 deletions src/PersistentStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use FFI\CData;
use ZEngine\Core;
use ZEngine\Reflection\ReflectionValue;
use ZEngine\Type\HashTable;
use ZEngine\Type\ObjectEntry;
use ZEngine\Type\PersistentObjectFactory;

Expand Down Expand Up @@ -332,10 +331,16 @@ public function detach(): void
$objectEntry = ObjectEntry::fromCData($object->object);

// Release the request-allocated properties hashtable rebuilt by
// get_object_vars()/var_dump()/casts, it would dangle next request
// get_object_vars()/var_dump()/casts, it would dangle next request.
// Mirrors zend_array_release(): drop our reference, and let the
// engine dismantle the table through its own allocator at zero
$dynamicProperties = $objectEntry->getDynamicPropertiesPointer();
if ($dynamicProperties !== null) {
(new HashTable($dynamicProperties))->releaseReference();
$gcHeader = $dynamicProperties->gc;
$gcHeader->refcount = $gcHeader->refcount - 1;
if ($gcHeader->refcount === 0) {
Core::call('rc_dtor_func', Core::cast('zend_refcounted *', $dynamicProperties));
}
$objectEntry->setDynamicPropertiesPointer(null);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Persister.php
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ private function persistStringSlot(CData $slot, string $path): void
*/
private function persistArray(CData $sourceArray, string $path): PersistentHashTable
{
$target = PersistentHashTable::create();
$target = new PersistentHashTable();

// Ownership is recorded up front: elements converted below may mint nested tables,
// and they all belong to the same object - the one whose slot started this array
Expand Down
14 changes: 7 additions & 7 deletions src/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ public static function fromAddress(int $address): self
*/
public static function create(): array
{
$root = PersistentHashTable::create();
self::addPointer($root, 'entries', PersistentHashTable::create()->getRawValue());
self::addPointer($root, 'objects', PersistentHashTable::create()->getRawValue());
$root = new PersistentHashTable();
self::addPointer($root, 'entries', new PersistentHashTable()->getRawValue());
self::addPointer($root, 'objects', new PersistentHashTable()->getRawValue());

return [new self($root), Core::addressOf($root->getRawValue())];
}
Expand All @@ -121,12 +121,12 @@ public function store(string $name, PersistedEntry $entry): void
$this->adjustShares($address, +1);
}

$members = PersistentHashTable::create();
$members = new PersistentHashTable();
foreach ($entry->members as $index => $address) {
self::addLong($members, $index, $address);
}

$meta = PersistentHashTable::create();
$meta = new PersistentHashTable();
self::addLong($meta, 'count', $entry->count());
self::addPointer($meta, 'members', $members->getRawValue());

Expand Down Expand Up @@ -272,12 +272,12 @@ public function objectCount(): int
*/
private function addObject(PersistedObject $object): void
{
$arrays = PersistentHashTable::create();
$arrays = new PersistentHashTable();
foreach ($object->arrays as $index => $array) {
self::addPointer($arrays, $index, $array);
}

$meta = PersistentHashTable::create();
$meta = new PersistentHashTable();
self::addPointer($meta, 'object', $object->object);
self::addPointer($meta, 'snapshot', $object->snapshot);
self::addInternedString($meta, 'class', $object->className);
Expand Down
Loading