当前位置: 首页 > news >正文

网站建设源码下载网站开发人员 组织架构

网站建设源码下载,网站开发人员 组织架构,WordPress的MySQL宕,个人工作室注册流程及费用目录 基于现有的 context 创建新的 context 现有创建方法的问题 Go 1.21 中的 context.WithoutCancel 函数 Go 版本低于 1.21 该怎么办#xff1f; 在 Golang 中#xff0c;context 包提供了创建和管理上下文的功能。当需要基于现有的 context.Context 创建新的 context …目录 基于现有的 context 创建新的 context 现有创建方法的问题 Go 1.21 中的 context.WithoutCancel 函数 Go 版本低于 1.21 该怎么办 在 Golang 中context 包提供了创建和管理上下文的功能。当需要基于现有的 context.Context 创建新的 context 时通常是为了添加额外的控制信息或为了满足特定的生命周期需求。 基于现有的 context 创建新的 context 可以基于现有的 context.Context 创建一个新的 context对应的函数有 context.WithCancel、context.WithDeadline、context.WithTimeout 或 context.WithValue。这些函数会返回一个新的 context.Context 实例继承了原来 context 的行为并添加了新的行为或值。使用 context.WithValue 函数创建的简单示例代码如下 package mainimport contextfunc main() {// 假设已经有了一个context ctxctx : context.Background()// 可以通过context.WithValue创建一个新的contextkey : myKeyvalue : myValuenewCtx : context.WithValue(ctx, key, value)// 现在newCtx包含了原始ctx的所有数据加上新添加的键值对 } 使用 context.WithCancel 函数创建简单示例代码如下 package mainimport contextfunc main() {// 假设已经有了一个context ctxctx : context.Background()// 创建一个可取消的contextnewCtx, cancel : context.WithCancel(ctx)// 当完成了newCtx的使用可以调用cancel来取消它// 这将释放与该context相关的资源defer cancel() } 现有创建方法的问题 先说一个使用场景一个接口处理完基本的任务之后后续一些处理的任务放使用新开的 Goroutine 来处理这时候会基于当前的 context 创建一个 context可以使用上面提到的方法来创建 给 Goroutine 使用也不需要控制 Goroutine 的超时时间。 这种场景下Goroutine 的声明周期一般都会比这个接口的生命周期长这就会出现一个问题——当前接口请求所属的 Goroutine 退出后会导致 context 被 cancel进而导致新开的 Goroutine 中的 context 跟着被 cancel 从而导致程序异常。看一个示例 package mainimport (bytescontexterrorsfmtionet/httpgithub.com/gin-gonic/gin )func main() {r : gin.New()r.GET(/test, func(c *gin.Context) {// 父 context有使用取消功能ctx, cancel : context.WithCancel(c)defer cancel()// 创建子 context 给新开的 Goroutine 使用ctxCopy, _ : context.WithCancel(ctx)go func() {err : TestPost(ctxCopy)fmt.Println(err)}()})r.Run(:8080) }func TestPost(ctx context.Context) error {fmt.Println(goroutine...)buffer : bytes.NewBuffer([]byte({xxx:xxx}))request, err : http.NewRequest(POST, http://xxx.luduoxin.com/xxx, buffer)if err ! nil {return err}request.Header.Set(Content-Type, application/json)client : http.Client{}rsp, err : client.Do(request.WithContext(ctx))if err ! nil {return err}defer func() {_ rsp.Body.Close()}()if rsp.StatusCode ! http.StatusOK {return errors.New(response exception)}_, err io.ReadAll(rsp.Body)if err ! nil {return err}return nil } 运行代码在浏览器中访问 http://127.0.0.1:8080/test控制台会打印如下错误信息 goroutine... Post http://xxx.luduoxin.com/xxx: context canceled 可以看出因为父级 context 被 cancel导致子 context 也被 cancel从而导致程序异常。因此需要一种既能继承父 context 所有的 value 信息又能去除父级 context 的 cancel 机制的创建函数。 Go 1.21 中的 context.WithoutCancel 函数 这种函数该如何实现呢其实 Golang 从 1.21 版本开始为我们提供了这样一个函数就是 context 包中的 WithoutCancel 函数。源代码如下 func WithoutCancel(parent Context) Context {if parent nil {panic(cannot create context from nil parent)}return withoutCancelCtx{parent} }type withoutCancelCtx struct {c Context }func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {return }func (withoutCancelCtx) Done() -chan struct{} {return nil }func (withoutCancelCtx) Err() error {return nil }func (c withoutCancelCtx) Value(key any) any {return value(c, key) }func (c withoutCancelCtx) String() string {return contextName(c.c) .WithoutCancel } 原理其实很简单主要功能是创建一个新的 context 类型继承了父 context 的所有属性但重写了 Deadline、Done、Err、Value 几个方法当父 context 被取消时不会触发任何操作。 Go 版本低于 1.21 该怎么办 如果 Go 版本低于 1.21 其实也很好办按照 Go 1.21 中的实现方式自己实现一个就可以了代码可以进一步精简示例代码如下 func WithoutCancel(parent Context) Context {if parent nil {panic(cannot create context from nil parent)}return withoutCancelCtx{parent} }type withoutCancelCtx struct {context.Context }func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {return }func (withoutCancelCtx) Done() -chan struct{} {return nil }func (withoutCancelCtx) Err() error {return nil } 使用自己实现的这个版本再跑一下之前的示例代码如下 package mainimport (bytescontexterrorsfmtionet/httptimegithub.com/gin-gonic/gin )func main() {r : gin.New()r.GET(/test, func(c *gin.Context) {// 父 context有使用取消功能ctx, cancel : context.WithCancel(c)defer cancel()// 创建子 context 给新开的 Goroutine 使用ctxCopy : WithoutCancel(ctx)go func() {err : TestPost(ctxCopy)fmt.Println(err)}()})r.Run(:8080) }func WithoutCancel(parent Context) Context {if parent nil {panic(cannot create context from nil parent)}return withoutCancelCtx{parent} }type withoutCancelCtx struct {context.Context }func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {return }func (withoutCancelCtx) Done() -chan struct{} {return nil }func (withoutCancelCtx) Err() error {return nil }func TestPost(ctx context.Context) error {fmt.Println(goroutine...)buffer : bytes.NewBuffer([]byte({xxx:xxx}))request, err : http.NewRequest(POST, http://xxx.luduoxin.com/xxx, buffer)if err ! nil {return err}request.Header.Set(Content-Type, application/json)client : http.Client{}rsp, err : client.Do(request.WithContext(ctx))if err ! nil {return err}defer func() {_ rsp.Body.Close()}()if rsp.StatusCode ! http.StatusOK {return errors.New(response exception)}_, err io.ReadAll(rsp.Body)if err ! nil {return err}return nil }type Context interface {Deadline() (deadline time.Time, ok bool)Done() -chan struct{}Err() errorValue(key any) any } 运行代码在浏览器中访问 http://127.0.0.1:8080/test发现不再报父 context 被 cancel 导致的报错了。
http://www.yayakq.cn/news/1936/

