Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

session access has a certain probability of not getting the value #2772

Closed
famiou opened this issue Jul 17, 2023 · 16 comments
Closed

session access has a certain probability of not getting the value #2772

famiou opened this issue Jul 17, 2023 · 16 comments
Labels
cannot reproduce We cannot reproduce it, it might resolved in new version or you should give more details.

Comments

@famiou
Copy link

famiou commented Jul 17, 2023

1. What version of Go and system type/arch are you using?

go version go1.20.2 windows/amd64

2. What version of GoFrame are you using?

require github.com/gogf/gf/v2 v2.3.1

3. Can this issue be re-produced with the latest release?

yes

4. What did you do?

package cmd

import (
	"context"

	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gcmd"

	"gf/internal/controller"
)

var (
	Main = gcmd.Command{
		Name:  "main",
		Usage: "main",
		Brief: "start http server",
		Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {

			s := g.Server()
			s.Group("/", func(group *ghttp.RouterGroup) {
				group.Middleware(ghttp.MiddlewareHandlerResponse)
				group.Bind(
					controller.Hello,
				)
				group.GET("/set", func(r *ghttp.Request) {
					r.Session.SetId("test")
					err := r.Session.Set("abc", "123")
					r.Response.WriteJson(g.Map{
						"err": err,
					})
				})
				group.GET("/get", func(r *ghttp.Request) {
					for i := 0; i < 10; i++ {
						ctx := context.Background()
						go func() {
							for {
								res := g.Client().GetContent(ctx, "http://127.0.0.1:8005/get")
								j := gjson.New(res)
								if j.Get("abc").IsEmpty() {
									panic("abc error")
								}
								g.Log().Info(ctx, "res===", res)
							}
						}()
					}
					r.Session.SetId("test")
					r.Response.WriteJson(g.Map{
						"abc": r.Session.MustGet("abc"),
					})
				})
			})
			s.Run()
			return nil
		},
	}
)

5. What did you expect to see?

首先运行 gf run main.go 让程序跑起来
http://127.0.0.1:8005/set 浏览器打开链接,设置session
然后运行http://127.0.0.1:8005/get ,后台跑程序,取不到值的时候会报错
获取session的时候有一定机率获取不到值
image

6. What did you see instead?

应该是每一次都能看到值

@Issues-translate-bot Issues-translate-bot changed the title session访问有一定机率取不到值 session access has a certain probability of not getting the value Jul 17, 2023
@famiou
Copy link
Author

famiou commented Jul 19, 2023

@gqcn 这个问题解决吗?

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@gqcn Is this problem solved?

@windvalley
Copy link
Contributor

@gqcn 这个问题解决吗?

@famiou 这个看上去是你写的测试代码有问题,/get接口写成递归,而且for还是死循环,系统资源最终会被耗尽,导致代码中的g.Client().GetContent这里请求/get失败,所以获取不到结果,就到了你的panic代码处了。我未实际测试,看代码推测的,仅供参考~

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@gqcn Is this problem solved?

@famiou It seems that there is a problem with the test code you wrote. The /get interface is written recursively, and the for is still an infinite loop. System resources will eventually be exhausted, causing g.Client().GetContent in the code to request /get to fail , so if you can’t get the result, you’re at your panic code. I haven't actually tested it, just speculated from the code, it's just for reference~

@famiou
Copy link
Author

famiou commented Jul 20, 2023

这个应该不是资源耗尽,我项目中的请求没有这么频繁也会出现这种情况,偶尔有个接口就是获取不到值,这是我单独拿出来的一个请求示例代码,刚开始获取没有问题,但后面请求报错多了就会出现

var (
	getCmd = &gcmd.Command{
		Name:  "get",
		Usage: "get",
		Brief: "start http server",
		Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
			for i := 0; i < 10; i++ {
				ctx := context.Background()
				go func() {
					for {
						res := g.Client().GetContent(ctx, "http://127.0.0.1:8005/get")
						j := gjson.New(res)
						if j.Get("abc").IsEmpty() {
							g.Log().Warning(ctx, "abc error")
						} else {
							g.Log().Info(ctx, "res===", res)
						}
						time.Sleep(time.Millisecond * 10)
					}
				}()
			}
			select {}
			return nil
		},
	}
)

