Temporal Activity取消的最佳实践
Temporal Activity取消的最佳实践背景在Temporal工作流开发中,我们遇到了一个典型的取消延迟问题:当Workflow发送Cancel请求后,Activity并未立即终止,而是继续执行了多个周期后才退出。以下是核心场景复现:
123456789101112131415161718192021222324252627282930313233343536373839404142434445// Workflowfunc 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. ...
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 的内容如下:
123456789package mainfunc 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请求更新数据库 -&g ...
每日mysql
查询结果去重第一种:使用distinct(关键词distinct用于返回唯一不同的值)1select distinct university from user_profile;
第二种:使用group by按照university进行分组1select university from user_profile group by university;
LIMIT 和 OFFSETLIMITLIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数
LIMIT 接受一个或两个数字参数。参数必须是一个整数常量
如果只给定一个参数,它表示返回最大的记录行数目
如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目
PS. 初始记录行的偏移量是 0(而不是 1)
检索记录行 6-10
123SELECT * FROM table LIMIT 5,5 | | 偏移量 返回的最大数量
检索记录行 11-last
1SELECT * FROM table LIMIT 10,-1
检索前 5 个记录 ...
Python 内置方法
初始化
**_init_**:这玩意看似写着初始化,但是实际上本方法是在类实例化之后调用,用于初始化内部数据
**_new_**:这才是实例化时会调用的方法,也就是类最开始调用的方法~
evalPython中的eval()是一个非常有用的内置函数,它可以用来执行一个字符串表达式,并返回表达式的值。
eval()函数将字符串当成有效的表达式来求值并返回计算结果。也就是说,我们可以将一个字符串传递给eval(),然后该字符串会被当作Python表达式执行。
例如:
123456789>>> 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 defaultdict方法
认识当我使用普通的字典时,用法一般是dict={},添加元素的只需要dict[element] =value即,调用的时候也是如此,dict[element] = xxx,但前提是element字典里,如果不在字典里就会报错,如:
这时defaultdict就能排上用场了,defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值,这个默认值是什么呢,下面会说
如何使用defaultdict接受一个工厂函数作为参数,如下来构造:
1dict = defaultdict(factory_function)
这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0,如下举例:
123456789101112from collections import defaultdictdict1 = defaultdict(int)dict2 = defaultdict(set ...
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的目的:避免依赖于特定接口的实现细节,只依赖于接口定义,从而实现面向接口编程。
常见用法示例:
123456789101112import abcclass Abstr ...
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的命令:
1$ brew install tree
使用1234567891011121314151617181920212223242526$ 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_ ...
Nginx过滤带有下划线('_')的请求头
在最近开发中遇到一个问题,记录一下。
发现问题有一个http请求,需要携带一个请求头Header,当时定义的请求头使用的下划线模式,header_name这样。然后神奇的事情就发生了。
我自己在本机运行代码,在ApiFox上测试没问题,后端能正常接收并响应。
当部署到服务器后,使用域名或者ip访问接口路径,这时候后端就接收不到前端塞的请求头了。
排查问题排查了好久,其中当尝试换成其他的请求头,发现只有携带下划线(_)才接收不到,换成 - 短横就可以了。
研究参考搜了一下,发现原来是nginx的问题。ngixn默认不支持下划线的header,带下划线的header会被丢弃。
所以一开始自己ApiFox测试是因为直接请求的本地运行的代码,没有经过nginx,所以能正常接收。但后面都是使用域名经过nginx转发,导致带下划线的header丢失。
Nginx默认不支持带有下划线的Header字段,这是由于历史原因。在早期的互联网规范中,HTTP Header字段名中并不允许使用下划线。因此,为了遵守这些规范并防止可能的冲突,Nginx在处理Headers时默认会丢弃任何带有下划线的Heade ...