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

Mongodb transport #430

Merged
merged 25 commits into from
May 3, 2018
Merged

Mongodb transport #430

merged 25 commits into from
May 3, 2018

Conversation

turboboy88
Copy link
Contributor

@turboboy88 turboboy88 commented Apr 26, 2018

Mongodb transport (ref #284)

@@ -44,6 +45,7 @@ services:
- RDKAFKA_PORT=9092
- PUBSUB_EMULATOR_HOST=http://google-pubsub:8085
- GCLOUD_PROJECT=mqdev
- MONGO_CONNECTION_STRING=mongodb://127.0.0.1/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to MONGO_DSN

*/
private $driverOptions;

public function __construct($uri = 'mongodb://127.0.0.1/', array $config = [], array $uriOptions = [], array $driverOptions = [])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constructor must accept one argument, an array.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t should have uri, uriOptions, driverOptions keys and other options

}

return $convertedMessage;
} catch (\Exception $e) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for catch

try {
$now = time();
$collection = $this->context->getCollection();
$message = $collection->findOne(['$or' => [['delayed_until' => ['$exists' => false]], ['delayed_until' => ['$lte' => $now]]]], ['sort' => ['priority' => -1]]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the line is too long, could you split it into several lines??

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!$message) {
return null;
}
$mongodbMessage = $message->getArrayCopy();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

if ($mongodbMessage['properties']) {
$message->setProperties(JSON::decode($mongodbMessage['properties']));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO there is no need to encode properties nor headers to json, we could store an array in mongodb.

*/
protected function convertMessage(array $mongodbMessage)
{
$message = $this->context->createMessage();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the createMessage method accept body, headers, and properties as arguments. pass them

/**
* @return array
*/
public function getConfig()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not make it public for now.

$collection = $this->context->getCollection();
$collection->insertOne($mongoMessage);
} catch (\Exception $e) {
throw new Exception('The transport fails to send the message due to some internal error.', null, $e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The transport has failed to send the message due to some internal error.

"require": {
"php": ">=5.6",
"queue-interop/queue-interop": "^0.6@dev|^1.0.0-alpha1",
"php-http/client-common": "^1.7@dev",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think we needed, please remove

@turboboy88 turboboy88 changed the title initial commit Mongodb transport Apr 26, 2018
composer.json Outdated
@@ -41,7 +42,8 @@
"symfony/console": "^2.8|^3|^4",
"friendsofphp/php-cs-fixer": "^2",
"empi89/php-amqp-stubs": "*@dev",
"php-http/client-common": "^1.7@dev"
"php-http/client-common": "^1.7@dev",
"mongodb/mongodb": "^1.3"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be remove as you required it in enqueue/mongodb

@@ -44,6 +45,7 @@ services:
- RDKAFKA_PORT=9092
- PUBSUB_EMULATOR_HOST=http://google-pubsub:8085
- GCLOUD_PROJECT=mqdev
- MONGO_DSN=mongodb://127.0.0.1/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be mongodb://mongo/

mongo:
image: mongo
ports:
- "27017:27017"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add an empty line after the service definition.

{
$now = time();
$collection = $this->context->getCollection();
$message = $collection->findOneAndDelete(['$or' => [['delayed_until' => ['$exists' => false]], ['delayed_until' => ['$lte' => $now]]]],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please split into several lines.

protected function convertMessage(array $mongodbMessage)
{
$message = $this->context->createMessage($mongodbMessage['body'], $mongodbMessage['properties'], $mongodbMessage['headers']);
$message->setId($mongodbMessage['_id']->__toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(string) $mongodbMessage['_id']


public function getCollection()
{
return $this->client->selectDatabase($this->config['dbname'])->selectCollection($this->config['collection_name']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<?php

return $this->client
    ->selectDatabase($this->config['dbname'])
    ->selectCollection($this->config['collection_name'])
;

$mongoMessage = [
'published_at' => $publishedAt,
'body' => $body,
'headers' => JSON::encode($message->getHeaders()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to json encode

"homepage": "https://enqueue.forma-pro.com/",
"license": "MIT",
"require": {
"php": ">=5.6",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^7.1

*/
private $config;

public function __construct($config = 'mongodb:')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add a docblcok with the information on possible configuration options

$this->markTestSkipped('The MONGO_DSN env is not available. Skip tests');
}
$params = ['uri' => $env];
$factory = new MongodbConnectionFactory($params);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<?php
$factory = new MongodbConnectionFactory(['uri' => $env]);

));
}

if ($parsedUrl['scheme'].':' === $dsn) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hardcode string mongodb:


if ($parsedUrl['scheme'].':' === $dsn) {
return [
'uri' => $parsedUrl['scheme'].'://127.0.0.1/',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

$config['uri'] = $parsedUrl['scheme'].'://'.$parsedUrl['host'];

if (isset($parsedUrl['path']) && '/' !== $parsedUrl['path']) {
$pathArr = explode('/', $parsedUrl['path']);
Copy link
Member

@makasim makasim Apr 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename the var to pathParts

];
}

$config['uri'] = $parsedUrl['scheme'].'://'.$parsedUrl['host'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not correct, the DSN might contain user, pasword, port, other options in it,

I think it would be good to store the orignal url as is is

}

if (isset($parsedUrl['query'])) {
parse_str($parsedUrl['query'], $queryParts);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use of undefined var, define $queryParts = null just before this line

parse_str($parsedUrl['query'], $queryParts);

//get enqueue attributes values
if (isset($queryParts['polling_interval']) && !empty($queryParts['polling_interval'])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no need for isset()

$factory = new Definition(MongodbConnectionFactory::class);
$factory->setArguments([$config]);
} else {
throw new \LogicException('Set "dsn" options when you want ot use Mongodb.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of this add required to ->scalarNode('dsn')

{
if (false == empty($config['dsn'])) {
$factory = new Definition(MongodbConnectionFactory::class);
$factory->setArguments([$config]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as far as I remember Definition takes an array of arguments as a second constructor argument.

throw new \LogicException('The config must be either an array of options, a DSN string or null');
}
$config = array_replace([
'uri' => 'mongodb://127.0.0.1/',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add dbname and a collection here as well

'headers' => $message->getHeaders(),
'properties' => $message->getProperties(),
'priority' => $message->getPriority(),
'queue' => $destination->getQueueName(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of getQueueName method is a bit misleading as we can send a message to the topic too.

Could you please add a neutral getName method to the destination and use it everywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added getName() alias for getQueueName() method. getQueueName() method should be implemented from PsrQueue interface.

$timeout /= 1000;
$startAt = microtime(true);

while (true) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's try capped collection plus tailable cursor approach.

https://gist.github.com/ASKozienko/cf45b09c68774ed83dea67b6d02d5846

InvalidDestinationException::assertDestinationInstanceOf($destination, MongodbDestination::class);
InvalidMessageException::assertMessageInstanceOf($message, MongodbMessage::class);

if (null !== $this->priority && 0 === $message->getPriority()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be if (null !== $this->priority && null === $message->getPriority()) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and set priority in the message to null by default (just unset).

@makasim makasim merged commit ccaaeb1 into php-enqueue:master May 3, 2018
ASKozienko pushed a commit that referenced this pull request Nov 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants