Hazelcast PHP Client Part I

  • 7th of April Hazelcast asks on Twitter which language should be next in the row for the client. Of course I can’t shut my mouth and voted for PHP. A minute later a question if I’d like to implement it. And how could I say no when all my 5 followers can see that?
  • 10th of April Hello world from the PHP client, still everything is hacked together in a simple script
  • 13th of April I started with the architecture of my implementation, wrote some stubs

PHP and datatypes is like building a watch with a sledgehammer

While the cool kids talk about double precision 64-bit floating point or 32-bit unsigned integers, PHP’s only word is “numberish”…

$x = "234g";
echo ++$x . PHP_EOL;
echo $x += 5 . PHP_EOL;

234h? Seriously? So this implementation will be quite a challenge.

Enough complaining, let’s try something cool

I have to use pack() to create a binary string with all the different datatypes. I started implementing a message class, which holds the variables to build the header, the child classes, e.g. Authentication should only store the values needed for authentication.

As I’m really lazy, I want to automate the string building as far as possible. So I will have a Serializer class, which can build the string for every <? extends Message> by itself.

By using an annotation and reflection, I can query the docblocks of the private properties of the class.

That’s how my class looks like:

class AuthenticationRequest extends Message
{
    /**
     * @var string
     * @type string
     */
    private $username;

    /**
     * @var string
     * @type string
     */
    private $password;

    /**
     * @var string
     * @type string
     */
    private $uuid;

    /**
     * @var string
     * @type string
     */
    private $ownerUuid;

    /**
     * @var bool
     * @type boolean
     */
    private $isOwnerConnection;

    /**
     * @var string
     * @type string
     */
    private $clientType;

    /**
     * @var int
     * @type uint8
     */
    private $serializationVersion;
}

And this script will extract the datatypes:

$refl = new ReflectionClass('Hazelcast\Message\Generic\AuthenticationRequest');
$props = $refl->getProperties(ReflectionProperty::IS_PRIVATE);

$map = [];

/** @var ReflectionProperty $prop */
foreach ($props as $prop) {
    $docBlock = $prop->getDocComment();
    $matches = [];

    preg_match('/@type\s+(\w+)/m', $docBlock, $matches);
    if (!empty($matches[1])) {
        $map[$prop->getName()] = $matches[1];
    }
}

print_r($map);

Here the result:

Array
(
    [username] => string
    [password] => string
    [uuid] => string
    [ownerUuid] => string
    [isOwnerConnection] => boolean
    [clientType] => string
    [serializationVersion] => uint8
)

Usually these values don’t change, so they should be cached. A Memcached / Redis / File / Whatever adapter can be configured in the client config.

I hope to publish some working code as soon as possible, maybe I find some fellow devs who want to join me or report bugs…

comments powered by Disqus