Temporal Workflow 测试用例编写指南
Temporal Workflow 测试用例编写指南 引言 篇指南旨在为初次使用 Temporal 的开发者提供一个清晰、易懂的 Workflow 测试用例编写框架。Temporal 作为一个强大的工作流编排引擎,其测试框架也同样功能丰富。 为了循序渐进,本次我们先将重点放在 Workflow 的测试用例编写上,关于 Activity 的测试用例,我们将在下一篇文章中详细探讨。 Workflow 测试的两大核心 要成功运行一个 Workflow 测试用例,重点依赖于两个关键部分:测试环境初始化 和 Mock Activity。 1. 测试环境初始化 Temporal 提供了一个专用的测试框架,允许你在内存中执行 Workflow,而无需依赖真实的 Temporal 服务。这大大加快了测试速度并简化了环境配置。 一个典型的初始化过程如下: // 引入测试包 import ( "testing" "github.com/stretchr/testify/suite" "go.temporal.io/sdk/testsuite" ) // 定义测试套件 type MyWorkf...
Temporal Activity取消的最佳实践
Temporal Activity取消的最佳实践 背景 在Temporal工作流开发中,我们遇到了一个典型的取消延迟问题:当Workflow发送Cancel请求后,Activity并未立即终止,而是继续执行了多个周期后才退出。以下是核心场景复现: // Workflow func MyWorkflow(ctx workflow.Context) error { ao := workflow.ActivityOptions{ StartToCloseTimeout: 30 * time.Minute, HeartbeatTimeout: 3 * time.Minute, WaitForCancellation: true, } // ...忽略部分代码 // 添加一个定时器以在20秒后取消活动 selector.AddFuture(workflow.NewTimer(ctx, 20*time.Second), func(f workflow.Future) { cancel() logger.Info("A...
Go语言单元测试
Go语言单元测试 单元测试是保证项目质量、简化debug和验证代码功能的重要手段。在Go语言中,利用testing包可以方便地编写和执行单元测试,利用mockgen包可以模拟待测试函数的依赖对象。本教程将介绍如何在Go语言中写好单元测试,涵盖从基本测试到复杂场景的应用,并结合目前云游戏使用的主流框架kratos进行最佳实践。 testing 基础教程 1. 编写基本的单元测试 在Go语言中,每个测试文件以 _test.go 结尾,放置于与源代码相同的目录下。例如,有文件 calc.go,对应的测试文件应该命名为 calc_test.go。 测试用例名称一般命名为 Test 加上待测试的方法名 测试用的参数有且只有一个,在这里是 t *testing.T 示例:测试 Add 和 Mul 函数 假设 calc.go 的内容如下: package main func Add(a int, b int) int { return a + b } func Mul(a int, b int) int { return a * b ...
Redis 场景应用
在工作中,经常会遇到高并发的时候,众所周知我们可以用Redis来做缓存,缓解数据库压力。这里的高并发指的是多个请求同时请求数据库,导致数据库压力过大,造成崩溃。 缓存原则 使用Reids做缓存要遵从的原则有: 热点数据缓存,即对于访问频繁的数据可以加上缓存,一般数据遵从二八原则,即80%的流量在20%的热点数据之上 静态数据缓存,对于部分数据长时间不会变动的可以做缓存,比如系统设置、奖品设置等 如何做缓存 一般而言,缓存分为服务器端缓存,和客户端缓存。 服务器端缓存即服务端将数据存入Redis,可以在访问DB之后,将数据缓存,或者在回包时将回包内容以请求参数为Key缓存。 本文主要讨论服务端缓存,客户端缓存需要具体情况具体分析故不再讨论范围内。 缓存的几种模式 旁路由模式 读操作 当请求到达服务端时,会先从Redis检索是否存在数据,如果存在则直接返回,否则将 写操作 当请求到达服务端时,会先更新数据库数据,然后删除Redis缓存内容 为什么写操作要删除缓存而不是更新缓存? 因为为了保证数据的一致性,若更新缓存可能会出现以下情况: A请求更新数据库 -> B请求更新...
每日mysql
查询结果去重 第一种:使用distinct(关键词distinct用于返回唯一不同的值) select distinct university from user_profile; 第二种:使用group by按照university进行分组 select university from user_profile group by university; LIMIT 和 OFFSET LIMIT LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数 LIMIT 接受一个或两个数字参数。参数必须是一个整数常量 如果只给定一个参数,它表示返回最大的记录行数目 如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目 PS. 初始记录行的偏移量是 0(而不是 1) 检索记录行 6-10 SELECT * FROM table LIMIT 5,5 | | 偏移量 返回的最大数量 检索记录行 11-last SELECT * FROM table LIMIT 10,-1 检索前 5 个记录...
Python 内置方法
初始化 _init_:这玩意看似写着初始化,但是实际上本方法是在类实例化之后调用,用于初始化内部数据 _new_:这才是实例化时会调用的方法,也就是类最开始调用的方法~ eval Python中的eval()是一个非常有用的内置函数,它可以用来执行一个字符串表达式,并返回表达式的值。 eval()函数将字符串当成有效的表达式来求值并返回计算结果。也就是说,我们可以将一个字符串传递给eval(),然后该字符串会被当作Python表达式执行。 例如: >>> eval("1 + 2") 3 >>> x = 2 >>> eval("x + 3") 5 >>> eval("[1, 2, 3] + [4, 5]") [1, 2, 3, 4, 5] 在上面的例子中,传递给eval()的字符串被解释执行了。 eval()可以执行使用Python语法的任何表达式,包括数字、字符串、列表、字典等。但需要注意的是,使用eval()执行的语句应该是安全可信的,不能直接处理用户输入,因为那会存在安全隐患。 另外,python还有一个非常类似的函数exec(),它也可以执行字符串形式的pyth...
Python defaultdict方法
认识 当我使用普通的字典时,用法一般是dict={},添加元素的只需要dict[element] =value即,调用的时候也是如此,dict[element] = xxx,但前提是element字典里,如果不在字典里就会报错,如: 这时defaultdict就能排上用场了,defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值,这个默认值是什么呢,下面会说 如何使用 defaultdict接受一个工厂函数作为参数,如下来构造: dict = defaultdict(factory_function) 这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0,如下举例: from collections import defaultdict dict1 = defaultdict(int) dict2 = defaultdict(set) dict3 = defaultdi...
Python ABC模块(抽象类)
最近在学习编写Python,发现Python其实很灵活,下面是我遇到的一个知识点,用AI生成的,记下来。 abc模块是Python的一个内置模块,全称为abstract base classes。它提供了一种机制来定义抽象基类(abstract base classes, ABCs),这些抽象基类可以用来帮助我们正确地组织代码。 主要功能和用途: 定义抽象基类:通过abc.ABCMeta元类可以定义抽象基类,这个抽象基类不能被直接实例化,只能被继承。抽象基类中可以包含抽象方法(decorated by @abstractmethod),子类必须实现这些抽象方法。 检查子类:可以通过issubclass()和isinstance()来检查一个类是否是另一个类的子类或者实例。 注册虚拟子类:还可以通过abc.ABCMeta.register()来注册一个虚拟子类,这样就可以将不继承自该抽象基类的类也视为其子类。 ABCs的目的:避免依赖于特定接口的实现细节,只依赖于接口定义,从而实现面向接口编程。 常见用法示例: import abc class AbstractClassEx...
Python six模块
Python的six模块是为了编写同时兼容Python 2和3的代码而创建的。它的主要作用是: 提供跨Python 2和3版本的兼容性函数和类。 six模块中定义了常用函数、抽象类等,通过这些接口可以编写同时在Python 2和3下运行的代码。例如six.add_metaclass、six.StringIO、six.string_types等。 兼容不同版本的语法。 six提供了几个宏来将代码转换为不同版本的语法,如:six.u()等。 提供代理类实现向后兼容。 如six.moves模块给常用模块定义代理类,可以在2和3中使用相同的导入方式。 提供工具函数进行版本检查。 如six.PY2、six.PY3等可以判断当前的Python版本。 所以简单来说,通过使用six,可以减少代码中针对Python 2和3不同语法、API的特殊判断和转换,将兼容问题集中处理,使代码同时兼容Python 2和3变得简单。 six模块被广泛使用在需要同时兼容Python 2和3的项目代码中。随着Python 2逐渐退出历史舞台,这个模块的重要性也逐渐降低。但了解six对理解一些旧项目代...
Tree - Linux命令
tree是用于查看当前目录的项目结构,可以帮我们迅速了解当前目录的结构。 安装 mac下安装tree的命令: $ brew install tree 使用 $ tree -I ".tox|venv|python_demo.egg-info|__pycache__" . ├── LICENSE ├── MANIFEST.in ├── README.md ├── docs │ └── development.md ├── pyproject.toml ├── requirements.txt ├── setup.cfg ├── src │ └── strategy_sdk_python │ ├── __init__.py │ ├── cmdline.py │ ├── config │ │ ├── __init__.py │ │ └── settings.yml │ └── log.py ├── tests │ ├── __init__.py │ ├── conftest.py │ ├─...
