vyuldashev / laravel-queue-rabbitmq

RabbitMQ driver for Laravel Queue. Supports Laravel Horizon.
MIT License
1.9k stars 376 forks source link

Exception: no connector for [rabbitmq] #32

Closed opb closed 9 years ago

opb commented 9 years ago

Hi there

Apologies for this issue, I'm sure it's something I'm doing wrong. I have installed and configured the package, and with my default driver set to sync (or anything other than rabbitmq), my app boots fine:

vagrant@homestead:~/repos/gk$ php artisan tinker
Psy Shell v0.5.2 (PHP 5.6.10-1+deb.sury.org~trusty+1 — cli) by Justin Hileman
>>> $q = app('queue');
=> Illuminate\Queue\QueueManager {#182}
>>> $con = $q->connection('rabbitmq');
=> FintechFab\LaravelQueueRabbitMQ\Queue\RabbitMQQueue {#779
     +"crypt": Illuminate\Encryption\McryptEncrypter {#191},
   }
>>>

But as soon as I set 'default' => 'rabbitmq', I get exceptions:

vagrant@homestead:~/repos/gk$ php artisan

  [InvalidArgumentException]
  No connector for [rabbitmq]

vagrant@homestead:~/repos/gk$

The only think I can think of is that the rabbitmq driver isn't available until the application has fully booted, but I'm not sure why that would be the case. The docs for this package suggest you can set QUEUE_DRIVER=rabbitmq in your .env file so I guess in theory I should be able to use it as my default driver. Any suggestions? (using L5.1)

vyuldashev commented 9 years ago

Hi there!

Did you add a connector to the "queue.php" configuration as described in README? Also, you need to add LaravelQueueRabbitMQServiceProvider to providers array in "app.php" configuration file?

If you did, please provide your code snippets so it will be more informative for me.

opb commented 9 years ago

Hi, thanks for the reply!

I did add those things. From the first code snippet above, you can see that I can manually resolve the rabbitmq connection, so the config is in place, along with the service provider. But just for confirmation...

Snippet from app.php:

...
        'Clockwork\Support\Laravel\ClockworkServiceProvider',
        'Illuminate\View\ViewServiceProvider',

        /*
         * Third Party Service Providers
         */
        'Zizaco\Entrust\EntrustServiceProvider',
        'Collective\Html\HtmlServiceProvider',
        'Laracasts\Utilities\JavaScript\JavascriptServiceProvider',
        'FintechFab\LaravelQueueRabbitMQ\LaravelQueueRabbitMQServiceProvider',

        /*
         * Application Service Providers...
         */
        'App\Providers\AppServiceProvider',
        'App\Providers\BusServiceProvider',
        'App\Providers\ConfigServiceProvider',
...

Config from queue.php:

    'connections' => [

        'sync' => [
            'driver' => 'sync',
        ],

        'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'expire' => 60,
        ],

        'beanstalkd' => [
            'driver' => 'beanstalkd',
            'host'   => 'localhost',
            'queue'  => 'default',
            'ttr'    => 60,
        ],

        'sqs' => [
            'driver' => 'sqs',
            'key'    => 'your-public-key',
            'secret' => 'your-secret-key',
            'queue'  => 'your-queue-url',
            'region' => 'us-east-1',
        ],

        'iron' => [
            'driver'  => 'iron',
            'host'    => 'mq-aws-us-east-1.iron.io',
            'token'   => 'your-token',
            'project' => 'your-project-id',
            'queue'   => 'your-queue-name',
            'encrypt' => true,
        ],

        'redis' => [
            'driver' => 'redis',
            'queue'  => 'gk',
            'expire' => 60,
        ],

        'rabbitmq' => [
            'driver'          => 'rabbitmq',

            'host'            => env('RABBITMQ_HOST', '127.0.0.1'),
            'port'            => env('RABBITMQ_PORT', 5672),

            'vhost'           => env('RABBITMQ_VHOST', '/'),
            'login'           => env('RABBITMQ_LOGIN', 'guest'),
            'password'        => env('RABBITMQ_PASSWORD', 'guest'),

            'queue'           => 'gk_main_queue', // name of the default queue,

            'queue_params'    => [
                'passive'     => false,
                'durable'     => true,
                'exclusive'   => false,
                'auto_delete' => false,
            ],

            'exchange_params' => [
                'type'        => 'direct', // more info at http://www.rabbitmq.com/tutorials/amqp-concepts.html
                'passive'     => false,
                'durable'     => true, // the exchange will survive server restarts
                'auto_delete' => false,
            ],

        ],

    ],

Please let me know if any other info would be helpful!

Thanks!

vyuldashev commented 9 years ago

Its really strange. Your code seems to be good. Silly question: did you do composer update? :)

