github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/engine/callback/callback.go (about)

     1  package callback
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	"fmt"
     7  	"reflect"
     8  	"time"
     9  
    10  	"github.com/mdaxf/iac-signalr/signalr"
    11  	"github.com/mdaxf/iac/com"
    12  	"github.com/mdaxf/iac/documents"
    13  	"github.com/mdaxf/iac/logger"
    14  )
    15  
    16  var callBackMap map[string]interface{}
    17  
    18  func init() {
    19  	callBackMap = make(map[string]interface{})
    20  }
    21  
    22  // RegisterCallBack registers a callback function with the specified key.
    23  // The callback function will be associated with the key in the callBackMap.
    24  // The key is used to identify the callback function when it needs to be invoked.
    25  // The callBack parameter should be a function or a method that matches the signature of the callback.
    26  // Example usage:
    27  //   RegisterCallBack("key", func() {
    28  //     // callback logic here
    29  //   })
    30  
    31  func RegisterCallBack(key string, callBack interface{}) {
    32  	log := logger.Log{ModuleName: logger.Framework, User: "System", ControllerName: "CallbackRegister"}
    33  	startTime := time.Now()
    34  	defer func() {
    35  		elapsed := time.Since(startTime)
    36  		log.PerformanceWithDuration("engine.callback.RegisterCallBack", elapsed)
    37  	}()
    38  	/*
    39  		defer func() {
    40  			if err := recover(); err != nil {
    41  				log.Error(fmt.Sprintf("There is error to engine.callback.RegisterCallBack with error: %s", err))
    42  				return
    43  			}
    44  		}()
    45  	*/
    46  	log.Debug(fmt.Sprintf("RegisterCallBack: %s with %v", key, callBack))
    47  	callBackMap[key] = callBack
    48  
    49  	log.Debug(fmt.Sprintf("callBackMap: %s", callBackMap))
    50  }
    51  
    52  // ExecuteTranCode executes a transaction code callback function.
    53  // It takes a key string, tcode string, inputs map[string]interface{}, ctx context.Context,
    54  // ctxcancel context.CancelFunc, dbTx *sql.Tx, DBCon *documents.DocDB, and sc signalr.Client as input parameters.
    55  // It returns a slice of interface{} as the result of the callback function.
    56  // Example usage:
    57  //
    58  //	ExecuteTranCode("key", "tcode", map[string]interface{}{"key": "value"}, context.Background(), context.CancelFunc, sql.Tx, documents.DocDB, signalr.Client)
    59  //	ExecuteTranCode("key", "tcode", map[string]interface{}{"key": "value"}, nil, nil, nil, nil, nil)
    60  //	ExecuteTranCode("key", "tcode", nil, nil, nil, nil, nil, nil)
    61  func ExecuteTranCode(key string, tcode string, inputs map[string]interface{}, ctx context.Context, ctxcancel context.CancelFunc, dbTx *sql.Tx, DBCon *documents.DocDB, sc signalr.Client) []interface{} {
    62  	log := logger.Log{ModuleName: logger.Framework, User: "System", ControllerName: "CallbackExecution"}
    63  
    64  	startTime := time.Now()
    65  	defer func() {
    66  		elapsed := time.Since(startTime)
    67  		log.PerformanceWithDuration("engine.callback.ExecuteTranCode", elapsed)
    68  	}()
    69  
    70  	defer func() {
    71  		if err := recover(); err != nil {
    72  			log.Error(fmt.Sprintf("There is error to engine.callback.ExecuteTranCode with error: %s", err))
    73  			return
    74  		}
    75  	}()
    76  
    77  	log.Debug(fmt.Sprintf("CallBackFunc: %s with %s %s %s %s %s", key, tcode, inputs, ctx, ctxcancel, dbTx))
    78  	log.Debug(fmt.Sprintf("callBackMap: %s", callBackMap))
    79  	if callBack, ok := callBackMap[key]; ok {
    80  
    81  		log.Debug(fmt.Sprintf("callBack: %s", callBack))
    82  
    83  		in := make([]reflect.Value, 7)
    84  		in[0] = reflect.ValueOf(tcode)
    85  		if inputs == nil {
    86  			inputs = map[string]interface{}{}
    87  		}
    88  
    89  		in[1] = reflect.ValueOf(inputs)
    90  
    91  		if sc == nil {
    92  			sc = com.IACMessageBusClient
    93  		}
    94  		in[2] = reflect.ValueOf(sc)
    95  
    96  		if DBCon == nil {
    97  			DBCon = documents.DocDBCon
    98  		}
    99  		in[3] = reflect.ValueOf(DBCon)
   100  
   101  		if ctx == nil {
   102  			ctx, ctxcancel = context.WithTimeout(context.Background(), time.Second*time.Duration(com.TransactionTimeout))
   103  		}
   104  		in[4] = reflect.ValueOf(ctx)
   105  
   106  		if ctxcancel == nil {
   107  			ctxcancel = func() {}
   108  		}
   109  		in[5] = reflect.ValueOf(ctxcancel)
   110  
   111  		in[6] = reflect.ValueOf(dbTx)
   112  
   113  		log.Debug(fmt.Sprintf("in: %s", in))
   114  
   115  		funcValue := reflect.ValueOf(callBack)
   116  		log.Debug(fmt.Sprintf("funcValue: %s", funcValue))
   117  
   118  		if funcValue.Kind() != reflect.Func {
   119  			log.Error(fmt.Sprintf("callBack(%s) is not a function", key))
   120  			return nil
   121  		}
   122  
   123  		outList := funcValue.Call(in)
   124  		result := make([]interface{}, len(outList))
   125  
   126  		log.Debug(fmt.Sprintf("outList: %s", logger.ConvertJson(outList)))
   127  
   128  		for i, out := range outList {
   129  			result[i] = out.Interface()
   130  		}
   131  		log.Debug(fmt.Sprintf("result: %s", logger.ConvertJson(result)))
   132  		return result
   133  	} else {
   134  		log.Error(fmt.Sprintf("callBack(%s) not found", key))
   135  		return nil
   136  	}
   137  }