github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/services/caches/get.go (about) 1 /* 2 * Copyright 2023 Wang Min Xiang 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package caches 19 20 import ( 21 "fmt" 22 "github.com/aacfactory/avro" 23 "github.com/aacfactory/errors" 24 "github.com/aacfactory/fns/commons/bytex" 25 "github.com/aacfactory/fns/context" 26 "github.com/aacfactory/fns/runtime" 27 "github.com/aacfactory/fns/services" 28 ) 29 30 func Load[E any](ctx context.Context, param any) (value E, has bool, err error) { 31 p, exist, getErr := Get(ctx, param) 32 if getErr != nil { 33 err = getErr 34 return 35 } 36 if exist { 37 result := new(E) 38 err = avro.Unmarshal(p, result) 39 if err != nil { 40 err = errors.Warning("fns: get cache failed").WithCause(err) 41 return 42 } 43 value = *result 44 has = true 45 } 46 return 47 } 48 49 func Get(ctx context.Context, param any) (p []byte, has bool, err error) { 50 if param == nil { 51 err = errors.Warning("fns: get cache failed").WithCause(fmt.Errorf("param is nil")) 52 return 53 } 54 kp, ok := param.(KeyParam) 55 if !ok { 56 err = errors.Warning("fns: get cache failed").WithCause(fmt.Errorf("param dose not implement caches.KeyParam")) 57 return 58 } 59 key, keyErr := kp.CacheKey(ctx) 60 if keyErr != nil { 61 err = errors.Warning("fns: get cache failed").WithCause(keyErr) 62 return 63 } 64 eps := runtime.Endpoints(ctx) 65 response, doErr := eps.Request(ctx, endpointName, getFnName, getFnParam{ 66 Key: bytex.ToString(key), 67 }, services.WithInternalRequest()) 68 if doErr != nil { 69 err = doErr 70 return 71 } 72 result, resultErr := services.ValueOfResponse[getResult](response) 73 if resultErr != nil { 74 err = errors.Warning("fns: get cache failed").WithCause(resultErr) 75 return 76 } 77 p = result.Value 78 has = result.Has 79 return 80 } 81 82 type getFnParam struct { 83 Key string `json:"key" avro:"key"` 84 } 85 86 type getResult struct { 87 Has bool `json:"has" avro:"has"` 88 Value []byte `json:"value" avro:"value"` 89 } 90 91 type getFn struct { 92 store Store 93 } 94 95 func (fn *getFn) Name() string { 96 return string(getFnName) 97 } 98 99 func (fn *getFn) Internal() bool { 100 return true 101 } 102 103 func (fn *getFn) Readonly() bool { 104 return false 105 } 106 107 func (fn *getFn) Handle(r services.Request) (v interface{}, err error) { 108 if !r.Param().Valid() { 109 err = errors.Warning("fns: get cache failed").WithCause(errors.Warning("param is invalid")) 110 return 111 } 112 param, paramErr := services.ValueOfParam[getFnParam](r.Param()) 113 if paramErr != nil { 114 err = errors.Warning("fns: get cache failed").WithCause(paramErr) 115 return 116 } 117 key := bytex.FromString(param.Key) 118 if len(key) == 0 { 119 err = errors.Warning("fns: get cache failed").WithCause(errors.Warning("param is invalid")) 120 return 121 } 122 value, has, getErr := fn.store.Get(r, key) 123 if getErr != nil { 124 err = errors.Warning("fns: get cache failed").WithCause(getErr) 125 return 126 } 127 v = getResult{ 128 Has: has, 129 Value: value, 130 } 131 return 132 }