C++异步网络库workflow系列教程(3)Series串联任务流

news2024/11/14 3:09:34

往期教程

如果觉得写的可以,请给一个点赞+关注支持一下

观看之前请先看,往期的两篇博客教程,否则这篇博客没办法看懂

  • workFlow c++异步网络库编译教程与简介

  • C++异步网络库workflow入门教程(1)HTTP任务

  • C++异步网络库workflow系列教程(2)redis任务

简介

首先,workflow是任务流的意思,在workflow中万物皆为任务流.任务流分为以下两种

  • 串联:就像链表一样,前面的任务执行完了后执行后面的
  • 并联:可以理解为开了多个线程,并发执行任务

无标题

示例代码

首先,还是老规矩,先看代码示例,我会将所有新出现的成员一一进行介绍

#include <workflow/WFFacilities.h>
void seriesCallback(const SeriesWork *series){
    fprintf(stderr,"series callback , free pkey\n");
    std::string *pkey = static_cast<std::string *>(series->get_context());
    delete pkey;
}
void callback(WFRedisTask *redisTask){
        protocol::RedisRequest *req = redisTask->get_req();
        protocol::RedisResponse *resp = redisTask->get_resp();
        int state = redisTask->get_state();
        int error = redisTask->get_error();
        protocol::RedisValue value;//value对象专门用来存储redis任务的结果
        switch (state){
        case WFT_STATE_SYS_ERROR:
            fprintf(stderr,"system error: %s\n", strerror(error));
            break;
        case WFT_STATE_DNS_ERROR:
            fprintf(stderr,"dns error: %s\n", gai_strerror(error));
            break;
        case WFT_STATE_SUCCESS:
            resp->get_result(value);
            if(value.is_error()){
                fprintf(stderr,"redis error\n");
                state = WFT_STATE_TASK_ERROR;
            }
            break;
        }

        if (state != WFT_STATE_SUCCESS){
            fprintf(stderr, "Failed\n");
            return;
        }
        else{
            fprintf(stderr, "Success!\n");
        }

        std::string cmd;
        req->get_command(cmd);
        if(cmd=="SET"){
            //firstTask的基本工作做完了
            //创建新任务,把新任务加入到本序列的末尾
            fprintf(stderr,"first task callback begins\n");
            std::string *pkey = static_cast<std::string *>(redisTask->user_data);
            WFRedisTask *secondTask = WFTaskFactory::create_redis_task("redis://127.0.0.1:6379",0,callback);
            protocol::RedisRequest *req = secondTask->get_req();
            req->set_request("GET",{*pkey});
            SeriesWork* series = series_of(redisTask);
            series->set_context(static_cast<void *>(pkey));
            series->set_callback(seriesCallback);
            series->push_back(secondTask);
            fprintf(stderr,"first task callback ends\n");
        }
        else{
            //secondTask的基本工作做完了
            fprintf(stderr,"second task callback begins\n");
            fprintf(stderr, "redis request, cmd = %s\n", cmd.c_str());
            if (value.is_string()){
                fprintf(stderr, "value is a string, value = %s\n", value.string_value().c_str());
            }
            else if (value.is_array()){
                fprintf(stderr, "value is string array\n");
                for (size_t i = 0; i < value.arr_size(); ++i){
                    fprintf(stderr, "value at %lu = %s\n", i, value.arr_at(i).string_value().c_str());
                }
            }
            fprintf(stderr,"second task callback ends\n");
        }
    }
int main(){
    //创建redis任务
    //std::string key = "43key1";
    std::string * pkey = new std::string("43key2");
    WFRedisTask *firstTask = WFTaskFactory::create_redis_task("redis://127.0.0.1:6379",0,callback);
    //设置redis任务的属性
    protocol::RedisRequest *req = firstTask->get_req();
    req->set_request("SET",{*pkey, "200"});
    firstTask->user_data = static_cast<void *>(pkey);
    //启动redis任务
    firstTask->start();
}

示例剖析

  • 首先我们先看见main函数中第77行firstTask->user_data,如下是该成员的源码实现截图,为一个void*指针,通过变量名我们可以知道这是用来存储用户上下文的变量,可以在响应回调函数中将数据取出来进行使用(如43行中取出使用)

image-20231215163901660

