-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
PHPORM-56 Replace Collection proxy class with Driver monitoring #3137
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,7 @@ | |
"illuminate/database": "^11", | ||
"illuminate/events": "^11", | ||
"illuminate/support": "^11", | ||
"mongodb/mongodb": "^1.15" | ||
"mongodb/mongodb": "^1.18" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Requires mongodb/mongo-php-library#1195 |
||
}, | ||
"require-dev": { | ||
"mongodb/builder": "^0.2", | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
namespace MongoDB\Laravel; | ||
|
||
use MongoDB\BSON\Document; | ||
use MongoDB\Driver\Monitoring\CommandFailedEvent; | ||
use MongoDB\Driver\Monitoring\CommandStartedEvent; | ||
use MongoDB\Driver\Monitoring\CommandSubscriber as CommandSubscriberInterface; | ||
use MongoDB\Driver\Monitoring\CommandSucceededEvent; | ||
|
||
use function get_object_vars; | ||
use function in_array; | ||
|
||
/** @internal */ | ||
final class CommandSubscriber implements CommandSubscriberInterface | ||
{ | ||
/** @var array<string, CommandStartedEvent> */ | ||
private array $commands = []; | ||
|
||
public function __construct(private Connection $connection) | ||
{ | ||
} | ||
|
||
public function commandStarted(CommandStartedEvent $event) | ||
{ | ||
$this->commands[$event->getOperationId()] = $event; | ||
} | ||
|
||
public function commandFailed(CommandFailedEvent $event) | ||
{ | ||
$this->logQuery($event); | ||
} | ||
|
||
public function commandSucceeded(CommandSucceededEvent $event) | ||
{ | ||
$this->logQuery($event); | ||
} | ||
|
||
private function logQuery(CommandSucceededEvent|CommandFailedEvent $event): void | ||
{ | ||
$startedEvent = $this->commands[$event->getOperationId()]; | ||
unset($this->commands[$event->getOperationId()]); | ||
|
||
$command = []; | ||
foreach (get_object_vars($startedEvent->getCommand()) as $key => $value) { | ||
if ($key[0] !== '$' && ! in_array($key, ['lsid', 'txnNumber'])) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I never checked the performance of this, but why not use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The array key is never empty, and I need to check only 1 char. This skips 1 method call. public function benchStrStartsWith()
{
$key = '$db';
return str_starts_with($key, '$');
}
public function benchStrictCmp()
{
$key = '$db';
return $key[0] === '$';
}
|
||
$command[$key] = $value; | ||
} | ||
} | ||
|
||
$this->connection->logQuery(Document::fromPHP($command)->toCanonicalExtendedJSON(), [], $event->getDurationMicros()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
use Illuminate\Database\Connection as BaseConnection; | ||
use InvalidArgumentException; | ||
use MongoDB\Client; | ||
use MongoDB\Collection; | ||
use MongoDB\Database; | ||
use MongoDB\Driver\Exception\AuthenticationException; | ||
use MongoDB\Driver\Exception\ConnectionException; | ||
|
@@ -47,6 +48,8 @@ class Connection extends BaseConnection | |
*/ | ||
protected $connection; | ||
|
||
private ?CommandSubscriber $commandSubscriber; | ||
|
||
/** | ||
* Create a new database connection instance. | ||
*/ | ||
|
@@ -62,6 +65,8 @@ public function __construct(array $config) | |
|
||
// Create the connection | ||
$this->connection = $this->createConnection($dsn, $config, $options); | ||
$this->commandSubscriber = new CommandSubscriber($this); | ||
$this->connection->addSubscriber($this->commandSubscriber); | ||
|
||
// Select database | ||
$this->db = $this->connection->selectDatabase($this->getDefaultDatabaseName($dsn, $config)); | ||
|
@@ -97,9 +102,9 @@ public function table($table, $as = null) | |
* | ||
* @return Collection | ||
*/ | ||
public function getCollection($name) | ||
public function getCollection($name): Collection | ||
{ | ||
return new Collection($this, $this->db->selectCollection($this->tablePrefix . $name)); | ||
return $this->db->selectCollection($this->tablePrefix . $name); | ||
} | ||
|
||
/** @inheritdoc */ | ||
|
@@ -198,6 +203,8 @@ public function ping(): void | |
/** @inheritdoc */ | ||
public function disconnect() | ||
{ | ||
$this->connection?->removeSubscriber($this->commandSubscriber); | ||
$this->commandSubscriber = null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unregistering the subscriber seems correct, but I'm more generally curious how the I assume Laravel never uses the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm just making sure that the objects are deleted without requiring a garbage collector cycle. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand why you made the additions to this method. It was a more general question about what the purpose of |
||
$this->connection = null; | ||
} | ||
|
||
|
@@ -264,12 +271,6 @@ protected function getDsn(array $config): string | |
throw new InvalidArgumentException('MongoDB connection configuration requires "dsn" or "host" key.'); | ||
} | ||
|
||
/** @inheritdoc */ | ||
public function getElapsedTime($start) | ||
{ | ||
return parent::getElapsedTime($start); | ||
} | ||
|
||
/** @inheritdoc */ | ||
public function getDriverName() | ||
{ | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might apply to other BC breaks as well, but do we want to leverage deprecations in 1.x to announce the break?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can mark the class as deprecated in 1.x. Unless we add an option to switch the monitoring feature from the proxy class to the monitoring events, there will be no way to disable the deprecation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it - not sure we need to do this, just wanted to check 👍