Now that I think about it again - I guess your suggestion could work for my
case with some caveats:

1. There can be contention on the map - but as you point out there is
sync.Map as well
2. The state should be removed from the map but that can also be arranged
by deferring a delete operation
3. If contention is indeed a problem I can mitigate by sharding the map
4. If contention continues to be a problem perhaps weak pointers with this
recipe https://github.com/golang/go/issues/67552#issuecomment-2195479919 may
help.

It won't be pretty but hey - help beggars can't be choosers!

Kind regards:
al_shopov

На пн, 12.05.2025 г. в 17:22 Jason E. Aten <j.e.a...@gmail.com> написа:

> Forgive me if this off base, as I'm still a little fuzzy on the exact
> constraints
> of you problem... but, as stated, if you want
> to associate additional optional behavior and state with any given response
> that is constrained to the generated, just use
> the responses's pointer (to its struct)  (if local an ephemeral is all you
> need, or a cryptographic hash of
> its contents, if you need to survive reboots) as the key into a separate
> map/sync.Map/
> database. Standard Go does not move pointers; the GC is a non-moving
> collector
> by intent to enable sane interfacing with C code, and does very well at
> avoiding
> fragmentation (the motivation for compaction/copying GC) by using
> size classes instead. Since you can rely on the pointer not moving, just
> use it as a key to a map[*generated.Response]*EnrichedResponse to
> lookup your additional state on either the caller or responder side.
>
> On Monday, May 12, 2025 at 1:12:25 PM UTC+1 Alexander Shopov wrote:
>
>> seems a very common assumption
>>
>>
>> I would have guessed it is due to compatibility with C but
>> https://pkg.go.dev/cmd/cgo#hdr-C_references_to_Go explicitly states:
>> *Go struct types are not supported; use a C struct type. *
>> So it may be completely at the decision of the implementer.
>> The caveats in https://go.dev/wiki/cgo#common-pitfalls also sound too
>> tricky.
>>
>> The pointer to the entire value stays alive while any pointer to one of
>> its fields is alive
>>
>> That requires some cooperation from the GC. In the case where structs are
>> reasonably small and they contain values rather than pointers this would
>> probably hold.
>>
>> Thanx for even further details (I am writing down the offset trick) but
>> I'd prefer to not stray too far away from usual conventions.
>>
>> Kind regards:
>> al_shopov
>>
>>
>> На пн, 12.05.2025 г. в 12:14 Axel Wagner <axel.wa...@googlemail.com>
>> написа:
>>
>>>
>>>
>>> On Mon, 12 May 2025 at 11:12, Alexander Shopov <a...@kambanaria.org>
>>> wrote:
>>>
>>>> Is the equality of pointer to struct and pointer to its first member
>>>> actually always guaranteed by Go lang?
>>>> https://go.dev/ref/spec#Package_unsafe says The effect of converting
>>>> between Pointer and uintptr is implementation-defined but I guess it
>>>> is not the same thing. The sections on Struct types and Alignment do not
>>>> give such guarantees.
>>>>
>>>
>>> Perhaps not, though it seems a very common assumption and if an
>>> implementation violates it, I would expect that to break a bunch of code.
>>> You can always make sure, by accounting for a potential offset:
>>> https://go.dev/play/p/whdFALRG20P
>>> I guess that still makes the assumption, that a pointer to the entire
>>> value stays alive while any pointer to one of its field is alive. I'm not
>>> sure *that* is guaranteed either, but at least it's a weaker assumption.
>>>
>>>
>>>> In the end it is not wise to use such a technique on a large code base
>>>> shared by many developers. I will not be going this way but many thanx for
>>>> the example it taught me something I did not know.
>>>>
>>>> Axel, you may use it for a 2nd part of Advanced Generics Patterns (nice
>>>> presentation! I liked it) - Advanced Type Patterns (use types wrongly so we
>>>> can learn how to make the wrong way the right way).
>>>>
>>>>
>>>> I was hoping that there is a trick that I am missing. Like - a returned
>>>> function can access state in a closure but I see no way to do it for
>>>> methods. I definitely do not want to go the direction - since I want to add
>>>> a method I should change the code generation, types (struct vs
>>>> interface-s)  to suit that small change.
>>>>
>>>> Kind regards:
>>>> al_shopov
>>>>
>>>> На пн, 12.05.2025 г. в 7:12 Axel Wagner <axel.wa...@googlemail.com>
>>>> написа:
>>>>
>>>>> On Mon, 12 May 2025 at 07:05, Axel Wagner <axel.wa...@googlemail.com>
>>>>> wrote:
>>>>>
>>>>>> A less evil, but still bad way, would be to store it in a global map:
>>>>>> https://go.dev/play/p/ZHBJVCduf25 (note: I'm not sure this use of
>>>>>> weak pointers is actually correct, I haven't used them yet).
>>>>>>
>>>>>
>>>>> Okay, I'm pretty sure it's not correct. It should be possible to make
>>>>> this work somehow, but I'm a bit too lazy to try right now, especially as
>>>>> you shouldn't do it anyways.
>>>>>
>>>>>
>>>>>> Otherwise, no. The state has to live somewhere. And really, both of
>>>>>> these tricks are still really bad and you shouldn't do them. The best way
>>>>>> is to respect the type system and if you want extra methods, you need a 
>>>>>> new
>>>>>> type and if that needs extra state, that should be stored in the type.
>>>>>>
>>>>>> -----
>>>>>>> Why would I want to do this? What am I trying to achieve?
>>>>>>>
>>>>>>> Basically there is a lot of generated code and I want to keep
>>>>>>> compatibility with it.
>>>>>>> Similar to the way Go embeds wider interfaces into narrower ones I
>>>>>>> want to be able to add methods to the generated code without having to
>>>>>>> change it.
>>>>>>
>>>>>>
>>>>>> Change the code generator, and/or add additional code in an extra
>>>>>> file. Hacking the language will cause you more pain, in the long run.
>>>>>>
>>>>>>
>>>>>>> Then - whenever some code calls the *Get* method on the server -
>>>>>>> based on the whether the returned value implements the *Enriched*
>>>>>>> interface or not and the value it returns - I can dispatch behavior.
>>>>>>>
>>>>>>> Kind regards:
>>>>>>> al_shopov
>>>>>>>
>>>>>>> --
>>>>>>> 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...@googlegroups.com.
>>>>>>> To view this discussion visit
>>>>>>> https://groups.google.com/d/msgid/golang-nuts/bbe6bcd8-e33c-41bf-868a-e498561c3e72n%40googlegroups.com
>>>>>>> <https://groups.google.com/d/msgid/golang-nuts/bbe6bcd8-e33c-41bf-868a-e498561c3e72n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>>
>>>>>> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/5gx3CCMfyJg/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion visit
> https://groups.google.com/d/msgid/golang-nuts/e823a08d-11c3-49d0-bd24-89eef57efc0an%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/e823a08d-11c3-49d0-bd24-89eef57efc0an%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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 visit 
https://groups.google.com/d/msgid/golang-nuts/CAP6f5MmNXt-AuUPA4XGc1ZbbYqaMibtdzcxikx04KWNUpy21nA%40mail.gmail.com.

Reply via email to