github.com/ovechkin-dm/go-dyno@v0.0.23/cmd/cache_example/cache.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/ovechkin-dm/go-dyno/pkg/dyno"
     6  	"reflect"
     7  	"time"
     8  	"unsafe"
     9  )
    10  
    11  type Service interface {
    12  	Foo(s string) string
    13  	Bar(i int) int
    14  }
    15  
    16  type Impl struct {
    17  }
    18  
    19  func (h *Impl) Foo(s string) string {
    20  	time.Sleep(2 * time.Second)
    21  	return s + " world!"
    22  }
    23  
    24  func (h *Impl) Bar(i int) int {
    25  	time.Sleep(2 * time.Second)
    26  	return i + 1
    27  }
    28  
    29  type CachingProxy struct {
    30  	delegate interface{}
    31  	cache    map[int][]reflect.Value
    32  }
    33  
    34  func (c *CachingProxy) Handle(method *dyno.Method, values []reflect.Value) []reflect.Value {
    35  	_, ok := c.cache[method.Num]
    36  	ref := reflect.ValueOf(c.delegate)
    37  	if !ok {
    38  		out := ref.Method(method.Num).Call(values)
    39  		c.cache[method.Num] = out
    40  	}
    41  	return c.cache[method.Num]
    42  
    43  }
    44  
    45  func CreateCachingProxyFor[T any](t T) (T, error) {
    46  	proxy := &CachingProxy{
    47  		delegate: t,
    48  		cache:    make(map[int][]reflect.Value),
    49  	}
    50  	return dyno.Dynamic[T](proxy)
    51  }
    52  
    53  type iFaceValue struct {
    54  	typ  uintptr
    55  	ptr  *nonEmptyInterface
    56  	flag uintptr
    57  }
    58  
    59  type nonEmptyInterface struct {
    60  	itab *itab
    61  	word unsafe.Pointer
    62  }
    63  
    64  type itab struct {
    65  	ityp uintptr
    66  	typ  uintptr
    67  	hash uint32
    68  	_    [4]byte
    69  	fun  [100000]unsafe.Pointer
    70  }
    71  
    72  func main() {
    73  	s := &Impl{}
    74  	proxy, err := CreateCachingProxyFor[Service](s)
    75  	if err != nil {
    76  		panic(err)
    77  	}
    78  
    79  	fmt.Println(proxy.Foo("hello"))
    80  	fmt.Println(proxy.Foo("hello"))
    81  	fmt.Println(proxy.Foo("hello"))
    82  }