• With issues: I have already checked the issues and could not find this in current issues.

Description

I have a saas project which is based upon Rest APIs. All apis are developed in GO using gin package. When the user logs in then I set current user details in the request context so that I can access these details furthere to display some data. However I had a case in which 2 requests hits in parallel & the context values for the 1st request are override with the context values in the 2nd request. Due to this, my data is displaying wrong.

How to reproduce

package main

import (
    "github.com/gin-gonic/gin"
        "fmt"
)

func main() {
    g := gin.Default()
    g.GET("/hello/:name", hello)
    g.Run(":9000")
}

func hello(c *gin.Context) {
                c.Keys = make(map[string]interface{})
                c.Keys["current_user_id"] = 10
                c.Keys["current_user_name"] = c.Param("name")
                fmt.Println(c.Keys)
        c.String(200, "Hello %s", c.Param("name"))
}

This issues is not produced every time for parallel requests.

Expectations

It should not override the values.

Environment

  • go version: 1.19
  • gin version (or commit ref): 1.8.1
  • operating system: Ubuntu

Comment From: MikeJackOne

Can't reproduce with the code you provide,can you give me more detail?

Comment From: MikeJackOne

Can you share more detailed code of the problem you encounter?

Comment From: MikeJackOne

Actually you should use following method to set a key to a map. c.Set("current_user_id",10)

Comment From: MikeJackOne

I check the source code and c.Keys is not automaticly initialized before use, So I suspect the code you provide would panic. You should use c.Set("current_user_id",10) as a way of setting value. It will handle initialization and lock for you.

Comment From: amankaur27

I have updated the code. I have initialized the keys before assigning some value to it

Comment From: amankaur27

Is assigning values like I provided & using c.Set() is behaviorally different ?

Comment From: MikeJackOne

I have updated the code. I have initialized the keys before assigning some value to it

you shouldn't use this way.

Comment From: MikeJackOne

use it this way, `package main

import ( "fmt"

"github.com/gin-gonic/gin"

)

func main() { g := gin.Default() g.GET("/hello/:name", hello) g.Run(":9000") }

func hello(c *gin.Context) { //c.Keys = make(map[string]any) c.Set("current_user_id", 10) c.Set("current_user_name", c.Param("name")) fmt.Println(c.Keys) c.String(200, "Hello %s", c.Param("name")) } `

Comment From: amankaur27

Whats the difference between two ?

Comment From: MikeJackOne

Is assigning values like I provided & using c.Set() is behaviorally different ?

yes, it handle initialization and lock for you, I think multiple goroutine changing the map cause the issue you encounter.

Comment From: MikeJackOne

Whats the difference between two ?

This is how Set is defined. it's pretty straightforwad and it answers you questions.

`func (c *Context) Set(key string, value any) { c.mu.Lock() if c.Keys == nil { c.Keys = make(map[string]any) }

c.Keys[key] = value
c.mu.Unlock()

}`

Comment From: MikeJackOne

Any other questions?

Comment From: amankaur27

Actually I am running this system from last 5 years. And I did not encounter problem except for 2-3 times. I doubt it does not break the current system.

Comment From: amankaur27

Also I provided you the sample. But actually the values are set in context in a middleware which is called before main(). Does it make any difference ?

Comment From: MikeJackOne

Actually I am running this system from last 5 years. And I did not encounter problem except for 2-3 times. I doubt it does not break the current system.

It may make some difference, you can share with me the middleware code and I will analyse it for you if you want to dig more.

Comment From: amankaur27

@MikeJackOne Please find the complete router code here (along with middleware): https://go.dev/play/p/8fFE7FTjkiv

Comment From: MikeJackOne

@MikeJackOne Please find the complete router code here (along with middleware): https://go.dev/play/p/8fFE7FTjkiv

I see where you problem is, you shouldn't use userName as a global variable.

Comment From: MikeJackOne

you may now close this issue, as this issue is not related to gin.

Comment From: amankaur27

Thanks @MikeJackOne I got it. Closing this issue.

Comment From: MikeJackOne

I am looking for a remote golang job, do you have any position that you can refer me to?

Comment From: amankaur27

Currently we have no vacancy for remote job. But I will let you know if there wil be any.

---- On Thu, 15 Dec 2022 14:29:17 +0530 Yan Mao @.***> wrote ---

I am looking for a remote golang job, do you have any position that you can refer me to?

— Reply to this email directly, https://github.com/gin-gonic/gin/issues/3437#issuecomment-1352744782, or https://github.com/notifications/unsubscribe-auth/AHX2B2KQXKZ3RBUROB6CBWLWNLMWLANCNFSM6AAAAAAS6BVGLE. You are receiving this because you modified the open/close state.