When using a connection as a field of a class that inherits from \Thread, I receive the following error on the $this->connection->channel() call:

Warning: fwrite() expects parameter 1 to be resource, integer given in /var/content-generator/PHP/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php on line 65

If I use local varaible, everything works fine, but I receive the error as soon as I move to field calls.

Failing Code:

public function run()
{
    $this->run = true;
    echo ' Thread-'.$this->ThreadId." including", "\n";
    require_once($this->loader);
    $this->connection = GetRabbitConnection();
    echo ' Thread-'.$this->ThreadId." opening channel", "\n";
    $this->channel = $this->connection->channel();
    echo ' Thread-'.$this->ThreadId." getting queue data", "\n";

    $RedisClient = GetRedisClient();

    $ScrapeExchange = $RedisClient->get(Scrape.":".Exchange);
    $ScrapeQueue = $RedisClient->get(Scrape.":".Queue);

    $this->OutboundExchange = $RedisClient->get(Extract.":".Exchange);
    $this->OutboundRoutingKey = $RedisClient->get(Extract.":".RoutingKey);

    $RedisClient = null;

    echo ' Thread-'.$this->ThreadId." consuming", "\n";

    $this->channel->basic_qos(0,1,false);
    $this->channel->basic_consume($ScrapeQueue, $ScrapeExchange, false, true, false, false, array($this, 'ProcessMessage'));

    while($this->run) {
        $this->channel->wait();
    }

    $this->channel->close();
}

Working Code:

public function run()
{
    echo ' Thread-'.$this->ThreadId." including", "\n";
    require_once($this->loader);
    echo ' Thread-'.$this->ThreadId." building connection", "\n";
    $connection = GetRabbitConnection();
    echo ' Thread-'.$this->ThreadId." opening channel", "\n";
    $channel = $connection->channel();

    echo ' Thread-'.$this->ThreadId." getting queue data", "\n";

    $RedisClient = GetRedisClient();

    $ScrapeExchange = $RedisClient->get(Scrape.":".Exchange);
    $ScrapeQueue = $RedisClient->get(Scrape.":".Queue);

    $this->OutboundExchange = $RedisClient->get(Extract.":".Exchange);
    $this->OutboundRoutingKey = $RedisClient->get(Extract.":".RoutingKey);

    $RedisClient = null;

    echo ' Thread-'.$this->ThreadId." consuming", "\n";

    $channel->basic_consume($ScrapeQueue, $ScrapeExchange, false, true, false, false, array($this, 'ProcessMessage'));

    while(true) {
        $channel->wait();
    }

    $channel->close();
    $connection->close();
}

What am I missing? Is there some piece of \Thread or pthreads that I am missing?

2

There are 2 best solutions below

0
On BEST ANSWER

Resources are not officially supported and those objects depend on resources.

You already found the solution: use method scope variables, you can also use static (class) scope variables.

0
On

PHP's PThreads has issues with the way it marshals object variables between instantiation and start. I ended up using an object instantiated in the run() function that held the object variables to do the work instead of trying to use the thread object itself, and have since had no issues.