BraveSirRobin/amqphp — Issue #9: Bug when connecting to multiple vhosts on the same server using persistent connection
Author: tcz
Created: 2012-02-21 18:30:16+00:00
State: open

Hi,

We have found the following error when implementing support for you library.

```
Uncaught exception 'Exception' with message 'Failed to reload amqp connection cache during wakeup' in /mnt/user/libs/external/amqphp/src/amqphp/persistent/PConnection.php:318
Stack trace:
#0 /mnt/user/libs/external/amqphp/src/amqphp/persistent/PConnection.php(131): amqphp\persistent\PConnection->wakeup()
#1 /mnt/user/web/engine/MQ.class.php(241): amqphp\persistent\PConnection->connect()
```

### How to reproduce? ###

- Use persistent connection when connecting to the message queue broker

```
new \amqphp\persistent\PConnection( array(
'socketParams' => array(
'url' => 'tcp://' . $connection['host'] . ':' . $connection['port'],
),
'username' => $connection['user'],
'userpass' => $connection['password'],
'vhost' => $connection['vhost'],
) );

self::$connection_pool[$key]->pHelperImpl = '\\amqphp\\persistent\\APCPersistenceHelper';
self::$connection_pool[$key]->connect();
```

- Connect to vhost1 on server1
- After the connection is set up for vhost1, connect to vhost2 on server1 (the same server)

### The cause ###

We have seen that the problem is caused by different caching patterns when persisting inter-request data:

- when creating persistent sockets (with stream_socket_client using STREAM_CLIENT_PERSISTENT flag) the OS persists the connection per url (protocol+hostname+port)
- when persisting connection info for sockets (channels, other amqp-related connection info) the library per url (protocol+hostname+port) AND vhost

When connecting to the 2ns vhost, the library first creates the socket, which has the same URL so it will be reused. This means that its internal pointer (`ftell`) is bigger than 0, so the library supposes that it's a reused connection (correct) and tries to load the data for it. The problem is that the cache key for the connection data is different (the vhost has changed), so it can't find it.

We are happy to help in fixing this by creating a pull request, I just wanted to consult about solutions to see if there is anything you prefer.

I was thinking to change to cache key (`getCK`) of the socket excluding the vhost. This, however, causes problems in other parts of the library (`Stream socket connection created a new wrapper object for an existing persistent connection on URL ...`). Alternatively we can generate the cache key for the persistence helper outside the socket class, or inside with a new method.

What do you think?