// entry function package main import ( "context" "flag" "time" "modelRT/alert" "modelRT/config" "modelRT/database" "modelRT/diagram" locker "modelRT/distributedlock" _ "modelRT/docs" "modelRT/handler" "modelRT/logger" "modelRT/middleware" "modelRT/pool" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" realtimedata "modelRT/real-time-data" "github.com/gin-gonic/gin" "github.com/panjf2000/ants/v2" "go.uber.org/zap" "gorm.io/gorm" ) var limiter *middleware.Limiter func init() { limiter = middleware.NewLimiter(10, 1*time.Minute) // 设置限流器,允许每分钟最多请求10次 } var ( modelRTConfigDir = flag.String("modelRT_config_dir", "./config", "config file dir of model runtime service") modelRTConfigName = flag.String("modelRT_config_name", "config", "config file name of model runtime service") modelRTConfigType = flag.String("modelRT_config_type", "yaml", "config file type of model runtime service") ) var ( modelRTConfig config.ModelRTConfig postgresDBClient *gorm.DB zapLogger *zap.Logger alertManager *alert.EventManager ) // TODO 使用 wire 依赖注入管理 DVIE 面板注册的 panel func main() { flag.Parse() ctx := context.TODO() modelRTConfig = config.ReadAndInitConfig(*modelRTConfigDir, *modelRTConfigName, *modelRTConfigType) // init postgresDBClient postgresDBClient = database.InitPostgresDBInstance(ctx, modelRTConfig.PostgresDBURI) defer func() { sqlDB, err := postgresDBClient.DB() if err != nil { panic(err) } sqlDB.Close() }() // init logger zapLogger = logger.InitLoggerInstance(modelRTConfig.LoggerConfig) defer zapLogger.Sync() // init alert manager _ = alert.InitAlertEventManager() // init model parse ants pool parsePool, err := ants.NewPoolWithFunc(modelRTConfig.ParseConcurrentQuantity, pool.ParseFunc) if err != nil { zapLogger.Error("init concurrent parse task pool failed", zap.Error(err)) panic(err) } defer parsePool.Release() storageClient := diagram.InitClientInstance(modelRTConfig.StorageRedisConfig) defer storageClient.Close() lockerClient := locker.InitClientInstance(modelRTConfig.LockerRedisConfig) defer lockerClient.Close() // init anchor param ants pool anchorRealTimePool, err := pool.AnchorPoolInit(modelRTConfig.RTDReceiveConcurrentQuantity) if err != nil { zapLogger.Error("init concurrent anchor param task pool failed", zap.Error(err)) panic(err) } defer anchorRealTimePool.Release() // init cancel context cancelCtx, cancel := context.WithCancel(ctx) defer cancel() // init real time data receive channel go realtimedata.ReceiveChan(cancelCtx) postgresDBClient.Transaction(func(tx *gorm.DB) error { // load circuit diagram from postgres componentTypeMap, err := database.QueryCircuitDiagramComponentFromDB(cancelCtx, tx, parsePool, zapLogger) if err != nil { zapLogger.Error("load circuit diagrams from postgres failed", zap.Error(err)) panic(err) } // TODO 暂时屏蔽完成 swagger 启动测试 err = database.QueryTopologicFromDB(ctx, tx, zapLogger, componentTypeMap) if err != nil { zapLogger.Error("load topologic info from postgres failed", zap.Error(err)) panic(err) } return nil }) // TODO 完成订阅数据分析 // TODO 暂时屏蔽完成 swagger 启动测试 // go realtimedata.RealTimeDataComputer(ctx, nil, []string{}, "") engine := gin.Default() engine.Use(limiter.Middleware) // diagram api engine.GET("/model/diagram_load", handler.CircuitDiagramLoadHandler) engine.POST("/model/diagram_create", handler.CircuitDiagramCreateHandler) engine.POST("/model/diagram_update", handler.CircuitDiagramUpdateHandler) engine.POST("/model/diagram_delete", handler.CircuitDiagramDeleteHandler) // real time data api engine.GET("/ws/rtdatas", handler.RealTimeDataReceivehandler) // anchor api engine.POST("/model/anchor_replace", handler.ComponentAnchorReplaceHandler) // alert api engine.GET("/alert/events/query", handler.QueryAlertEventHandler) // real time data api engine.GET("/rt/datas/query", handler.QueryRealTimeDataHandler) // dashborad api dashboard := engine.Group("/dashboard", limiter.Middleware) { dashboard.GET("/load", nil) dashboard.GET("/query", nil) dashboard.POST("/create", nil) dashboard.POST("/update", nil) dashboard.POST("/delete", nil) } // engine.Group() // Swagger UI engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) // 注册 Swagger UI 路由 // docs.SwaggerInfo.BasePath = "/model" // v1 := engine.Group("/api/v1") // { // eg := v1.Group("/example") // { // eg.GET("/helloworld", Helloworld) // } // } // start route with 8080 port engine.Run(":8080") // Redis hashmap 母线模型、异步电动机模型 // kv key name value busx }