phasync
Coordination across workers / SealedObject

Class

SealedObject

A decoded JSON object that nobody can change: what a subscriber of Swerve::subscribe gets for a published object.

Introduction#

The message is decoded once per worker and shared by all its subscribers, which are coroutines; a plain stdClass would let one attach a property, or change one, for all the others to see. Nested objects are SealedObjects too.

Reading a missing property triggers a warning and gives null. Assigning or unsetting throws a LogicException. json_encode() gives the object back as it was published.

Class synopsis#

final class SealedObject implements \IteratorAggregate, \JsonSerializable, \Traversable {
    /* Methods */
    public SealedObject::__construct(stdClass $inner)
    public static SealedObject::seal(mixed $value): mixed
    public SealedObject::__get(string $name): mixed
    public SealedObject::__isset(string $name): bool
    public SealedObject::__set(string $name, mixed $value): never
    public SealedObject::__unset(string $name): never
    public SealedObject::getIterator(): Generator
    public SealedObject::jsonSerialize(): stdClass
}

Methods#

MethodDescription
__constructWrap a decoded object; SealedObject::seal does it for a whole decoded value.
sealWhat json_decode() (without assoc) returned, with its objects replaced by SealedObjects; the objects inside one are wrapped when first read.
__getThe property $name; an object in it is a SealedObject.
__issetWhether the property exists and is not null.
__setAlways throws: the message is shared by every subscriber.
__unsetAlways throws: the message is shared by every subscriber.
getIteratorThe properties by name; objects in them are SealedObjects.
jsonSerializeA copy of the object as it was published, for json_encode().

Examples#

Example 1A read-only message
use Swerve\Swerve;

phasync::run(function () {
    $subscription = Swerve::subscribe('game');
    Swerve::publish('game', ['type' => 'move', 'player' => ['id' => 7, 'name' => 'ann'], 'to' => [3, 4]]);

    foreach ($subscription as $message) {
        echo $message->type, ' by ', $message->player->name, "\n";   // nested objects are sealed too
        var_dump(isset($message->end));

        foreach ($message as $name => $value) {
            echo "$name: ", get_debug_type($value), "\n";
        }

        try {
            $message->type = 'cheat';            // shared by every subscriber: refused
        } catch (LogicException $e) {
            echo get_class($e), "\n";
        }

        echo json_encode($message), "\n";       // as it was published
        break;
    }
});
Output
move by ann
bool(false)
type: string
player: Swerve\Util\SealedObject
to: array
LogicException
{"type":"move","player":{"id":7,"name":"ann"},"to":[3,4]}
Example 2
foreach (Swerve::subscribe('game') as $message) {
    if ($message instanceof SealedObject && isset($message->end)) {   // a property
        break;
    }
    foreach ($message as $name => $value) { ... }                     // iterable
}

See also#

  • Swerve::publishSend a message to every subscriber of $topic, in every worker process of this swerve, this one included.
  • Swerve::subscribeReceive what is published to $topic from now on.