任务流

  • series_of(redisTask)函数可以通过任务流节点获取到该任务节点所属的任务流的指针(在main函数中调用的firstTask->start();便是创建了一个任务流),
  • set_context()与上面的user_data类似,不过set_context设置的生存周期在整个任务流的生存周期,而user_data的生存周期只在所属的任务流节点的生存周期
  • set_callback()用来设置该任务流的清理回调函数,调用时机在该任务流所有任务节点全部执行完毕之后
  • series->push_back(secondTask):secondTask这个任务添加在任务流的末尾节点

代码执行流程梳理

  1. main函数中设置了一个redis任务,任务将执行"SET 43key2 200"这个指令
  2. callback回调函数中,找到该任务所属的任务流,并创建一个新的任务执行"GET 43key2"这个命令,并将这个任务插在任务流后面,
  3. callback回调函数中,执行53行开始的代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1313190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图解python | 字典

1.Python字典(Dictionary) 字典是另一种可变容器模型&#xff0c;且可存储任意类型对象。 字典的每个键值 key>value 对用冒号 : 分割&#xff0c;每个键值对之间用逗号 , 分割&#xff0c;整个字典包括在花括号 {} 中 ,格式如下所示&#xff1a; d {key1 : value1, key…

软件测试职业规划

软件测试人员的发展误区【4】 公司开发的产品专业性较强&#xff0c;软件测试人员需要有很强的专业知识&#xff0c;现在软件测试人员发展出现了一种测试管理者不愿意看到的景象&#xff1a; 1、开发技术较强的软件测试人员转向了软件开发(非测试工具开发)&#xff1b; 2、业务…

题目:区间或 (蓝桥OJ 3691)

题目描述: 解题思路: 本题采用位运算.先求出全部数组每一位各自的前缀和,然后再判断区间内每一位区间和是否为0,不为0则乘上相应的2^n并将各个为的2^n相加,得ans. 实现原理图 题解: #include<bits/stdc.h> using namespace std;const int N 1e5 9;int a[N], prefix[35…

2023AI Agent智能体HR商用落地的案例汇集

过去一周在各类智能体产品不断呈现新发展态势的情况下&#xff0c;我们将注意力继续放回AI Agent智能体在大型和超大型企业不同领域商用落地的可能性探索上面去。 本着这一初衷&#xff0c;我们会继续把注意力转向探索AI Agent智能体在HR领域的商用落地所面临的挑战和最可能实…

ida脚本环境开发配置idapythonidacpp三端环境(win,mac,linux)

ida脚本也有一段时间了,一直有个痛点是找不到比较好的方法热重载脚本来实时改动生效,导致开发效率老慢了。固总结下比较友好的环境搭配 使用ida热加载插件让你开发脚本更高效 github地址: GitHub - 0xeb/ida-qscripts: An IDA plugin to increase productivity when developi…

PyTorch: 基于【VGG16】处理MNIST数据集的图像分类任务【准确率98.9%+】

目录 引言在Conda虚拟环境下安装pytorch步骤一&#xff1a;利用代码自动下载mnist数据集步骤二&#xff1a;搭建基于VGG16的图像分类模型步骤三&#xff1a;训练模型步骤四&#xff1a;测试模型运行结果后续模型的优化和改进建议完整代码结束语 引言 在本博客中&#xff0c;小…

MySQL数据库卸载-Windows

目录 1. 停止MySQL服务 2. 卸载MySQL相关组件 3. 删除MySQL安装目录 4. 删除MySQL数据目录 5. 再次打开服务&#xff0c;查看是否有MySQL卸载残留 1. 停止MySQL服务 winR 打开运行&#xff0c;输入 services.msc 点击 "确定" 调出系统服务。 2. 卸载MySQL相关组…

国标级联/流媒体音视频平台EasyCVR设备录像下载异常该如何解决?

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c;也能支…

一、win10+yolov8+anaconda环境部署

1、安装anaconda &#xff08;1&#xff09;打开aonconda下载地址&#xff1a;https://www.anaconda.com/download&#xff0c;点击download下载。 2、下载完成后&#xff0c;双击打开&#xff0c;点击Next&#xff0c;I Agree&#xff0c;选择just me&#xff1b; 3、勾选…

SQL进阶理论篇(五):什么是Hash索引

