On Thu, Jan 7, 2021 at 10:20 AM Axel Wagner
<axel.wagner...@googlemail.com> wrote:
>
> Hi,
>
> this works fine, but it incurs an extra allocation (AFAIK both for storing 
> the data, and for looking it up). requestContext is not zero-sized, so to 
> store it in an interface{}, a new value must be allocated and put into the 
> interface. This also has to happen on lookup (I don't think the compiler 
> optimizes that, today), because you need to convert it to interface{} when 
> passing it to `Value`. The recommended way
>
> type ctxKey struct{}
>
> type requestContext struct {
>     requestID string
>     requestID
> }
>
> ctx := context.WithValue(req.Context(), ctxKey{}, 
> requestContext{"request-123-abc", "client-451"})
>
> does not have this drawback - zero-sized values are special, because there 
> can only be one of them, so the compiler is free to re-use the same address. 
> So, a conversion of a zero-sized value to ctxKey{} is free.
> I would also argue, that the code is clearer and safer that way - because 
> there can only be one value of type ctxKey{}, you don't have to wonder what 
> would happen if you use different keys of the same type - and fmt.Println 
> only prints the type-name of keys, not the actual value 
> (https://play.golang.org/p/pAj6RclqAGw), so if you encounter a bug with 
> unexpected context-contents, it's just one less thing to worry about.
>
> So, yes, your way absolutely works. I would still strongly recommend going 
> the "official" route. It's one line of additional overhead, but there are 
> concrete technical benefits (as well as just the general benefits of 
> uniformity).

Your previous reply made me think of the same approach - use a
separate type for key.

> I would also argue, that the code is clearer and safer that way - because 
> there can only be one value of type ctxKey{}, you don't have to wonder what 
> would happen if you use different keys of the same type

I agree, I was thinking the same.

Thank you.



>
>
> On Thu, Jan 7, 2021 at 12:09 AM Amit Saha <amitsaha...@gmail.com> wrote:
>>
>> On Thu, Jan 7, 2021 at 10:01 AM Axel Wagner
>> <axel.wagner...@googlemail.com> wrote:
>> >
>> > Why do you need fields? If you need fields, you are likely putting too 
>> > many things into your context (note, that the lookup is O(N), with N being 
>> > the number of distinct keys - so you want the number of distinct keys to 
>> > be small). The intended use of `context.WithValue` is to only have one key 
>> > per "use-case" (normally, that means one key per package) and then store 
>> > the actual data in the value.
>> >
>> > So, yes, you *can* have fields and if you have fields and re-use one type 
>> > for many keys that way. And if you do that, you need to specify the exact 
>> > field values on the lookup as well. But if you want "many keys" from a 
>> > single type, that's a code-smell and I would suggest to change your 
>> > design. If you think you need it, feel free to expand on your use-case and 
>> > we might come up with a better solution :)
>>
>> This is what I have now in a HTTP handler function:
>>
>> Attach the data:
>>
>> c := requestContext{
>>      requestID: "request-123-abc",
>>      clientID: "client-451",
>> }
>>
>> currentCtx := req.Context()
>> newCtx := context.WithValue(currentCtx, requestContext{}, c)
>> req = req.WithContext(newCtx)
>>
>>
>> Retrieve the data somewhere else during processing the request:
>>
>> ctx := req.Context()
>> v := ctx.Value(requestContext{})
>> if m, ok := v.(requestContext); ok {
>>      log.Printf("Processing request: %v", m)
>> }
>>
>> Is this inefficient?
>>
>>
>>
>>
>> >
>> >
>> > On Wed, Jan 6, 2021 at 11:52 PM Amit Saha <amitsaha...@gmail.com> wrote:
>> >>
>> >> On Thu, Jan 7, 2021 at 9:48 AM Axel Wagner
>> >> <axel.wagner...@googlemail.com> wrote:
>> >> >
>> >> >
>> >> >
>> >> > On Wed, Jan 6, 2021 at 11:39 PM Amit Saha <amitsaha...@gmail.com> wrote:
>> >> >>
>> >> >> Is it fair to say then that any user-defined type here is acceptable 
>> >> >> as a key?
>> >> >
>> >> >
>> >> > No. You can create a user-defined type out of *any* type T, by just 
>> >> > writing `type X T`. In particular, you can write `type X func()` and 
>> >> > get an incomparable user-defined type.
>> >> >
>> >> > I highly recommend sticking to the recommendation from the docs: Use 
>> >> > `type ctxKey struct{}` as a key type and `ctxKey{}` as the key - it's 
>> >> > comparable and the only value equal to `ctxKey{}` is `ctxKey{}`, which 
>> >> > gives exactly the desirable semantics. And as it's zero-sized, it also 
>> >> > doesn't occur any allocation (at least with gc, all zero-sized objects 
>> >> > have the same address). You could also use `[0]int` or similar, but 
>> >> > `struct{}` is very common for use-cases like this.
>> >>
>> >> Thanks. If I wanted to have a struct like this
>> >>
>> >> type myReqContext struct {
>> >>     ID1 string
>> >>     ID2 string
>> >> }
>> >>
>> >> Would the correct key and value be: myReqContext{}, myReqContext{ID1:
>> >> "abcd", ID2: "defg"}?
>> >>
>> >> The key isn't zero value any more, or is it? If so, should I have a
>> >> dedicated empty struct for the key?
>> >>
>> >>
>> >>
>> >> >
>> >> >>
>> >> >>
>> >> >>
>> >> >> >>
>> >> >> >> Thanks,
>> >> >> >> Amit.
>> >> >> >>
>> >> >> >> --
>> >> >> >> You received this message because you are subscribed to the Google 
>> >> >> >> Groups "golang-nuts" group.
>> >> >> >> To unsubscribe from this group and stop receiving emails from it, 
>> >> >> >> send an email to golang-nuts+unsubscr...@googlegroups.com.
>> >> >> >> To view this discussion on the web visit 
>> >> >> >> https://groups.google.com/d/msgid/golang-nuts/CANODV3kUmtJvG9Lfys_HXfedwnm54neA6uub6cY1aiz%2B9w5DUA%40mail.gmail.com.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANODV3%3DKZHZ_O2JDvC0F3wT3k725iHzgD79qXoHpWjY4vvT%3DMw%40mail.gmail.com.

Reply via email to