вторник, 12 февраля 2008 г.

Проектирование многопоточного (multi thread) приложения

Я решил поместить все xml-rpc запросы в отдельный поток. Причины этого я уже описывал: сколько будет идти запрос к xml-rpc серверу неизвестно, и в это время негоже, чтобы приложение как бы подвисало, то есть не обрабатывалась бы очередь событий. Ну это очевидно. Чтобы начать xml-rpc запрос в отдельном потоке, его необходимо приготовить. Для синхронизации с потоком, где находится http клиент, я использую события Windows, посылая их с помощью PostMessage. В потоке, где клиент, организована обработка очереди событий. По большому очередь событий не нужна, можно было бы обойтись и объектом синхронизации событием, но не тем что посылается. Но это хорошо работает только на одном/двух событиях, а если событий несколько, то придется это разруливать, поэтому удобнее и проще использовать стандартную очередь событий.

И так, начинается приключение под названием “синхронизация событий”. Создан xml-rpc запрос, и отправлено событие потоку. Поток проснулся и начал танец с подключением к серверу. В это время главный поток может заниматься своими делами, например показывать диалог с индикатором выполнения. Предположим, что все прошло успешно: запрос отправлен и получен ответ, и ответ не содержит ошибок. А если где то случилась ошибка, ну например прервалась связь с Интернетом, то из этого потока надо сообщить главному об ошибке. А если во время выполнения запроса юзверь захочет прервать операцию, например закрыв приложение, то надо предусмотреть механизм досрочного прекращения работы. после окончания сеанса связи с сервером надо сообщить об этом главному потоку или вызвавшему потоку о завершении связи. С другой стороны можно также позволить юзверу делать все что угодно, кроме операций с сервером, пока идет сеанс связи с сервером. Ну например вы удаляете комментарии - выделили несколько комментов и нажали кнопку Del, тем самым запустив параллельный поток, который и будет удалять комментарии с сервера и на локальном списке. В это время можно позволить юзверю ходить по списку и читать комменты, либо показывать диалог с пробегающими процентами текущего сеанса связи, тем самым блокируя любую активность юзверя. С точки зрения программиста проще не пущать и показывать диалог с прогресс баром. Но можно и позволить юзверю толику свободы. Как поступить? Я не знаю. По умолчанию сбуду показывать диалог, в котором будет кнопка “Скрыть”, убирающая диалог. Но если без диалога, то надо будет ждать в специальном месте окончание сеанса связи, чтобы обработать ответ сервера и в случае ошибки показать таковую, а в случае успеха произвести симметричные действия с локальным списком комментариев. Если без диалога, то надо еще помнить, какую функцию вызвал на сервере, чтобы обработать ответ: если удалял, то и локально удалить, если снял отметку спам, то переместить из папки со спамом. То есть требуется симметричная синхронизация из потока с http клиентом в основной поток. Следовательно в два раза увеличивается количество передаваемых событий и следствие этого в два раза увеличивается вероятность ошибки в написанном коде. Если вообще без потоков то нет никакой нужды синхронизировать одно с другим. Но события от юзверя всегда происходят в главном потоке.

Можно придумать еще одну потоковую модель для блог клиента: из GUI посылается событие потоку на какое то действие, например удаление. Поток просыпается на это событие и формирует запрос, его же отправляет, расшифровывает ответ и удаляет из локального списка. А чтобы не был изменен контекст, в котором производятся действия, можно запретить на время операции менять папку: делай все что угодно, но только в пределах одной папки, пока не закончится сеанс связи с сервером. Ну а как же тогда операции drag&drop? Получается больше вопросов чем ответов.

Вывод: многопотоковое приложение это вам не хухры-мухры, и не дули в кармане крутить… Окончательное решение я еще не принял, потому что для меня еще есть ряд нерешенных задач, по мере написания часть из них решается, но и возникают новые. Уже написал диалог с прогрессом и основу для потока и лога событий http запросов вместе с обработкой ошибок. Отдельной решенной задачей явилась получение адреса xml rpc сервера из заголовков или из html страницы. Все приходится ручками прописывать, и не факт, что созданный мной код не содержит ошибок.

Продолжается эпопея с arhivperipiski.ru: яндекс ответил что все в порядке, но в индексе и в выдаче сайт отсутствует. По статистике webmaster.yandex.ru раздел мои сайты, проиндексировано яндексом более 30000 страниц - может быть у них там какой то особый фильтр, не знаю, буду ждать. После письма яндексу сдвинулся с мертвой точки simplygate.com(12 страниц в индексе в течении нескольких месяцев) до 300 уже сегодня. Не знаю может быть ему тоже уготована судьба быть выкинутым из выдачи. По той же статистике много ошибок 404 - задумался, но не знаю как решить: по статистике яндекс конкретно указывает откуда битая ссылка, но по моей проверке битых ссылок нет, так что я в растерянности.

Здесь можно оставить свои комментарии. Выпуск подготовленплагином wordpress для subscribe.ru

Комментариев нет: