długo wykonujący się skrypt + Ajax

0

Napisałem skrypt, który wysyła maile z informacją do userów. Jest ich max. 500, mam też obsługę dzielenia na paczki np. po 50.
Skrypt wykonuje się w zależności od ilości wiadomości ok 3-5 min.
Chciałbym ten skrypt odpalić przez AJAX a na ekranie pokazać userowi np. pasek postępu lub wysłano 5 z 50 itd.
W sieci natknąłem się na taki sposób aby skrypt PHP po każdej sztuce zapisywał np. w sesji postęp. Drugie żądanie AJAX np. co 5 sekund zaglądało by do sesji i zwracało co tam znalazło.
Jak byście podeszli do takiego tematu?

0

Możesz jeszcze użyć socketów lub Server-Sent Events

0

Troszkę długo Ci to trwa. Czego używasz do wysyłania maili? 500maili w ~240 sekund... może dasz radę zoptymalizować troszkę sam proces przygotowania treści. A co do Twojego rozwiązania - nie widzę przeszkód, ogranicz tylko ponawianie wysyłania wiadomości do jakiejś granicznej wartości np 3 powtórzenia. W sumie to przełoży się pewnie na to, aby te dane trzymał w bazie (daty nieudanych wysyłek oraz dane adresata), stąd byś też pewnie zaciągał ilość niewysłanych maili ... coś w stylu "select * from mail_queue where mail_queue_user_id = ? AND mail_queue_sent = 0 and mail_queue_try_count < 5" Rozumiem też że każdy mail zawiera spersonalizowaną treść np "Witaj Piotrek"

0

Zamiast wysyłać pojedynczo maile wyślij jednego z ukrytymi odbiorcami

0

Tak treść maila jest spersonalizowana o parę zmiennych.

0

Ja bym stworzył jakąś buforową wartość w bazie danych, gdzie skrypt wysyłający maile po każdym obiegu pętli uaktualniał postęp, z kolei z poziomu przeglądarki ajaxem sprawdzałbym jaka jest wartość postępu w bazie danych :)

Jeżeli mailing jest b.duży można uzupełnić pasek postępu o dodatkowe informacje typu ilość odrzuconych, odebranych czy też odczytanych maili.

Kiedyś napisałem skrypt który wysyłał pakiety mailingowe po 2-3 miesiące, i tak to rozwiązałem.

1

Wypróbuj to:

<?php
// Wszystko poza blokiem TWÓJ KOD edytujesz na własną odpowiedzialność :P

$recipients = array_fill(0, 50, '[email protected]');
$total = count($recipients);

foreach ($recipients as $index => $recipient) {
    // ustawiamy konieczne headery
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');

    // ---------- TWÓJ KOD START -----------

    // imitujemy wysyłanie maila
    sleep(1);

    // tutaj wrzucasz to co chcesz przesłać na front-end
    $data = json_encode([
        'last_recipient' => $recipient,
        'done' => $index + 1,
        'total' => $total
    ]);

    // ---------- TWÓJ KOD END -----------

    // ten format musi być dokładnie taki
    echo "data: " . $data . PHP_EOL;
    echo PHP_EOL;

    // tutaj musimy wywołać dokładnie te funkcje,
    // w tej kolejności bo inaczej nie zadziala
    ob_end_flush();
    flush();
}
<span id="progress"></span>
<button id="send">Wyślij</button>
const sendBtn = document.getElementById('send')

sendBtn.addEventListener('click', function (e) {
    const progress = document.getElementById('progress')
    const sse = new EventSource('mail.php')

    sse.addEventListener('message', function(e) {
        const data = JSON.parse(e.data)
        console.log(data);

        progress.innerHTML = `${data.done}/${data.total}`
    }, false)
})
0

Natknąłem się na coś takiego Desu. Dzieki, wyprobuję.
Moja wysylka trwa tyle bo co x czasu (konfigurowalne) robie chwilkę przerwy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1