1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/sogou-workflow

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
about-module.md 5.4 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 01.03.2025 10:20 552780a

О задачах модулей

Наши потоки выполнения основаны на элементах типа 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

Как и любая другая задача, модуль также имеет свои методы использования. Однако модуль не имеет состояния или области ошибок. Определение класса 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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/sogou-workflow.git
git@api.gitlife.ru:oschina-mirror/sogou-workflow.git
oschina-mirror
sogou-workflow
sogou-workflow
master