Skip to content
This repository has been archived by the owner on Dec 16, 2019. It is now read-only.

Serialization of 'Closure' is not allowed in Worker #942

Open
landall opened this issue Jun 19, 2019 · 5 comments
Open

Serialization of 'Closure' is not allowed in Worker #942

landall opened this issue Jun 19, 2019 · 5 comments

Comments

@landall
Copy link

landall commented Jun 19, 2019

Environment

PHP 7.2.19 (cli) (built: May 29 2019 14:17:01) ( ZTS MSVC15 (Visual C++ 2017) x86 )
Pthread 3.2.0
Win10 x64

Summary

When I assign a object with a member of GuzzleHttp\Client to a field of my worker class, I raise an exception saying Serialization of 'Closure' is not allowed.

Reproducing Code

class TaskQueueWorker extends \Worker
{
public function __construct($client)
{
$this->client = $client;
}

public static $client;

}

$client is an object of a class with a sub object of GuzzleHttp\Client.

Its package information:
"name": "guzzlehttp/guzzle",
"version": "6.3.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"shasum": ""
},
"require": {
"guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.4",
"php": ">=5.5"
},

Expected Output

Actual Output

raise a fatal error.

@landall
Copy link
Author

landall commented Jun 19, 2019

also happened in CentOS 7 with remi-php7.2 rpm packages.
PHP 7.2.19 (cli) (built: May 29 2019 11:10:45) ( ZTS )

Installed Packages
php.x86_64 7.2.19-2.el7.remi @remi-php72
php-cli.x86_64 7.2.19-2.el7.remi @remi-php72
php-common.x86_64 7.2.19-2.el7.remi @remi-php72
php-json.x86_64 7.2.19-2.el7.remi @remi-php72
php-pecl-pthreads.x86_64 3.2.0-1.el7.remi.7.2 @remi-php72

@AlexSayHello
Copy link

The properties of the instances that inherit from Threaded are serialized so that the information they host can be passed between contexts.

When you pass your http client to your worker, the engine tries to serialize the instance of GuzzleHttp\Client and at some point you will find an anonymous function or closure. Anonymous functions cannot be serialized due to their nature. It's like trying to do:

$result = serialize(function () {});

That will throw a fatal error: Serialization of 'Closure' is not allowed

If you want to create an instance that is shared by all the threads of your worker you can do the following.

<?php

use Worker;

class TaskQueueWorker extends Worker
{
    protected static $client;

    public function run()
    {
        // It is necessary to call the autoload composer file, since the context
        // of the worker is new and does not have the spl autoload function
        // for psr-4
        require 'vendor/autoload.php';
    }

    public function getClient()
    {
        if (self::$client) {
            return self::$client;
        }

        self::$client = new GuzzleHttp\Client();

        return self::$client;
    }
}

You can learn more about how to share objects in the examples:
https://github.com/krakjoe/pthreads/blob/master/examples/MySQLi.php

@dktapps
Copy link
Contributor

dktapps commented Aug 6, 2019

@AlexSayHello That isn't sharing. Statics are thread-local, not shared.

@AlexSayHello
Copy link

@dktapps When I refer to "shared" I mean that the instance is available from the thread through $this->worker->getClient(). Maybe I have not used the most appropriate concept to describe it. I wasn't referring to sharing data.

@landall
Copy link
Author

landall commented Aug 7, 2019

Does this means I must create the instance as a thread-local object if it uses an anonymous function or closure? I cannot control the code from others' package.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants