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

怎么用wordpress建电商网站吗国外网站如何搭建网页

怎么用wordpress建电商网站吗,国外网站如何搭建网页,如何做网络营销推广唯选一 诺,网站建设推广服务合同范本目录 基于现有的 context 创建新的 context 现有创建方法的问题 Go 1.21 中的 context.WithoutCancel 函数 Go 版本低于 1.21 该怎么办? 在 Golang 中,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 "context"func main() {// 假设已经有了一个context ctxctx := context.Background()// 可以通过context.WithValue创建一个新的contextkey := "myKey"value := "myValue"newCtx := context.WithValue(ctx, key, value)// 现在newCtx包含了原始ctx的所有数据,加上新添加的键值对
}

使用 context.WithCancel 函数创建,简单示例代码如下:

package mainimport "context"func 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 ("bytes""context""errors""fmt""io""net/http""github.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 ("bytes""context""errors""fmt""io""net/http""time""github.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/662189/

相关文章:

  • 怎么关闭自己公司网站眉山做网站
  • 网站空间不足公司加盟代理
  • 网站源码下载以营销推广为主题的方案
  • 西部数码网站管理助手自己如何做网站关键词排名
  • 使用c 语言建设网站优点微信小程序是干什么用的
  • 深圳做微信网站制作网站链接可以自己做吗
  • 网站定制需求变装小说wordpress
  • 三网合一网站建设合同h5游戏大厅
  • 外网如何查看局域网建设的网站网络推广方案ppt
  • 二手房在哪个网站做合同建设银行余额明细查询
  • 网站宽度 自动收缩为什么明明有网却打不开网页
  • 免费网站建设网站优化软件山西seo博客
  • 网站开发遇到的难点做包子网站
  • 网站1g空间多少钱江西建站哪家专业
  • 注册360建筑网平台百度seo优化公司
  • 网站建设公众号开发网页设计与制作考试
  • 专业网站设计公司和普通设计公司的区别c 教程如何做网站
  • 关于建立网站的计划做企业网站备案都需要什么
  • 如何用php数据库做网站多语言网站建设应注意哪些事项
  • tornado做网站开发一个小程序
  • 大千科技网站建设高校网络架构
  • 怎么把网站上的通栏手机建站系统
  • 我是做网站怎么赚钱资源链接搜索引擎
  • 网站建设方案案例wordpress 任务
  • 阳朔县建设规划局网站微信app小程序
  • 旅游网站模板免费下载福建省建设注册中心网站
  • 品牌网站建设小科6a蚪济南百度爱采购
  • 网站建设相关制度内部网站做域名解析到端口
  • 织梦网站安装dir企业推广网站建设报价
  • 高端模板建站怎样在电脑登录wordpress