Наши потоки выполнения основаны на элементах типа task. Однако часто требуется более высокий уровень абстракции — модуль, который объединяет несколько задач для выполнения конкретной функции. Использование текущего подхода требует от последней задачи передать управление следующей задаче через callback или заполнить ответ сервера. Это не всегда удобно. Поэтому мы ввели тип задачи WFModuleTask, чтобы сделать процесс создания модулей проще и снизить связанность между различными модулями.
Модуль представляет собой специальный тип задачи, называемый WFModuleTask. Внутри модуля содержится sub_series для выполнения задач внутри модуля. Для задачи важно знать, что она может работать независимо от того, находится ли она внутри модуля или нет. Sub_series внутри модуля ничем не отличается от обычного series. Создание модуля задачи доступно через интерфейсы в WFTaskFactory.h:
using module_callback_t = std::function<void(const WFModuleTask *)>;
class WFTaskFactory
{
public:
static WFModuleTask *create_module_task(SubTask *first, module_callback_t callback);
};
Первым аргументом create_module_task() является первый подзадача модуля, аналогично созданию серии задач. Параметр callback должен принимать константный указатель, чтобы предотвратить возможность добавления новых задач внутри callback.
Как и любая другая задача, модуль также имеет свои методы использования. Однако модуль не имеет состояния или области ошибок. Определение класса WFModuleTask приведено в WFTask.h:
class ModuleTask : public ParallelTask, protected SeriesWork // не обращайте внимания на этот наследственный связь
{
public:
void start() { .. }
void dismiss() { ... }
public:
SeriesWork *sub_series() { return this; }
const SeriesWork *sub_series() const { return this; }
public:
void *user_data;
};
Уникальный интерфейс sub_series возвращает серию задач внутри модуля. Модуль фактически представляет собой подпоток задач. Sub_series также является обычной серией, которую можно использовать set_context(), get_context(), push_back() и другие функции. Но использование callback модуля рекомендовано вместо установки callback для sub_series. Обратите внимание, что параметр callback модуля является const WFModuleTask *, то есть доступен только константный sub_series. Поэтому в callback модуля доступна только функция get_context() для получения контекста серии.
В логике обработки HTTP сервера все обработчики могут быть организованы как один модуль.
struct ModuleCtx
{
std::string body;
};
void http_callback(WFHttpTask *http_task)
{
SeriesWork *series = series_of(http_task); // эта серия - это sub_series модуля.
struct ModuleCtx *ctx = (struct ModuleCtx *)series->get_context();
const void *body;
size_t size;
if (http_task->get_resp()->get_parsed_body(&body, &size))
{
ctx->body.assign(body, size);
}
ParallelWork *pwork = Workflow::create_parallel_work(...); // выполняются некоторые другие действия
series->push_back(pwork);
}
void process(WFHttpTask *server_task)
{
WFHttpTask *http_task = WFTaskFactory::create_http_task(..., http_callback);
WFModuleTask *module = WFTaskFactory::create_module_task(http_task, [server_task](const WFModuleTask *mod) {
struct ModuleCtx *ctx = (struct ModuleCtx *)mod->sub_series()->get_context();
server_task->get_resp()->append_output_body(ctx->body);
delete ctx;
});
module->sub_series()->set_context(new ModuleCtx);
series_of(server_task)->push_back(module);
}
Этот подход позволяет задачам внутри модуля работать с контекстом серии, а затем callback модуля собирает и заполняет ответ. Это значительно снижает связанность между задачами.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )