Skip to content

Commit a8a0858

Browse files
committed
Merge pull request #1092
2 parents f28de00 + d4f8583 commit a8a0858

File tree

8 files changed

+149
-15
lines changed

8 files changed

+149
-15
lines changed

src/MongoDB/Manager.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ static PHP_METHOD(Manager, executeCommand)
408408
}
409409

410410
/* If the Manager was created in a different process, reset the client so
411-
* that cursors created by this process can be differentiated. */
411+
* that cursors created by this process can be differentiated and its
412+
* session pool is cleared. */
412413
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
413414

414415
phongo_execute_command(intern->client, PHONGO_COMMAND_RAW, db, command, options, server_id, return_value, return_value_used TSRMLS_CC);
@@ -455,7 +456,8 @@ static PHP_METHOD(Manager, executeReadCommand)
455456
}
456457

457458
/* If the Manager was created in a different process, reset the client so
458-
* that cursors created by this process can be differentiated. */
459+
* that cursors created by this process can be differentiated and its
460+
* session pool is cleared. */
459461
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
460462

461463
phongo_execute_command(intern->client, PHONGO_COMMAND_READ, db, command, options, server_id, return_value, return_value_used TSRMLS_CC);
@@ -491,7 +493,8 @@ static PHP_METHOD(Manager, executeWriteCommand)
491493
}
492494

493495
/* If the Manager was created in a different process, reset the client so
494-
* that cursors created by this process can be differentiated. */
496+
* that cursors created by this process can be differentiated and its
497+
* session pool is cleared. */
495498
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
496499

497500
phongo_execute_command(intern->client, PHONGO_COMMAND_WRITE, db, command, options, server_id, return_value, return_value_used TSRMLS_CC);
@@ -527,7 +530,8 @@ static PHP_METHOD(Manager, executeReadWriteCommand)
527530
}
528531

529532
/* If the Manager was created in a different process, reset the client so
530-
* that cursors created by this process can be differentiated. */
533+
* that cursors created by this process can be differentiated and its
534+
* session pool is cleared. */
531535
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
532536

533537
phongo_execute_command(intern->client, PHONGO_COMMAND_READ_WRITE, db, command, options, server_id, return_value, return_value_used TSRMLS_CC);
@@ -572,7 +576,8 @@ static PHP_METHOD(Manager, executeQuery)
572576
}
573577

574578
/* If the Manager was created in a different process, reset the client so
575-
* that cursors created by this process can be differentiated. */
579+
* that cursors created by this process can be differentiated and its
580+
* session pool is cleared. */
576581
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
577582

578583
phongo_execute_query(intern->client, namespace, query, options, server_id, return_value, return_value_used TSRMLS_CC);
@@ -617,6 +622,10 @@ static PHP_METHOD(Manager, executeBulkWrite)
617622
goto cleanup;
618623
}
619624

625+
/* If the Server was created in a different process, reset the client so
626+
* that its session pool is cleared. */
627+
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
628+
620629
phongo_execute_bulk_write(intern->client, namespace, bulk, options, server_id, return_value, return_value_used TSRMLS_CC);
621630

622631
cleanup:

src/MongoDB/Server.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ static PHP_METHOD(Server, executeCommand)
4848
options = php_phongo_prep_legacy_option(options, "readPreference", &free_options TSRMLS_CC);
4949

5050
/* If the Server was created in a different process, reset the client so
51-
* that cursors created by this process can be differentiated. */
51+
* that cursors created by this process can be differentiated and its
52+
* session pool is cleared. */
5253
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
5354

5455
phongo_execute_command(intern->client, PHONGO_COMMAND_RAW, db, command, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
@@ -76,7 +77,8 @@ static PHP_METHOD(Server, executeReadCommand)
7677
}
7778

7879
/* If the Server was created in a different process, reset the client so
79-
* that cursors created by this process can be differentiated. */
80+
* that cursors created by this process can be differentiated and its
81+
* session pool is cleared. */
8082
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
8183