opb commented 9 years ago

Yep, composer all updated! Will spend a bit more time digging through laravel source, so if that gives any clues.

vyuldashev commented 9 years ago

Can you provide a line from composer.json where you require our library, please?

opb commented 9 years ago
"require": {
    "league/csv": "^7.1",
    "predis/predis": "^1.0",
    "zizaco/entrust": "^1.4",
    "fzaninotto/faker": "^1.5",
    "league/fractal": "^0.12.0",
    "laravel/framework": "5.1.*",
    "laracasts/utilities": "~2.0",
    "cooperl/laravel-db2": "~2.0",
    "laravelcollective/html": "~5.0.0",
    "fintech-fab/laravel-queue-rabbitmq": "5.1",
    "mathiasverraes/money": "dev-master#b3f12b93d5b1bd58e45cc22d12c4b267e48d4cc4"
},
vyuldashev commented 9 years ago

That's really really strange. Try to create new laravel project and add just laravel connector and see if it works.

opb commented 9 years ago

not had a look at a fresh laravel install yet. But if I modify you're service provider with a dd line...

    public function register()
    {
        $this->app->booted(function () {
            dd('booted');
            /**
             * @var \Illuminate\Queue\QueueManager $manager
             */
            $manager = $this->app['queue'];
            $manager->addConnector('rabbitmq', function () {
                return new RabbitMQConnector;
            });
        });
    }

This still produced the "No connector" exception, and didn't get around to doing dd('booted'). This indicates to me that for some reason my queue is being resolved earlier than it should in the app boot process.

opb commented 9 years ago

Found it :)

The service provider is adding the connector inside $this->app->booted(), so the app boots before the connector is added. One of our other service providers from a third party (Clockwork) was evidently doing something to cause the queue to be resolved before the app had booted, and consequently before our connector had been added.

I'm not sure whether Clockwork should be doing something differently, or whether perhaps this package is adding the connector in too late? What would the effect be of removing the the $this->app->booted() and just doing it as a normal register() method? or perhaps move to boot()?

Thanks

vyuldashev commented 9 years ago

I just merged one pull request. It moves loading connector to "boot". You can try and I think it will work for you.

opb commented 9 years ago

Thanks. I've tried dev-master and that works, but I still had to get rid of Clockwork to get it to work. Not an issue from my perspective, as we were going to remove it anyway. I think Clockwork must be doing something dodgy!

Thanks for your help with this, I'll close this now.

vyuldashev commented 9 years ago

You are welcome.

D-Skywalker commented 6 years ago

Hi @opb , seems that you found a solution, but is not to much clear for me where are that things on code: "$this->app->booted()", "boot()", "register()". Can you clear this, please?

chillichicken commented 4 years ago

Adding the provider to the config/app.php is not part of the readme. After finding this issue I could configure it properly and things worked for Laravel 5.8.

'providers' => [ ...
    \VladimirYuldashev\LaravelQueueRabbitMQ\LaravelQueueRabbitMQServiceProvider::class, 
]
vyuldashev commented 4 years ago

@chillichicken Package uses Laravel Auto-Discovery. There is no need to manually register provider. Did you disable it explicitly?

chillichicken commented 4 years ago

@vyuldashev we turned off the laravel specific scripts that composer shall run. In this case "post-autoload-dump". We didn't want any magic to happen without us explicitly turning it on.

I made a pull request to reflect that scenario.