go的实践

文章目录

  • 用goroutine来替代mq做异步的应用
    • 心跳
    • contenx的超时设置
    • 定时器
    • break label
    • 核心代码

用goroutine来替代mq做异步的应用

方法在创建ai任务接口中用协程的方式异步调用go s.handleResultPolling(ctx, algorithm, taskId, iAiHandle),来更新ai任务的状态

心跳

心跳机制是一种用于检测连接或任务是否仍处于活动状态的方法。在分布式系统或网络通信中,心跳机制可以用来监视节点和服务的可用性、性能和故障。心跳通常是通过定期发送小的数据包或信号来实现的,然后接收方会对这些信号进行响应,以表示它们仍然在线并正常运行。
在这段代码中,心跳机制用于监控AI任务的进行情况。每隔2秒,会将当前时间戳写入Redis缓存,作为心跳信号。这样,外部监控系统可以检查Redis缓存中的心跳信号来判断任务是否仍在进行。如果在一定时间内没有收到新的心跳信号,那么可以认为任务已经中止或出现故障。

contenx的超时设置

context没有默认的超时时间,如果要设置超时时间的话,记得调用

ctxTimeout, timeoutCancel := context.WithTimeout(ctx, time.Hour)
defer timeoutCancel() // 操作完成时立即释放资源

定时器

在这段代码中,time.NewTicker(time.Millisecond)创建的定时器最初每隔1毫秒触发一次,ticker.Reset(time.Second * 2)的作用是重置定时器(ticker)的时间间隔为2s,这样能每2s从通道中取到信息case <-ticker.C:

break label

