I'm using Filament PHP v3 with Laravel and have a table that can contain 500,000+ user records. When users click the "Select All" button the application crashes with a memory exhausted error:
Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)
use Filament\Tables\Concerns\InteractsWithTable;
class SendMail extends Page implements HasTable
{
use InteractsWithTable;
public function table(Table $table): Table
{
return $table
->query(User::query()->where('is_admin', 0))
->columns([
TextColumn::make('full_name'),
TextColumn::make('email'),
])
->bulkActions([
BulkAction::make('send_mail')
->form([
Wizard::make([
Wizard\Step::make('メール入力画面')
->schema(fn($livewire) => [
ViewField::make('user-table')
->label('')
->dehydrated(false)
->view('filament.commons.selected-user-table-wrapper'),
TextInput::make('subject')
->label('件名')
->markAsRequired()
->rules(['required'])
->validationMessages([
'required' => Config::get('messages.ERROR.MES_001'),
])
->columnSpan('full')
->extraInputAttributes(['maxlength' => "255"]),
Textarea::make('content')
->label('内容')
->rows(5)
->markAsRequired()
->rules(['required'])
->validationMessages([
'required' => Config::get('messages.ERROR.MES_001'),
])
->columnSpan('full')
->extraInputAttributes(['maxlength' => "512"]),
]),
Wizard\Step::make('メール確認画面')
->schema([
Placeholder::make('mail_subject')
->label('件名')
->content(fn(Get $get) => $get('subject')),
Placeholder::make('mail_content')
->label('内容')
->content(fn(Get $get) => new HtmlString(nl2br(e($get('content'))))),
]),
])
->previousAction(fn($action) => $action->label('戻る'))
->submitAction(new HtmlString(Blade::render(<<<BLADE
<x-filament::button
type="submit"
size="md"
>
送信
</x-filament::button>
BLADE)))
])
->label('メール送信')
->modalSubmitAction(false)
->modalCancelAction(false)
->modalWidth(MaxWidth::FiveExtraLarge)
->action(fn($data, $records) => $this->sendMail($data, $records)),
])
}
}
The problem is that when "Select All" is clicked, $records contains all 500k User models loaded into memory.
How can I either: Limit "Select All" to 150,000 records max and show a warning notification if exceeded
Thanks all
sendMailfunction? Also, have you thought of doing background process? As for limiting the records, I believe you can throw an exception in thesendMailfunction as well. But let's see your code first.