Maximum execution time of 60 seconds exceeded

I have this Observer where I want to get the total whenever I create or update on my OrderResource It's working but taking a long time to process and gets error at the end of the process "maximum execution time error of 60 seconds"
30 Replies
Chrysippus
ChrysippusOP2y ago
OrderResource
Chrysippus
ChrysippusOP2y ago
OrderObserver
<?php

namespace App\Observers;

use App\Models\Order;

class OrderObserver
{
public function saved(Order $order)
{
$this->updateTotal($order);
}

public function deleted(Order $order)
{
$this->updateTotal($order);
}

private function updateTotal(Order $order)
{
$orderItems = $order->orderItems()->get();
$shippingFee = $order->shipping_fee;
$subtotal = $orderItems->sum(function ($item) {
return $item->product_quantity * $item->product_price;
});
$total = $subtotal + $shippingFee;
$order->total = $total;
$order->save();
}
}
<?php

namespace App\Observers;

use App\Models\Order;

class OrderObserver
{
public function saved(Order $order)
{
$this->updateTotal($order);
}

public function deleted(Order $order)
{
$this->updateTotal($order);
}

private function updateTotal(Order $order)
{
$orderItems = $order->orderItems()->get();
$shippingFee = $order->shipping_fee;
$subtotal = $orderItems->sum(function ($item) {
return $item->product_quantity * $item->product_price;
});
$total = $subtotal + $shippingFee;
$order->total = $total;
$order->save();
}
}
Dennis Koch
Dennis Koch2y ago
What's the question?
Chrysippus
ChrysippusOP2y ago
The process of getting the total whenever I create/update was working but only after 60seconds and i get the 60seconds timeout
Dennis Koch
Dennis Koch2y ago
Again: What is your question? Why does that simple summarization code take so long?
Chrysippus
ChrysippusOP2y ago
yes
Dennis Koch
Dennis Koch2y ago
That's something you need to figure out. It's hard to debug performance issues via chat. Start by checking the execution time of the updateTotal method.
Chrysippus
ChrysippusOP2y ago
Is my method correct or there's more suitable solution to do this?
Dennis Koch
Dennis Koch2y ago
I guess you are running into a loop: When you call $order->save() your Observer::saved() method is called again
Chrysippus
ChrysippusOP2y ago
Can't I just get the total directly from the textInput something like this
TextInput::make('total')
->dehydrated(false)
->label('Total Price')
->default(function ($get) {
$orderItems = collect($get('orderItems'));
$shippingFee = $get('shipping_fee');
$subtotal = $orderItems->sum(function ($item) {
return $item['product_quantity'] * $item['product_price'];
});
return $subtotal + $shippingFee;
}),
TextInput::make('total')
->dehydrated(false)
->label('Total Price')
->default(function ($get) {
$orderItems = collect($get('orderItems'));
$shippingFee = $get('shipping_fee');
$subtotal = $orderItems->sum(function ($item) {
return $item['product_quantity'] * $item['product_price'];
});
return $subtotal + $shippingFee;
}),
Hiighsky
Hiighsky2y ago
You can just use saveQuietly() instead save() to prevent this endless loop in your observer.
Chrysippus
ChrysippusOP2y ago
yes, problem already solved but created another problem. the mthod only works when I updated but when I tried to create my total value is the same of $shippingFee which means $subTotal doesnt have value. So maybe can resolve both if I can just directly get the total using the TextInput and disregard the Observer
Hiighsky
Hiighsky2y ago
My suggestion would be to make this whole thing reactive and calculate the total on the fly https://filamentphp.com/docs/2.x/forms/advanced#reloading-the-form-when-a-field-is-updated So basically you make orderItems and shippingFee reactive and on the total field you listen for changes and calculate everything
Chrysippus
ChrysippusOP2y ago
so i'll need do use afterStateUpdated multiple times?
Hiighsky
Hiighsky2y ago
Why multiple times? If I got you correct you just need it for your total field
Chrysippus
ChrysippusOP2y ago
ohh, I forgot to mention that im using the total outside the repeater
Chrysippus
ChrysippusOP2y ago
This is what I got when im using Placeholder but its only Placeholder, I need the TextInput
Placeholder::make('total')
->dehydrated(false)
->label('Total Price')
->content(function ($get) {
$orderItems = collect($get('orderItems'));
$shippingFee = $get('shipping_fee');
$subtotal = $orderItems->sum(function ($item) {
return $item['product_quantity'] * $item['product_price'];
});
return $subtotal + $shippingFee;
}),
Placeholder::make('total')
->dehydrated(false)
->label('Total Price')
->content(function ($get) {
$orderItems = collect($get('orderItems'));
$shippingFee = $get('shipping_fee');
$subtotal = $orderItems->sum(function ($item) {
return $item['product_quantity'] * $item['product_price'];
});
return $subtotal + $shippingFee;
}),
but its not working when I used TextInput instead of Placeholder
Hiighsky
Hiighsky2y ago
Can you show me the repeater code?
Chrysippus
ChrysippusOP2y ago
this is what I have so far, I was able to get the total for now but only if I set/updated the shipping_fee
Chrysippus
ChrysippusOP2y ago
Hiighsky
Hiighsky2y ago
Yes because you only have afterStateUpdated on the shipping_fee field, you need it for product_quantity and price too
Chrysippus
ChrysippusOP2y ago
but when I tried it didnt work I think because total is outside the repeater.
Hiighsky
Hiighsky2y ago
$set('../../total', ....
$set('../../total', ....
That should work from inside the repeater
Dennis Koch
Dennis Koch2y ago
Make those fields reactive and use a placeholder field instead of `afterStateUpdated
Hiighsky
Hiighsky2y ago
He don't want a placeholder field, he want it as a TextInput
Chrysippus
ChrysippusOP2y ago
should I still use the orderItem collection? inside repeater?
Dennis Koch
Dennis Koch2y ago
Sorry, skipped that part
Hiighsky
Hiighsky2y ago
You probably have to
Chrysippus
ChrysippusOP2y ago
collection returns null but its working now, I just need to used $get then do the '../../TextInput_outside_repeater', to get other the necessary values. now I wont have to use Observer, idk which one is better but atleast for now its working. Thankyou!
Chrysippus
ChrysippusOP2y ago
I didnt notice that It has an issue if I have 2 values on my repeater it will only get the total of the recent value.
Want results from more Discord servers?
Add your server