breakFor是一个标签,它用于在嵌套循环或选择语句中提供更精确的控制。在这个例子中,breakFor标签用于跳出外层的for循环。 在Go语言中,break语句默认只跳出当前层次的循环或选择语句。在这个例子中,当ctxTimeout.Done()通道接收到一个值或者满足其他条件时,我们希望跳出整个for循环,而不仅仅是select语句。通过在for循环前添加breakFor标签,并在break`语句中指定该标签,我们可以实现这个功能。

核心代码

// handleCreateAsync 启动协程处理结果
func (s *aiHandle) handleCreateAsync(ctx context.Context, algorithm string, taskId string, data interface{}, iAiHandle IAiHandle) {// 上报神策properties := map[string]interface{}{"uid": util.GetCtx(ctx).User.WsId,"alg": algorithm,}sensorsdata.Track(gtrace.GetTraceID(ctx), "SeAlgCreate", properties, util.GetCtx(ctx).User.WsId != "", "")// 创建任务s.createDbSave(ctx, taskId, algorithm, data)// 任务数量+1s.handleCreateActive(ctx, algorithm, true)// 异步处理结果go s.handleResultPolling(ctx, algorithm, taskId, iAiHandle)
}
// handleCreateAsync 启动协程处理结果
func (s *aiHandle) handleCreateAsync(ctx context.Context, algorithm string, taskId string, data interface{}, iAiHandle IAiHandle) {// 上报神策properties := map[string]interface{}{"uid": util.GetCtx(ctx).User.WsId,"alg": algorithm,}sensorsdata.Track(gtrace.GetTraceID(ctx), "SeAlgCreate", properties, util.GetCtx(ctx).User.WsId != "", "")// 创建任务s.createDbSave(ctx, taskId, algorithm, data)// 任务数量+1s.handleCreateActive(ctx, algorithm, true)// 异步处理结果go s.handleResultPolling(ctx, algorithm, taskId, iAiHandle)
}// handleResultPolling 轮询结果
func (s *aiHandle) handleResultPolling(ctx context.Context, algorithm, taskId string, iAiHandle IAiHandle) {// 60分钟超时// 1. 首先,设置一个60分钟的超时上下文,确保处理不会无限期地进行下去。ctxTimeout, timeoutCancel := context.WithTimeout(ctx, time.Hour)defer timeoutCancel() // 超时前调用这个,用来释放资源;不调用这个方法的话,会在超时时间释放资源// 2. 创建一个心跳goroutine,每隔2秒更新一次心跳缓存。这样可以在外部监控任务的进行情况。// 启动心跳,2秒一次go func(ctx context.Context, taskId string) {ticker := time.NewTicker(time.Millisecond)defer ticker.Stop()heartbeatKey := aiCache.GetAiTaskHeartBeat(taskId)for {select {case <-ctx.Done():returncase <-ticker.C:ticker.Reset(time.Second * 2)if cache.RedisExists(ctx, heartbeatKey) == false {_ = cache.RedisSet(ctx, heartbeatKey, time.Now().Unix(), time.Hour*24)}_ = cache.RedisIncBy(ctx, heartbeatKey, 2)}}}(ctxTimeout, taskId)// 3. 初始化任务结果的状态和数据变量。// 任务结果taskEnd := falsetaskStatus := consts.TaskStatusProcessingtaskMsg := ""var taskData any// 4. 设置一个定时器,每隔3秒执行一次轮询查询结果。// 每3秒重试一次step := time.NewTimer(time.Millisecond)defer step.Stop()// 查询失败时,重试5次retry := 1//5. 使用`breakFor`标签和`select`语句进行轮询操作,当超时或查询到结果时跳出循环。//- 调用`iAiHandle.ResultHandle`方法查询任务结果。//- 如果查询失败,重试5次。//- 如果任务状态不是处理中或等待中,则更新任务状态和数据,设置`taskEnd`为`true`,跳出循环。// 轮询结果
breakFor:for {select {case <-ctxTimeout.Done():break breakForcase <-step.C:step.Reset(time.Second * 3)// 查结果taskResult, err := iAiHandle.ResultHandle(ctx, &v1.ResultReq{Algorithm: algorithm,TaskId:    taskId,})taskData = taskResultif err != nil {if retry > 5 {taskStatus = consts.TaskStatusServerFailtaskMsg = "handle result err retry than 5 times"break breakFor}retry++} else {// 状态不一致则返回if taskResult != nil && taskResult.Status != consts.TaskStatusProcessing && taskResult.Status != consts.TaskStatusWaiting {taskStatus = taskResult.StatustaskMsg = taskResult.ReasontaskEnd = truebreak breakFor}}}}// 程序处理超时if taskEnd == false {taskStatus = consts.TaskStatusServerOutTimetaskMsg = "handle result than 60 minutes"}// 7. 更新任务计数器。// 任务数量-1s.handleCreateActive(ctx, algorithm, false)// 8. 保存任务结果到数据库。// 更数任务s.resultDbSave(ctx, taskId, taskStatus, taskMsg, taskData)}

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

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

相关文章

Python如何调用rar命令

通过os模块的system()方法调用了系统的rar.exe命令&#xff0c;这个方法会返回一个变量exit_status。 import os import time source [r‘D:\Work\Python\Demo‘, ‘d:\\work\\linux‘] target_dir ‘D:\\Work\\backup\\‘ target target_dir time.strftime(‘%Y%m%d%H%M%S…

Flutter第十弹 ScrollView滚动组件

目标&#xff1a; 1&#xff09;滚动组件的特性&#xff1f; 2&#xff09;有哪些常用的滚动组件&#xff1f; 一、基础滚动组件 Flutter有许多内置的小部件可以自动滚动&#xff0c;还提供了各种小部件&#xff0c;您可以自定义这些小部件来创建特定的滚动行为。 1.1 Scr…

【单元测试】Junit 4--junit4 内置Rule

1.0 Rules ​ Rules允许非常灵活地添加或重新定义一个测试类中每个测试方法的行为。测试人员可以重复使用或扩展下面提供的Rules之一&#xff0c;或编写自己的Rules。 1.1 TestName ​ TestName Rule使当前的测试名称在测试方法中可用。用于在测试执行过程中获取测试方法名称…

深入理解汇编:平栈、CALL和RET指令详解

​视频学习下载地址&#xff1a;​​https://pan.quark.cn/s/04e6946a803a​​ 汇编语言以其接近硬件的特性和高效的执行速度&#xff0c;在系统编程、性能优化和逆向工程中占有不可或缺的地位。本文将深入探讨汇编语言中的平栈操作以及​​CALL​​​和​​RET​​指令&#…

计算机网络实验实验之VLAN的配置与分析

实验目的 了解什么是带内管理&#xff1b;熟练掌握如何使用telnet方式管理交换机&#xff1b;熟练掌握如何为交换机设置web方式管理&#xff1b;熟练掌握如何进入交换机web管理方式&#xff1b;了解交换机web配置界面&#xff0c;并能进行部分操作。 (6)了解VLAN原理&#xf…

如何理解泛型擦除机制的兼容性

让我们通过一个具体的例子来更好地理解泛型擦除机制的第一个优点&#xff0c;即确保向后兼容性。这个例子将展示在引入泛型之前和之后的代码是如何在同一Java虚拟机上运行的。 场景设置 假设在Java 5引入泛型之前&#xff0c;我们有一个处理字符串列表的Java类库。这个库在Ja…

Linux 使用用户级别的 systemd 服务

目录 使用用户级别的 systemd 服务示例 .service 文件内容然后执行以下命令使服务生效&#xff1a; 使用用户级别的 systemd 服务 可以创建一个用户级别的 systemd 服务来实现开机启动。这种方式更加灵活和规范&#xff0c;适用于需要长期运行的服务或后台任务。 创建一个 .s…

不敢说懂你 - Glide硬核源码剖析

问题 Glide加载流程? Glide整体架构? Glide数据加载的来源? Glide缓存加载的流程? Glide线程切换原理? Glide如何感知Activity? Glide哪种情况会返回应用级的RequestManager? … 带着一些问题去阅读… 使用示例 本篇主要基于glide:4.12.0进行分析。下面是Gli…

● Queryable State实现原理与配置方法

Queryable State 是 Apache Flink 提供的一个特性&#xff0c;它允许外部系统查询 Flink 作业的状态。这是通过将 Flink 的状态暴露为一个可查询接口来实现的&#xff0c;使得外部应用可以直接访问和查询 Flink 中的状态数据&#xff0c;而不需要触发整个 Flink 作业的计算。 …

浏览器原理之浏览器机制

事件机制 一 事件是什么&#xff1f;事件模型&#xff1f; 事件 是浏览器或用户自身发出的某种特定交互的信号。这包括但不限于鼠标点击、按键操作、页面加载、滚动等。 事件模型 主要包括三个阶段&#xff1a; 捕获阶段&#xff1a;事件从文档根节点向下传递到目标节点&am…

PyQt6实战7--文本编辑器

一个简单的文本编辑器 features: 1.open 一个文件夹作为项目 2.save 保存当前窗口的内容 3.退出 4.双击文件可以打开文件内容 5.简单的python高亮 6.双击相同文件&#xff0c;会找到之前打开过的文件 打开一个文件夹 打开项目&#xff0c;双击打开文件 保存 代码&#xf…

雷电模拟器+python

import os import time from compare import compare #上一段代码我存为了compare.pyclass Ldconsole: #请根据自己软件的路径来console rF:\leidian\LDPlayer9\dnconsole.exe ld rF:\leidian\LDPlayer9\ld.exeadb rF:\leidian\LDPlayer9\adb.exe #这个类其实不用写的&…

CSRF漏洞

文章目录 目录 文章目录 一.什么是CSRF 二.CSRF漏洞工作原理 一.什么是CSRF CSRF&#xff08;Cross-Site Request Forgery&#xff09;漏洞&#xff0c;也被称为跨站请求伪造漏洞&#xff0c;是一种Web应用程序安全漏洞。当受害者在已经登录了某个网站的情况下&#xff0c;访问…

密码学 | 数字签名方法:Schnorr 签名

⚠️原文&#xff1a;Introduction to Schnorr Signatures ⚠️写在前面&#xff1a;适用于有一点密码学基础的亲故&#xff0c;否则建议跑路。 1 Schnorr 签名的定义 假设你有密钥对 ( x , X x ∗ G ) ( x, X x * G ) (x,Xx∗G)&#xff0c;那么消息 m m m 的 Schnor…

吴恩达机器学习笔记 三十五 异常检测与监督学习

什么时候选择异常检测&#xff1f; 正样本 ( y 1 ) 的数量非常少 负样本 ( y 0 ) 的数量非常多 有很多不同的异常&#xff0c;现有的算法不能从正样本中得知什么是异常&#xff0c;或未来可能出现完全没见过的异常情况。 例如金融欺诈&#xff0c;隔几个月或几年就有新的…

java+idea+mysql采用医疗AI自然语言处理技术的3D智能导诊导系统源码

javaideamysql采用医疗AI自然语言处理技术的3D智能导诊导系统源码 随着人工智能技术的快速发展&#xff0c;语音识别与自然语言理解技术的成熟应用&#xff0c;基于人工智能的智能导诊导医逐渐出现在患者的生活视角中&#xff0c;智能导诊系统应用到医院就医场景中&#xff0c…

jvm-接口调用排查

问题描述 线上碰到个问题&#xff0c;某个接口调用时间特别长&#xff0c;线上调用接口直接报gateway time out 分析处理 1、先关闭该功能 &#xff08;该功能是非核心功能&#xff09; 2、本地起服务连环境排查&#xff0c;发现本地正常。并且线上其他接口正常&#xff0c;…

机器学习笔记——浅析L2,1范数正则化的线性回归

前言 嘻嘻&#xff0c;刚开始搓逾期了快两周的线性回归实验报告&#xff0c;为了让报告稍微不那么平淡不得不啃论文。 本文从最基本的线性回归开始&#xff0c;对比不同正则化方法的特点和作用&#xff0c;推广到多任务问题并引出L2,1范数正则化&#xff0c;卑微小采购尝试去…

顺序表复习(C语言版)

数据结构是什么&#xff1f; 数据结构就是为了把数据管理起来&#xff0c;方便我们的增删查改 数据结构是计算机存储、组织数据的方式 数组就是一种最基础的数据结构 顺序表是什么&#xff1f; 顺序表就是数组 Int arr[100] {1,2,3,4,5,x,……} 修改某个数据&#xff1a…

【leetcode面试经典150题】56. 基本计算器(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…