github.com/kaydxh/golang@v0.0.131/pkg/scheduler/task/task.go (about) 1 /* 2 *Copyright (c) 2022, kaydxh 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining a copy 5 *of this software and associated documentation files (the "Software"), to deal 6 *in the Software without restriction, including without limitation the rights 7 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 *copies of the Software, and to permit persons to whom the Software is 9 *furnished to do so, subject to the following conditions: 10 * 11 *The above copyright notice and this permission notice shall be included in all 12 *copies or substantial portions of the Software. 13 * 14 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 *SOFTWARE. 21 */ 22 package task 23 24 import ( 25 "reflect" 26 27 reflect_ "github.com/kaydxh/golang/go/reflect" 28 ) 29 30 type Task struct { 31 TaskId string 32 TaskFunc interface{} 33 Args []TaskArgument 34 // TaskStatus 35 PreTaskHandler func(*Task) error 36 PostTaskHandler func(*Task) error 37 } 38 39 // Types which can be used: bool, string, int int8 int16 int32 int64, uint uint8 uint16 uint32 uint64, float32 float64 40 type TaskArgument struct { 41 Type string `json:"type"` 42 Value interface{} `json:"value"` 43 } 44 45 func (t *Task) Run() ([]*TaskResult, error) { 46 47 reflectTaskFunc := reflect.ValueOf(t.TaskFunc) 48 reflectTaskArgs, err := reflectTaskArgs(t.Args) 49 if err != nil { 50 return nil, err 51 } 52 53 results := reflectTaskFunc.Call(reflectTaskArgs) 54 return reflectTaskResults(results) 55 } 56 57 func reflectTaskArgs(args []TaskArgument) ([]reflect.Value, error) { 58 argValues := make([]reflect.Value, len(args)) 59 60 for i, arg := range args { 61 argValue, err := reflect_.ReflectValue(arg.Type, arg.Value) 62 if err != nil { 63 return nil, err 64 } 65 argValues[i] = argValue 66 } 67 68 return argValues, nil 69 } 70 71 func reflectTaskResults(results []reflect.Value) ([]*TaskResult, error) { 72 // Task must return at least a value 73 if len(results) == 0 { 74 return nil, ErrTaskReturnsNoValue 75 } 76 77 // Last returned value 78 lastResult := results[len(results)-1] 79 if !lastResult.IsNil() { 80 // check that the result implements the standard error interface, 81 // if not, return ErrLastReturnValueMustBeError error 82 errorInterface := reflect.TypeOf((*error)(nil)).Elem() 83 if !lastResult.Type().Implements(errorInterface) { 84 return nil, ErrLastReturnValueMustBeError 85 } 86 87 // Return the standard error 88 return nil, lastResult.Interface().(error) 89 } 90 91 // Convert reflect values to task results 92 taskResults := make([]*TaskResult, len(results)-1) 93 for i := 0; i < len(results)-1; i++ { 94 val := results[i].Interface() 95 typeStr := reflect.TypeOf(val).String() 96 taskResults[i] = &TaskResult{ 97 Type: typeStr, 98 Value: val, 99 } 100 } 101 102 return taskResults, nil 103 }