image

@windvalley
Copy link
Contributor

@famiou

你的/get接口代码:

group.GET("/get", func(r *ghttp.Request) {
					for i := 0; i < 10; i++ {
						ctx := context.Background()
						go func() {
							for {
								res := g.Client().GetContent(ctx, "http://127.0.0.1:8005/get")
								j := gjson.New(res)
								if j.Get("abc").IsEmpty() {
									panic("abc error")
								}
								g.Log().Info(ctx, "res===", res)
							}
						}()
					}
					r.Session.SetId("test")
					r.Response.WriteJson(g.Map{
						"abc": r.Session.MustGet("abc"),
					})
				})

是否去掉了下面这段?

for i := 0; i < 10; i++ {
						ctx := context.Background()
						go func() {
							for {
								res := g.Client().GetContent(ctx, "http://127.0.0.1:8005/get")
								j := gjson.New(res)
								if j.Get("abc").IsEmpty() {
									panic("abc error")
								}
								g.Log().Info(ctx, "res===", res)
							}
						}()
					}

@famiou
Copy link
Author

famiou commented Jul 20, 2023

@windvalley 去掉了

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@windvalley removed

@windvalley
Copy link
Contributor

@famiou 如果去掉了, 我测是没问题的, 跑了5分钟了也没出错.

建议你把res := g.Client().GetContent(ctx, "http://127.0.0.1:8005/get") 这行改成:

								res, err := g.Client().Get(ctx, "http://127.0.0.1:8005/get")
								if err != nil {
									g.Log().Errorf(ctx, "res: %+v, error: %v", res, err)
									continue
								}

看看究竟报的什么错误

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


If @famiou is removed, I tested that there is no problem, and there is no error after running for 5 minutes.

It is recommended that you change the line res := g.Client().GetContent(ctx, "http://127.0.0.1:8005/get") to:

res, err := g.Client().Get(ctx, "http://127.0.0.1:8005/get")
if err != nil {
g.Log().Errorf(ctx, "res: %+v, error: %v", res, err)
continue
}

See what error is reported

@famiou
Copy link
Author

famiou commented Jul 20, 2023

@windvalley 报错如下

2023-07-20 12:56:01.811 [ERRO] res: &{Response:<nil> request:0xc0000b2200 requestBody:[] cookies:map[]}, error: request failed: Get "http://127.0.0.1:8005/get": dial tcp 127.0.0.1:8005: connectex: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Stack:
1.  gf/internal/cmd.glob..func2.1
    D:/project/test/gf/internal/cmd/get.go:24

@windvalley
Copy link
Contributor

@famiou 看报错很明显了, 这是客户端socket错误, 和服务端没啥关系, 具体可以google一下

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@famiou It is obvious that the error is reported. This is a client socket error and has nothing to do with the server. You can google it for details

@famiou
Copy link
Author

famiou commented Jul 22, 2023

@windvalley 我找到我获取不到session的原因了,在一次请求中,如果我去更新session,然后再下次请求有可能获取不到session的数据

group.Middleware(func(r *ghttp.Request) {
	r.Session.SetId(r.Get("token").String())
	size, err := r.Session.Size()
	r.Session.Set("abc", guid.S())
	g.Log().Info(r.GetCtx(), r.URL.Path, "session id:", r.Get("token").String(), "size:", size, err)
	r.Middleware.Next()
})

image

@gqcn
Copy link
Member

gqcn commented Sep 25, 2023

@famiou 你好,我没有复现这个问题。请使用最新版本再试试,如果问题依旧请将最小可复现的完整代码,提交新的issue我运行试试。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@famiou Hello, I have not reproduced this problem. Please use the latest version and try again. If the problem persists, please submit the smallest reproducible complete code to issue and I will try it.

@gqcn gqcn added the cannot reproduce We cannot reproduce it, it might resolved in new version or you should give more details. label Sep 25, 2023
@gqcn gqcn closed this as completed Sep 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cannot reproduce We cannot reproduce it, it might resolved in new version or you should give more details.
Projects
None yet
Development

No branches or pull requests

4 participants