8284
phongo_execute_command(intern->client, PHONGO_COMMAND_READ, db, command, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
@@ -100,7 +102,8 @@ static PHP_METHOD(Server, executeWriteCommand)
100102
}
101103

102104
/* If the Server was created in a different process, reset the client so
103-
* that cursors created by this process can be differentiated. */
105+
* that cursors created by this process can be differentiated. and its
106+
* session pool is cleared. */
104107
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
105108

106109
phongo_execute_command(intern->client, PHONGO_COMMAND_WRITE, db, command, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
@@ -124,7 +127,8 @@ static PHP_METHOD(Server, executeReadWriteCommand)
124127
}
125128

126129
/* If the Server was created in a different process, reset the client so
127-
* that cursors created by this process can be differentiated. */
130+
* that cursors created by this process can be differentiated and its
131+
* session pool is cleared. */
128132
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
129133

130134
phongo_execute_command(intern->client, PHONGO_COMMAND_READ_WRITE, db, command, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
@@ -151,7 +155,8 @@ static PHP_METHOD(Server, executeQuery)
151155
options = php_phongo_prep_legacy_option(options, "readPreference", &free_options TSRMLS_CC);
152156

153157
/* If the Server was created in a different process, reset the client so
154-
* that cursors created by this process can be differentiated. */
158+
* that cursors created by this process can be differentiated and its
159+
* session pool is cleared. */
155160
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
156161

157162
phongo_execute_query(intern->client, namespace, query, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
@@ -185,6 +190,10 @@ static PHP_METHOD(Server, executeBulkWrite)
185190

186191
options = php_phongo_prep_legacy_option(options, "writeConcern", &free_options TSRMLS_CC);
187192

193+
/* If the Server was created in a different process, reset the client so
194+
* that its session pool is cleared. */
195+
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
196+
188197
phongo_execute_bulk_write(intern->client, namespace, bulk, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
189198

190199
if (free_options) {

tests/cursor/bug1274-001.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ MongoDB\Driver\Monitoring\addSubscriber(new CommandLogger);
5454
$query = new MongoDB\Driver\Query([], ['batchSize' => 2]);
5555
$cursor = $manager->executeQuery(NS, $query);
5656

57-
$parentPid = getmypid();
5857
$childPid = pcntl_fork();
5958

6059
if ($childPid === 0) {

tests/cursor/bug1274-002.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ MongoDB\Driver\Monitoring\addSubscriber($subscriber);
5757
$query = new MongoDB\Driver\Query([], ['batchSize' => 2]);
5858
$cursor = $manager->executeQuery(NS, $query);
5959

60-
$parentPid = getmypid();
6160
$childPid = pcntl_fork();
6261

6362
if ($childPid === 0) {

tests/cursor/bug1274-003.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ MongoDB\Driver\Monitoring\addSubscriber(new CommandLogger);
5454
$query = new MongoDB\Driver\Query([], ['batchSize' => 2]);
5555
$cursor = $manager->executeQuery(NS, $query);
5656

57-
$parentPid = getmypid();
5857
$childPid = pcntl_fork();
5958

6059
if ($childPid === 0) {

tests/session/bug1274-001.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ $bulk->insert(['x' => 2]);
2828
$result = $manager->executeBulkWrite(NS, $bulk, ['session' => $session]);
2929
printf("Parent inserted %d documents\n", $result->getInsertedCount());
3030

31-
$parentPid = getmypid();
3231
$childPid = pcntl_fork();
3332

3433
if ($childPid === 0) {

tests/session/bug1274-002.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ MongoDB\Driver\Monitoring\addSubscriber(new CommandLogger);
5757
$query = new MongoDB\Driver\Query([], ['batchSize' => 2]);
5858
$cursor = $manager->executeQuery(NS, $query, ['session' => $session]);
5959

60-
$parentPid = getmypid();
6160
$childPid = pcntl_fork();
6261

6362
if ($childPid === 0) {

tests/session/bug1274-003.phpt

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
--TEST--
2+
PHPC-1274: Implicit sessions are not reused from parent process
3+
--SKIPIF--
4+
<?php if (!function_exists('pcntl_fork')) { die('skip pcntl_fork() not available'); } ?>
5+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
6+
<?php skip_if_not_libmongoc_crypto(); ?>
7+
<?php skip_if_not_replica_set(); ?>
8+
<?php skip_if_server_version('<', '3.6'); ?>
9+
<?php skip_if_not_clean(); ?>
10+
<?php skip_if_not_clean(DATABASE_NAME, COLLECTION_NAME . '_sessions'); ?>
11+
--FILE--
12+
<?php
13+
require_once __DIR__ . "/../utils/basic.inc";
14+
15+
class SessionLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
16+
{
17+
private $lsids = [];
18+
private $logNamespace;
19+
private $manager;
20+
private $pid;
21+
22+
public function __construct(MongoDB\Driver\Manager $manager, $logNamespace)
23+
{
24+
$this->logNamespace = $logNamespace;
25+
$this->manager = $manager;
26+
$this->pid = getmypid();
27+
}
28+
29+
public function executeAndLogSessions(callable $callable)
30+
{
31+
$this->lsids = [];
32+
33+
MongoDB\Driver\Monitoring\addSubscriber($this);
34+
call_user_func($callable);
35+
MongoDB\Driver\Monitoring\removeSubscriber($this);
36+
37+
if (empty($this->lsids)) {
38+
return;
39+
}
40+
41+
$bulk = new MongoDB\Driver\BulkWrite();
42+
43+
foreach ($this->lsids as $lsid) {
44+
$bulk->update(['lsid' => $lsid], ['$inc' => ['count' => 1]], ['upsert' => true]);
45+
}
46+
47+
$this->manager->executeBulkWrite($this->logNamespace, $bulk);
48+
}
49+
50+
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
51+
{
52+
$command = $event->getCommand();
53+
54+
if (isset($command->lsid)) {
55+
$this->lsids[] = $command->lsid;
56+
}
57+
58+
$commandName = $event->getCommandName();
59+
$process = $this->pid === getmypid() ? 'Parent' : 'Child';
60+
61+
printf("%s executes %s\n", $process, $commandName);
62+
}
63+
64+
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
65+
{
66+
}
67+
68+
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
69+
{
70+
}
71+
}
72+
73+
$manager = new MongoDB\Driver\Manager(URI);
74+
$logNamespace = NS . '_sessions';
75+
$sessionLogger = new SessionLogger($manager, $logNamespace);
76+
77+
/* This test uses executeBulkWrite() as it's the only execute method that does
78+
* not create a cursor. The original patch for PHPC-1274 covered those methods
79+
* that return a cursor but omitted executeBulkWrite(). */
80+
$sessionLogger->executeAndLogSessions(function() use ($manager) {
81+
$bulk = new MongoDB\Driver\BulkWrite();
82+
$bulk->insert(['x' => 1]);
83+
$manager->executeBulkWrite(NS, $bulk);
84+
});
85+
86+
$childPid = pcntl_fork();
87+
88+
if ($childPid === 0) {
89+
$sessionLogger->executeAndLogSessions(function() use ($manager) {
90+
$bulk = new MongoDB\Driver\BulkWrite();
91+
$bulk->insert(['x' => 2]);
92+
$manager->executeBulkWrite(NS, $bulk);
93+
});
94+
95+
echo "Child exits\n";
96+
exit;
97+
}
98+
99+
if ($childPid > 0) {
100+
$waitPid = pcntl_waitpid($childPid, $status);
101+
102+
if ($waitPid === $childPid) {
103+
echo "Parent waited for child to exit\n";
104+
}
105+
106+
$query = new MongoDB\Driver\Query([]);
107+
$cursor = $manager->executeQuery($logNamespace, $query);
108+
109+
printf("Sessions used: %d\n", iterator_count($cursor));
110+
}
111+
112+
?>
113+
===DONE===
114+
<?php exit(0); ?>
115+
--EXPECT--
116+
Parent executes insert
117+
Child executes insert
118+
Child exits
119+
Parent waited for child to exit
120+
Sessions used: 2
121+
===DONE===

0 commit comments

Comments
 (0)