Memory exhausted when queueing "a lot" of emails
glpzzz opened this issue · comments
First, thanks for the wonderful extension! I have been using without issue till now:
For a certain case I tried to queue 1500 emails, but the script exploded around the 500 emails.
Email is no complex, the generated .eml when using fileTransport is 20kb.
Making some db optimizations so all the data is grabbed in one query I was able to make it queue around 700 emails.
After other tests, it seems that the issue is on Yii::$app->mailer->queue().
Any ideas on this?
Thanks!
@glpzzz the issue is at $item->save()
in queue()
function, which makes a database call each time it's called. So, for 700 mails it makes 700 database calls. You can solve this by doing a bulk insert. Serialize the messages first and insert them later.
$queueModel = new Queue;
Yii::$app->db->createCommand()->batchInsert(Queue::tableName(), $queueModel->attributes(), $rows)->execute();
Don't forget to send a PR if you add a new function to do bulk insert. :)
No promising but I'll try to implement the bulk insert. Thanks on the suggestion!
@nterms any idea on how to call this bulk insert? I'm thinking in something like Yii::$app->mailqueue->bulkQueue($messages)
and then execute your suggested code there.
Your suggestion worked for us. There where so many emails that it exploded anyway, but because of yiisoft/yii2#6472 TL;DR
$connection = \Yii::$app->db;
$connection->enableLogging = false;
$connection->enableProfiling = false;
before doing the batchInsert. With that all good.
The other thing was to do several batchInsert instead of just one. The base64_encode(serialize($message))
increases the size of the row that MySQL complains for the packet size or PHP because of memory.
Ours is a corner case, so making some manual adjustments to the code it's not a big issue.