相关文章:

  • 网络服务器搭建与配置济南做网站优化的公司
  • 公司网站打不开怎么办可以做任务的网站有哪些
  • 有哪些做ppt网站手把手教你实现电商网站开发
  • 网站购物车实现临沂市建设安全管理网站
  • 长春网站制作可选吉网传媒好制作网线的基本步骤
  • 浙江建设职业技术学院招生网站用jsp做网站一般会用到什么软件
  • 网站主页的布局方式云南大学网站建设
  • 自己主机做多个网站wordpress 游戏插件
  • 厦门市住宅建设办公室网站中国建设职业注册中心网站
  • 如何建设内部网站网站数据比较
  • c 手机网站开发模板宣传片拍摄制作公司报价明细
  • 网站建设服务费的摊销期限东莞做商城网站建设
  • 深圳制作网站制作wordpress链接调用
  • 用asp做网站有哪控件动漫网站设计与实现
  • 廊坊高端模板建站wordpress输出到模板
  • 江西雄基建设网站海外网文
  • 织梦网站怎么做优化网站设计合理
  • 网站建设的成功经验信息图表网站
  • 做淘宝美工图片网站吉林市百姓网免费发布信息网
  • 公司网站设计与实现网站建设 开办费
  • 做网站链接还要服务器吗买怎么发布网站
  • 创立一个网站要多少钱建设局哪个网站查证
  • 如何自己建站网站制作网站备案名称几个字
  • sql做网站经典品牌推广文案
  • 网站开发交付验收文档wordpress如何注册地址
  • 电视台网站策划书全网营销新胜天下
  • 为什么要建设应急管理网站中国科技成就2021
  • 网站视频播放器用什么做的成都网站建设案例单招网
  • 丽江旅游网站建设网站仿造
  • 网站规划建设实训报告界面交互设计