Skip to content

access to HybridRelations Model from Queued event Listeners #1675

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

Closed
irajtaghlidi opened this issue Dec 9, 2018 · 2 comments
Closed

access to HybridRelations Model from Queued event Listeners #1675

irajtaghlidi opened this issue Dec 9, 2018 · 2 comments
Labels

Comments

@irajtaghlidi
Copy link

irajtaghlidi commented Dec 9, 2018

Problem scenario:

Order Model is in mysql with a belongsTo Relationship.

use Illuminate\Database\Eloquent\Model;

class DeviceOrder extends Model
{
    protected $connection = 'mysql';

    protected $table = 'device_orders';

    public function device()
    {
        return $this->belongsTo('App\Models\Device', 'device_id');
    }
}

Device Model is MongoDB Model (with HybridRelations with Order Model)


use Jenssegers\Mongodb\Eloquent\Model;
use Jenssegers\Mongodb\Eloquent\HybridRelations;

class Device extends Model
{
    use HybridRelations;
    ...
}

I have access to Device model via Eloquent Relationships.
for example :

$order = Order::find(1);
$device = $order->device;

when I create an Event and pass Order Model to it. I have access to Device model via relationships in Event Listener when Event Listener work without Queue.

use App\Events\NewOrderSubmitted;

class ProcessOrder  # <-----------
{
    public function handle(NewOrderSubmitted $event)
    {
        $order = $event->order;
        $device = $order->device;  # <-----------
        Log::info('Device Info: ' . $device);
    }
}

But when I implement ShouldQueue to Listener Class, Queue visible in Horizon but it will timeout after about 300 seconds.

use App\Events\NewOrderSubmitted;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class ProcessOrder implements ShouldQueue  # <-------
{
    public function handle(NewOrderSubmitted $event)
    {
        $order = $event->order;
        $device = $order->device;  # <-------
        Log::info('Device Info: ' . $device);
    }
}

Although it work in Queue mode without Eloquent Relationships and just with ::find() method.

use App\Events\NewOrderSubmitted;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class ProcessOrder implements ShouldQueue  # <-------
{
    public function handle(NewOrderSubmitted $event)
    {
        $order = $event->order;
        $device = Device::find($order->id);  # <-------
        Log::info('Device Info: ' . $device);
    }
}

Timeout Error:

MongoDB\Driver\Exception\ConnectionTimeoutException: Failed to send "find" command with database "shopping": Failed to read 4 bytes: socket error or timeout in /Users/iraj/projects/project/vendor/mongodb/mongodb/src/Operation/Find.php:299
Stack trace:
#0 /Users/iraj/projects/project/vendor/mongodb/mongodb/src/Operation/Find.php(299): MongoDB\Driver\Server->executeQuery('shopping.device...', Object(MongoDB\Driver\Query), Array)
#1 /Users/iraj/projects/project/vendor/mongodb/mongodb/src/Collection.php(624): MongoDB\Operation\Find->execute(Object(MongoDB\Driver\Server))
#2 [internal function]: MongoDB\Collection->find(Array, Array)
#3 /Users/iraj/projects/project/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Collection.php(45): call_user_func_array(Array, Array)
#4 /Users/iraj/projects/project/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Query/Builder.php(394): Jenssegers\Mongodb\Collection->__call('find', Array)
#5 /Users/iraj/projects/project/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Query/Builder.php(211): Jenssegers\Mongodb\Query\Builder->getFresh(Array)
#6 /Users/iraj/projects/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(481): Jenssegers\Mongodb\Query\Builder->get(Array)
#7 /Users/iraj/projects/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(465): Illuminate\Database\Eloquent\Builder->getModels(Array)
#8 /Users/iraj/projects/project/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php(77): Illuminate\Database\Eloquent\Builder->get(Array)

I do not think it's because of real timeout problems or sothing related with connectTimeoutMS, socketTimeoutMS, wTimeoutMS or maxTimeMS options.
because in ::find() mode it is very fast in just milliseconds.

Laravel Framework: 5.6.39
jenssegers/mongodb: 3.4.5
Laravel/horizon: v1.4.3

@mauri870
Copy link
Contributor

Hello @irajtaghlidi we are facing the same issue, did you manage to solve the problem? If so, can you share the solution with us? Thanks

@irajtaghlidi
Copy link
Author

Hello @mauri870,
yes
I solved the problem just with adding use HybridRelations; to first relational Model too (in my case DeviceOrder class).

Another suggestion is to add Connection name in both mysql and MongoDB Model classes when they have relations together even when on of them have default Connection name, This will cause problem if you do not in some situations.

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

No branches or pull requests

3 participants