文章目录 简介MySQL中的Hash索引与B树的区别总结参考文献 简介 hash&#xff0c;即哈希&#xff0c;也被称为是散列函数。 Hash在数据库中的应用&#xff0c;可以帮助我们大幅度提升检索数据的效率。 大名鼎鼎的MD5其实就是Hash函数的一种变体。 Hash算法&#xff0c;是通过…

ArkTS编译时遇到arkts-no-obj-literals-as-types错误【Bug已解决-鸿蒙】

文章目录 项目场景:问题描述原因分析:解决方案:解决方案1解决方案2此Bug解决方案总结项目场景: 在开发鸿蒙项目过程中,遇到了arkts-no-obj-literals-as-types,总结了自己和网上人的解决方案,故写下这篇文章。 遇到问题: rkTS编译时遇到arkts-no-obj-literals-as-type…

操作系统中的作业管理

从用户的角度看&#xff0c;作业是系统为完成一个用户的计算任务&#xff08;或一次事务处理&#xff09;所做的工作总和。例如&#xff0c;对于用户编制的源程序&#xff0c;需经过对源程序的编译、连接编辑或连接装入及运行产生计算结果。这其中的每一个步骤&#xff0c;常称…

解锁知识的新大门:自建知识付费小程序的技术指南

在数字化时代&#xff0c;知识付费小程序的崛起为创作者和学习者提供了全新的学习和分享方式。本文将以“知识付费小程序源码”为关键词&#xff0c;从技术角度出发&#xff0c;为你展示如何搭建一个独具特色的知识付费平台。 步骤1&#xff1a;选择适用的知识付费小程序源码…

知识库SEO:提升网站内容质量与搜索引擎排名的策略

随着搜索引擎算法的不断更新和优化&#xff0c;单纯依靠关键词堆砌和外部链接的时代已经过去。现在的SEO&#xff08;搜索引擎优化&#xff09;已经转向了以提供高质量、有价值内容为核心的阶段。知识库SEO便是这个新阶段的重要策略之一。 | 一、知识库SEO的概念与意义 1.定义…

《儿童绘本》期刊杂志发表论文投稿

《儿童绘本》杂志是由国家新闻出版管理部门批准&#xff0c;由吉林省舆林报刊发展有限责任公司主管主办&#xff0c;国内外公开发行的全国优秀期刊。办刊宗旨&#xff1a;以“普及绘本知识、推动儿童阅读”为理念&#xff0c;带动家庭亲子阅读&#xff0c;推动阅读教育及图画书…

一文解析数据结构是如何装入 CPU 寄存器的?

我们在之前很多文章的讲解中涉及了CPU与寄存器&#xff0c;然后有同学问了这样一个问题&#xff1a;既然CPU内部的寄存器数量有限&#xff0c;容量有限&#xff0c;那么我们使用的庞大的数据结构是怎样装入寄存器供CPU计算的呢&#xff1f;这篇文章就为你讲解一下这个问题。 内…

交叉销售与场景业务销售运营

交叉销售 交叉销售的定义 交叉销售是一种从横向角度开发产品市场的方式,是营销人员在完成本职工作以后,主动积极的向现有客户、市场等销售其他的、额外的产品或服务。 交叉销售的类型 补充销售 搭配销售个性化推荐奖励推荐 捆绑销售 交叉销售的意义 通过增加客户的转移成本…

VMP泄露编译的一些注意事项

VMP编译教程 鉴于VMP已经在GitHub上被大佬强制开源&#xff0c;特此出一期编译教程。各位熟悉的可以略过&#xff0c;不熟悉的可以参考一下。 环境&#xff08;软件&#xff09; Visual Studio 2015 - 2022 &#xff08;建议使用VS2019&#xff0c;Qt插件只有这个版本及以上…

企业信息建设现状

信息化建设是传统计算机与互联网技术高速发展并融合的产物&#xff0c;现阶段已经成为引领产业创新的决定性技术手段。 随着信息化的不断发展与进步&#xff0c;各行各业都开始了信息化的建设与应用。信息化是未来发展的大趋势&#xff0c;企业运用信息技术可以大幅度提高员工效…

【node】 地址标准化 解析手机号、姓名、行政区

地址标准化 解析手机号、姓名、行政区 实现效果链接源码 实现效果 将东光县科技园南路444号马晓姐13243214321 解析为 东光县科技园南路444号 13243214321 河北省;沧州市;东光县;东光镇 马晓姐 console.log(address, phone, divisions,name);链接 API概览 源码 https://gi…