Конференция "Прочее" » Нужен совет по поводу обработки большого количества почты
 
  • Sha © (22.03.16 14:40) [20]
    > при удалении приходится перебирать все письма и сравнивать UIDL

    зачем перебирать, если можно сразу можно получить список всех пар
    No:UIDL
  • jack128 © (22.03.16 14:45) [21]
    На счет объема Rouse загнул, на пару порядков поменьше объем будет. И надежности никакой не надо, потерялась сотня сообщений об ошибках, ну и бог с ними, не жалко.  Поэтому я просто раз 15 минут подключаюсь считываю все письма на диск, удаляю с сервера и оправляю дальше на обработку, никаких заморочек нет.
  • KSergey © (22.03.16 14:54) [22]
    > Игорь Шевченко ©   (22.03.16 14:36) [19]
    > Sha ©   (22.03.16 13:49) [12]
    >
    > Я примерно понял, что ты хочешь сказать, но хотелось бы
    > для начала услышать, может, какие-то механизмы есть уже
    > готовые.

    Видимо речь про готовую команду UIDL протокола POP3

    А нельзя опереться на тот факт, что номера (не UIDL, а порядковые) неудалённых писем от сессии к сессии не меняются?
    Впрочем, можно же вообще не закрывать POP3 сессию. Подключился - загрузил письма - обработал - если успешно - удалил. Вот тут можно переподключиться и увидеть новые письма.
    Правда, вероятон медленное удаление писем - фича почтового сервера. ВОзможно - конкретного почтового сервера. Например, для корректной работы разных POP3 сессий (которые теоретически могут быть), плюс приём новых писем.
  • Sha © (22.03.16 14:55) [23]
    > мне не хочется хранить все в памяти и обрабатывать помногу

    размер порции может быть любой

    > если произойдет сбой, мне кажется, я могу потерять всю хранящуюся у меня информацию.

    во время обработки все данные лежат также на почтовом сервере

    > повторно отправлять на обработку валидные письма нежелательно

    если не потеряешь список UIDL, то все будет OK
  • Игорь Шевченко © (22.03.16 15:05) [24]
    jack128 ©   (22.03.16 14:45) [21]

    Увы, не мой вариант

    Sha ©   (22.03.16 14:40) [20]


    > зачем перебирать, если можно сразу можно получить список
    > всех пар
    > No:UIDL


    Не понял, можно подробнее ?

    KSergey ©   (22.03.16 14:54) [22]


    > А нельзя опереться на тот факт, что номера (не UIDL, а порядковые)
    > неудалённых писем от сессии к сессии не меняются?


    Я ОЧЕНЬ не уверен, что они не меняются.


    > Впрочем, можно же вообще не закрывать POP3 сессию. Подключился
    > - загрузил письма - обработал - если успешно - удалил. Вот
    > тут можно переподключиться и увидеть новые письма.


    Тут есть один нюанс - все процессы (валидации и оповещения об успешной постановке на обработку) асинхронные. То есть, я отправляю запрос на валидацию и занимаюсь дальше своим делом. Точно также я отправляю запрос на обработку письма и тоже занимаюсь своим делом. В нужный момент мне приходят оповещения об удачной/неудачной валидации и удачной/неудачной постановке на обработку. В обработчиках этих оповещений я и занимаюсь взаимодействием с почтовым сервером на предмет удалить письмо.
  • Sha © (22.03.16 15:38) [25]
    > Не понял, можно подробнее ?

    если опустить порядковый номер, то результат (список) вернется для всех порядковых номеров, известных в текущей сессии

    см https://tools.ietf.org/html/rfc1939
  • Игорь Шевченко © (22.03.16 15:46) [26]
    Sha ©   (22.03.16 15:38) [25]

    Спасибо, этого я не знал.
    К сожалению, используемые мной компоненты список не поддерживают. Indy, как я вижу, умеет.
    Но зтот список будет действительным для номеров в текущей транзакции сервера. После закрытия соединения, мне кажется, я могу список выбросить, нет ?
  • NoUser © (22.03.16 15:52) [27]
    А если на постоянной основе подключится несколькими такими клиентами ( UIDL and UIDL_MASK )
    и внешние процессы валидации и обработки подстроить под 'многоклиентность' ?

    ( я так понимаю на такой режим работы и заточены почтовики,
     а производительность обмена с внешними процессами увеличится )
  • Nouser © (22.03.16 15:55) [28]
    о, коли они асинхронные, то ( как минимум для теста) так и нужно сделать
  • Игорь Шевченко © (22.03.16 15:56) [29]
    NoUser ©   (22.03.16 15:52) [27]

    Не понимаю, можно подробнее ?
  • Nouser © (22.03.16 15:59) [30]

    > В обработчиках этих оповещений я и занимаюсь взаимодействием
    > с почтовым сервером на предмет удалить письмо.

    то есть новая сесия POP3 для каждого удаления?
  • Nouser © (22.03.16 16:03) [31]
    > подробнее
    каждый клиент работает только со своим 'окончанием'  UIDL или порядкового номера
    ( чёт/нечёт, если их два; b00/b01/b02/b03 если четыре )
  • Sha © (22.03.16 16:47) [32]
    > Но зтот список будет действительным для номеров в текущей транзакции сервера.
    >  После закрытия соединения, мне кажется, я могу список выбросить, нет ?

    Да, правильно его получать каждый раз в начале сессии.

    > то есть новая сесcия POP3 для каждого удаления?

    Удаление происходит по окончании сессии.
    До этого помеченные на удаление можно вернуть к жизни.
  • Игорь Шевченко © (22.03.16 17:46) [33]
    Sha ©   (22.03.16 16:47) [32]


    > Да, правильно его получать каждый раз в начале сессии.


    Я и так получаю этот список в начале сессии, при получении порции писем. Все письма складываются в некий внутренний список, с которым собственно выполняется работа. Когда мне надо письмо удалить (одно), я зная его UIDL, получаю от сервера письма, спрашиваю UIDL каждого, если совпадает, прошу удалить его и закрываю соединение. Ты предлагаешь при удалении получать полный список UIDL с сервера, найти там номер нужного и удалить, я верно понимаю ?
  • Sha © (22.03.16 18:37) [34]
    Нет.

    Удаление вообще не наша цель. Оно - прибамбас к получению.

    Наша цель - получение.
    Когда нам приходит мысль, что надо получить порцию данных
    (таймер или сигнал или просто бесконечный цикл),
    делаем следующее.
    1. Открываем соединение и прочитываем список всех UIDL, имеющихся на сервере.
    2. Определяем, что там появилось нового.
    3. Считываем порцию данных нужного нам размера.
    4. Отдаем на валидацию.
    5. Глядя в ведущийся нами список подлежащих удалению, помечаем на удаление невалидное и обработанное.
    6. Закрываем соединение, при этом произойдет физическое удаление.

    По событию завершения валидации
    - либо помещаем UIDL в список невалидных,
    - либо передаем сообщение на обработку, UIDL помещаем в список обрабатываемых.

    По событию завершения обработки
    1. помещаем UIDL в список обработанных
    2. если список обрабатываемых пуст, сигналим, что пора принимать.
  • Игорь Шевченко © (22.03.16 23:07) [35]
    Sha ©   (22.03.16 18:37) [34]

    Саша, спасибо тебе за помощь, но есть нюансы:
    И валидация и обработка - это асинхронные процессы. Результат валидации может поступить неизвестно когда. Но по результату надо запустить на обработку. Постановка на обработку - это тоже асинхронный процесс, ее результат тоже может придти неизвестно когда. Ты предлагаешь постоянно держать открытый сеанс с почтовым сервером ?
  • Sha © (23.03.16 00:14) [36]
    > Игорь Шевченко ©   (22.03.16 23:07) [35]
    > Ты предлагаешь постоянно держать открытый сеанс с почтовым сервером ?

    Нет, конечно.

    Основная идея в том, чтобы все время поддерживать непустую очередь на обработку. При этом мы отслеживаем текущее состояние всех скачанных писем (готово к валидации/готово к обработке/готово к удалению).

    По таймеру или сигналу об опустошении очереди на обработку выполняем такую единицу работы:
    1 Открываем соединение.
    2. Считываем оглавление, определяем в нем количество и ID ранее нами не прочитанных писем, скачиваем их (ставя на валидацию и запоминая ID) сколько надо (напр, 10 или 1000 штук)
    3. Метим на сервере на удаление те, которые надо было удалить к началу сеанса (т.е. как бы выполняем отложенное удаление).
    4. И быстренько закрываем сеанс.

    Остальные обработчики событий очевидны.
    Важно не терять время на индивидуальные удаление писем в отдельных сеансах и на лишние чтения оглавление.
  • Сергей Суровцев © (23.03.16 02:46) [37]
    Я правильно понял из Игорь Шевченко ©   (22.03.16 15:05) [24] что письма удаляются по одному за раз?
  • Игорь Шевченко © (23.03.16 10:36) [38]
    Сергей Суровцев ©   (23.03.16 02:46) [37]

    Да

    Sha ©   (23.03.16 00:14) [36]

    Я понял примерно.  Ты предлагаешь организовать зеркало писем и заниматься его синхронизацией. Это все хорошо, но если будет ошибка, что станет с этими внутренними структурами ?


    > Считываем оглавление, определяем в нем количество и ID ранее
    > нами не прочитанных писем


    Я не до конца понимаю, как определить "ранее не прочитанные письма". Как  только я открыл соединение, я считываю содержимое почтового ящика.
  • Sha © (23.03.16 11:03) [39]
    > Ты предлагаешь организовать зеркало писем

    Не совсем.
    Предлагается вести и надежно хранить только список троек (No,Id,State),
    полностью описывающих текущее состояние.

     

    > если будет ошибка, что станет с этими внутренними структурами ?

    Ничего страшного не произойдет.
    Максимум, если все рухнет совсем - повторная обработка.
    А если дублировать тройки хотя бы в INI файле, то вообще никаких последствий.

     

    > как определить "ранее не прочитанные письма"

    Ну, мы же в начале каждого сеанса имеем список пар (No,Id) на сервере
    и такой же список пар для писем, которые скачали в прошлых сеансах.
    Более того, для всех скачанных писем мы знаем их состояние в техпроцессе (готово к валидации/готово к обработке/готово к удалению).
 
Конференция "Прочее" » Нужен совет по поводу обработки большого количества почты
Есть новые Нет новых   [134434   +27][b:0.001][p:0.001]