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  }