-
> при удалении приходится перебирать все письма и сравнивать UIDL
зачем перебирать, если можно сразу можно получить список всех пар No:UIDL
-
На счет объема Rouse загнул, на пару порядков поменьше объем будет. И надежности никакой не надо, потерялась сотня сообщений об ошибках, ну и бог с ними, не жалко. Поэтому я просто раз 15 минут подключаюсь считываю все письма на диск, удаляю с сервера и оправляю дальше на обработку, никаких заморочек нет.
-
> Игорь Шевченко © (22.03.16 14:36) [19] > Sha © (22.03.16 13:49) [12] > > Я примерно понял, что ты хочешь сказать, но хотелось бы > для начала услышать, может, какие-то механизмы есть уже > готовые.
Видимо речь про готовую команду UIDL протокола POP3
А нельзя опереться на тот факт, что номера (не UIDL, а порядковые) неудалённых писем от сессии к сессии не меняются? Впрочем, можно же вообще не закрывать POP3 сессию. Подключился - загрузил письма - обработал - если успешно - удалил. Вот тут можно переподключиться и увидеть новые письма. Правда, вероятон медленное удаление писем - фича почтового сервера. ВОзможно - конкретного почтового сервера. Например, для корректной работы разных POP3 сессий (которые теоретически могут быть), плюс приём новых писем.
-
> мне не хочется хранить все в памяти и обрабатывать помногу
размер порции может быть любой
> если произойдет сбой, мне кажется, я могу потерять всю хранящуюся у меня информацию.
во время обработки все данные лежат также на почтовом сервере
> повторно отправлять на обработку валидные письма нежелательно
если не потеряешь список UIDL, то все будет OK
-
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 сессию. Подключился > - загрузил письма - обработал - если успешно - удалил. Вот > тут можно переподключиться и увидеть новые письма.
Тут есть один нюанс - все процессы (валидации и оповещения об успешной постановке на обработку) асинхронные. То есть, я отправляю запрос на валидацию и занимаюсь дальше своим делом. Точно также я отправляю запрос на обработку письма и тоже занимаюсь своим делом. В нужный момент мне приходят оповещения об удачной/неудачной валидации и удачной/неудачной постановке на обработку. В обработчиках этих оповещений я и занимаюсь взаимодействием с почтовым сервером на предмет удалить письмо.
-
> Не понял, можно подробнее ? если опустить порядковый номер, то результат (список) вернется для всех порядковых номеров, известных в текущей сессии см https://tools.ietf.org/html/rfc1939
-
Sha © (22.03.16 15:38) [25]
Спасибо, этого я не знал. К сожалению, используемые мной компоненты список не поддерживают. Indy, как я вижу, умеет. Но зтот список будет действительным для номеров в текущей транзакции сервера. После закрытия соединения, мне кажется, я могу список выбросить, нет ?
-
А если на постоянной основе подключится несколькими такими клиентами ( UIDL and UIDL_MASK ) и внешние процессы валидации и обработки подстроить под 'многоклиентность' ?
( я так понимаю на такой режим работы и заточены почтовики, а производительность обмена с внешними процессами увеличится )
-
о, коли они асинхронные, то ( как минимум для теста) так и нужно сделать
-
NoUser © (22.03.16 15:52) [27]
Не понимаю, можно подробнее ?
-
> В обработчиках этих оповещений я и занимаюсь взаимодействием > с почтовым сервером на предмет удалить письмо.
то есть новая сесия POP3 для каждого удаления?
-
> подробнее каждый клиент работает только со своим 'окончанием' UIDL или порядкового номера ( чёт/нечёт, если их два; b00/b01/b02/b03 если четыре )
-
> Но зтот список будет действительным для номеров в текущей транзакции сервера. > После закрытия соединения, мне кажется, я могу список выбросить, нет ?
Да, правильно его получать каждый раз в начале сессии.
> то есть новая сесcия POP3 для каждого удаления?
Удаление происходит по окончании сессии. До этого помеченные на удаление можно вернуть к жизни.
-
Sha © (22.03.16 16:47) [32]
> Да, правильно его получать каждый раз в начале сессии.
Я и так получаю этот список в начале сессии, при получении порции писем. Все письма складываются в некий внутренний список, с которым собственно выполняется работа. Когда мне надо письмо удалить (одно), я зная его UIDL, получаю от сервера письма, спрашиваю UIDL каждого, если совпадает, прошу удалить его и закрываю соединение. Ты предлагаешь при удалении получать полный список UIDL с сервера, найти там номер нужного и удалить, я верно понимаю ?
-
Нет.
Удаление вообще не наша цель. Оно - прибамбас к получению.
Наша цель - получение. Когда нам приходит мысль, что надо получить порцию данных (таймер или сигнал или просто бесконечный цикл), делаем следующее. 1. Открываем соединение и прочитываем список всех UIDL, имеющихся на сервере. 2. Определяем, что там появилось нового. 3. Считываем порцию данных нужного нам размера. 4. Отдаем на валидацию. 5. Глядя в ведущийся нами список подлежащих удалению, помечаем на удаление невалидное и обработанное. 6. Закрываем соединение, при этом произойдет физическое удаление.
По событию завершения валидации - либо помещаем UIDL в список невалидных, - либо передаем сообщение на обработку, UIDL помещаем в список обрабатываемых.
По событию завершения обработки 1. помещаем UIDL в список обработанных 2. если список обрабатываемых пуст, сигналим, что пора принимать.
-
Sha © (22.03.16 18:37) [34]
Саша, спасибо тебе за помощь, но есть нюансы: И валидация и обработка - это асинхронные процессы. Результат валидации может поступить неизвестно когда. Но по результату надо запустить на обработку. Постановка на обработку - это тоже асинхронный процесс, ее результат тоже может придти неизвестно когда. Ты предлагаешь постоянно держать открытый сеанс с почтовым сервером ?
-
> Игорь Шевченко © (22.03.16 23:07) [35] > Ты предлагаешь постоянно держать открытый сеанс с почтовым сервером ?
Нет, конечно.
Основная идея в том, чтобы все время поддерживать непустую очередь на обработку. При этом мы отслеживаем текущее состояние всех скачанных писем (готово к валидации/готово к обработке/готово к удалению).
По таймеру или сигналу об опустошении очереди на обработку выполняем такую единицу работы: 1 Открываем соединение. 2. Считываем оглавление, определяем в нем количество и ID ранее нами не прочитанных писем, скачиваем их (ставя на валидацию и запоминая ID) сколько надо (напр, 10 или 1000 штук) 3. Метим на сервере на удаление те, которые надо было удалить к началу сеанса (т.е. как бы выполняем отложенное удаление). 4. И быстренько закрываем сеанс.
Остальные обработчики событий очевидны. Важно не терять время на индивидуальные удаление писем в отдельных сеансах и на лишние чтения оглавление.
-
Я правильно понял из Игорь Шевченко © (22.03.16 15:05) [24] что письма удаляются по одному за раз?
-
Сергей Суровцев © (23.03.16 02:46) [37]
Да
Sha © (23.03.16 00:14) [36]
Я понял примерно. Ты предлагаешь организовать зеркало писем и заниматься его синхронизацией. Это все хорошо, но если будет ошибка, что станет с этими внутренними структурами ?
> Считываем оглавление, определяем в нем количество и ID ранее > нами не прочитанных писем
Я не до конца понимаю, как определить "ранее не прочитанные письма". Как только я открыл соединение, я считываю содержимое почтового ящика.
-
> Ты предлагаешь организовать зеркало писем
Не совсем. Предлагается вести и надежно хранить только список троек (No,Id,State), полностью описывающих текущее состояние.
> если будет ошибка, что станет с этими внутренними структурами ?
Ничего страшного не произойдет. Максимум, если все рухнет совсем - повторная обработка. А если дублировать тройки хотя бы в INI файле, то вообще никаких последствий.
> как определить "ранее не прочитанные письма"
Ну, мы же в начале каждого сеанса имеем список пар (No,Id) на сервере и такой же список пар для писем, которые скачали в прошлых сеансах. Более того, для всех скачанных писем мы знаем их состояние в техпроцессе (готово к валидации/готово к обработке/готово к удалению).
|