Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persistent connection with TLS closed in forked process #2370

Open
2 tasks done
adri opened this issue Aug 7, 2023 · 1 comment
Open
2 tasks done

Persistent connection with TLS closed in forked process #2370

adri opened this issue Aug 7, 2023 · 1 comment
Assignees

Comments

@adri
Copy link

adri commented Aug 7, 2023

Expected behaviour

When using pconnect in a CLI context (background worker, using Resque which uses process forking) connections are properly passed to the child and reused in the parent.

Actual behaviour

This works great when not using TLS, however when using TLS the child closes the connection when it exits, causing the parent to create a new connection.

I could not find anything in phpredis related to this, so it might as well be in PHP itself. Is there a way to avoid closing the connection when the child exits?

I'm seeing this behaviour on

  • OS: Ubuntu
  • Redis: 7
  • PHP: 8.2
  • phpredis: redis-5.3.7

Steps to reproduce, backtrace or example script

Here an example script connecting to a local Redis server, configured with a certificate.

<?php

$persistentId = 'redis';
$streamContext = [
    'stream' => [
        'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true,
        'so_reuseport' => true,
    ],
];

$redisParent = new Redis();
$redisParent->pconnect('127.0.0.1', 60305, 3, $persistentId, 0, 3, $streamContext);
$redisParent->echo('from parent before fork');
// monitor: 127.0.0.1:<parentId> ECHO from parent before fork

// Fork a child process
$pid = pcntl_fork();

if ($pid === 0) {
    // This is the child
    $redisParent->echo('from child');
    // monitor: 127.0.0.1:<parentId> ECHO from child


    sleep(1);
    exit(0);
}

// This is the parent, wait for the child to finish
pcntl_wait($status);
$exitStatus = pcntl_wexitstatus($status);
if ($exitStatus !== 0) {
    echo "Child exited with status {$exitStatus}\n";
}

$redisParent->echo('from parent after fork');
// monitor: 127.0.0.1:<newId> ECHO from parent after fork
// ! Here we have a new connection, because the child process closed the connection

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch
@michael-grunder michael-grunder self-assigned this Aug 9, 2023
@RemkoNolten
Copy link

We 'fixed' a similar issue by calling $redisParent->close() just before the fork (we used a normal connection, not an persistent/pooled one): This makes sure that both parent & child will use their own (new) connection so they don't share the same TLS state. Not ideal, but in the context of a job worker not a real issue either.

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

No branches or pull requests

3 participants