graph_engine_go

package module
v0.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2024 License: MIT Imports: 10 Imported by: 0

README

graph_engine_go

第一个golang项目,持续优化开发中...

用于实现Golang模块的自动组装功能,便于模块解耦,易于更新维护。

Introduction

golang版本的图引擎

在实际的业务生产环境中,经常需要对各种逻辑进行组合以实现业务需求。使用一套框架来完成各个业务逻辑的组装是比较便于维护的,既能节省研发人员的精力,又能保持运行稳定。

本仓库为Golang工程提供图引擎框架,也就是以图的形式来组织程序中的数据和操作。 一个操作总是依赖一些数据或者发射一些数据,包括输入和输出操作,因此这些任务可以使用图来描述,图中包括一些节点(操作)以及这些节点之间的连接关系(数据)。 图引擎是由数据驱动的。如果一个操作所依赖的数据都准备就绪,那么该操作就会自动运行起来。

Features

  • 以图的方式组织业务逻辑,满足复杂业务需求

组织业务逻辑的方式大体可以分两类,一类是完全使用代码组织,通常用于学习和试验性的工程;另一类是使用配置文件+固定结构的框架,通常用于生产环境下。对于第二类,一种比较简单的实现就是线性结构,按照配置文件中的顺序执行业务逻辑,缺点是不够灵活;另一种就是本项目采取的图结构,配置文件中的信息描述节点和依赖,框架按照图结构组装节点,可以方便地实现复杂业务逻辑。

  • 业务逻辑解耦,便于维护升级

把业务逻辑拆分到每个节点中,可以逻辑模块进行更新和日常维护

  • 自动并行执行没有依赖关系的所有逻辑

图结构的组装框架自动完成没有依赖关系的节点并行执行,最大程度提升程序运行效率

  • 尽量保持内存复用

同一处理池在处理不同请求的时候,尽量复用最开始创建的内存。能够最大程度避免程序运行过程中出现内存剧烈波动。

Install

在自己的工程根目录下使用如下指令

go get github.com/jielyu/graph_engine_go

在需要使用的文件中导入graph_engine_go

import (
    ge "github.com/jielyu/graph_engine_go"
)

User Guide

示例: example

第1步 实现接口

实现ge.GraphOperator 接口

type GraphOperator interface {
	// 设置并记录节点的config信息
	SetConfig(config *GraphNodeConfig) error
	// 建立图结构,主要用于创建依赖和发布的数据结构,只在创建时执行一次
	SetUp(ctx *GraphContext) error
	// 初始化操作,一般用于设置初始化参数,只在创建时执行一次
	Initailize(ctx *GraphContext) error
	// 执行任务,业务逻辑主要封装在这个函数,每次都会执行
	Process(ctx *GraphContext) error
}

图引擎中的节点分为3种:

  • 输入节点,不依赖其他节点提供的数据,每次运行时自动处于就绪状态。输入节点示例
  • 中间计算节点,依赖其他节点提供数据,也会提供数据给其他节点依赖,需要等待依赖的数据全部就绪才能运行。中间节点示例
  • 输出节点,依赖其他节点提供数据,但不为其他节点提供依赖数据,需要等待依赖的数据全部就绪才能运行。输出节点示例

建议:每个节点单独放在一个文件,便于维护

第2步 注册类型

init函数中注册所定义的节点类型,例如

func init() {
	ge.Register[TwoNumbersGeneratorOp]()
}

建议:init函数与节点实现放在同一个文件中,便于解耦合

第3步 编写配置

编写图结构的配置文件,可以参照例子 main_graph

图结构配置字段说明

"name": string, 指定图的名字
"type": string, 指定图的类型,[MainGraph/SubGraph]
"include": []string, 指定依赖的子图文件
"pool_size": int, 指定资源池的大小,越大的pool响应并发的能力越强,但消耗资源也越大
"num_threads": int, 指定单个context运行的线程数,暂时无用
"nodes": []GraphNodeConfig, 存储每个节点的配置信息

节点配置信息说明

{
    "name": string, 节点名字
    "type": string, 节点类型名,要求必须是注册过的类型名,否则报错
    "depends": map[string]string, 依赖的数据 
    {
        "Name": "data", Name是在程序中使用的,data是在当前配置文件内使用的,可以多个
    },
    "emitters": map[string]string, 发布的数据 
    {
        "Name": "data", Name是在程序中使用的,data是在当前配置文件内使用的,可以多个
    },
    "config": map[string]string, 用于设置一些配置项,需要自行在实现时解析
}
第4步 运行图引擎

准备工作就绪之后就可以把图引擎运行起来了,可以参照示例

package main

import (
	"fmt"
	"sync"

	_ "example/nodes"
	ge "github.com/jielyu/graph_engine_go"
)

var wg sync.WaitGroup

func main() {
	fmt.Println("welcome to graph_engine_go example")
	ge := ge.NewGraphEngine("./config/main_graph.json")
	times := 10
	wg.Add(times)
	for i := 0; i < times; i++ {
		go func(reqId uint64) {
			var v interface{}
			ge.Process(v, reqId)
			wg.Done()
		}(uint64(i))
	}
	wg.Wait()
}

Future

  • 子图机制,使用子图提高图配置的复用率
  • 动态图机制,使用节点发射数据控制图的运行流程

Documentation

Overview

用于注册算子,并提供创建对象的接口

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Dep

func Dep[T any](gdep *GraphDep) *T

func Emit

func Emit[T any](gdata *GraphData) *T

func EmitDep

func EmitDep[T any](gdata *GraphData, gdep *GraphDep) *T

直接发布依赖的数据,用于inplace形式的修改,节省内存 模版不能用于类型方法,因此只能单独提供函数

func Register

func Register[T any]()

使用范型和反射机制简化注册函数

func RegisterClass

func RegisterClass(name string, fac_func func() GraphOperator) error

注册一个类型 Deprecated,建议外部使用 Register 函数完成注册功能

Types

type GraphConfig

type GraphConfig struct {
	Name       string            `json:"name"`
	TypeName   string            `json:"type"`
	Include    []string          `json:"include"`
	PoolSize   int               `json:"pool_size"`
	NumThreads int               `json:"num_threads"`
	Nodes      []GraphNodeConfig `json:"nodes"`
}

整图结构的配置

func LoadGraphConfig

func LoadGraphConfig(configJson string) (*GraphConfig, error)

载入关于图结构信息描述的json文件

type GraphContext

type GraphContext struct {
	InputData  interface{}
	OutputData interface{}
	Busy       bool   // ctx是否处于繁忙的标志
	Id         int    // ctx在缓冲池中的Id
	ReqId      uint64 // 每次请求尽量使用不同的ReqId,便于日志查询
	// contains filtered or unexported fields
}

func NewGraphContext

func NewGraphContext() *GraphContext

创建GraphContext对象

func (*GraphContext) Build

func (ctx *GraphContext) Build(graphConfig *GraphConfig) error

创建图结构

func (*GraphContext) NameDepend

func (ctx *GraphContext) NameDepend(name string) *GraphDep

用于创建依赖数据的对象

func (*GraphContext) NameEmit

func (ctx *GraphContext) NameEmit(name string) *GraphData

用于创建发布数据的对象

func (*GraphContext) Process

func (ctx *GraphContext) Process() error

/ 运行所有有效节点

func (*GraphContext) Release

func (ctx *GraphContext) Release()

/ 释放资源

type GraphData

type GraphData struct {
	Name     string
	Active   bool
	TypeName string
	Data     interface{}
}

** 用于管理节点发布的数据

func GetGraphDataByName

func GetGraphDataByName(ctx *GraphContext, config *GraphNodeConfig, name string) *GraphData

用于SetUp函数中创建GraphData

type GraphDep

type GraphDep struct {
	Name         string
	Mutable      bool
	RefGraphData *GraphData
}

** 用于管理节点依赖的数据

func GetGraphDependByName

func GetGraphDependByName(ctx *GraphContext, config *GraphNodeConfig, name string) *GraphDep

用于SetUp函数中创建GraphDep

func (*GraphDep) SetMutable

func (gdep *GraphDep) SetMutable()

type GraphEngine

type GraphEngine struct {
	// contains filtered or unexported fields
}

func NewGraphEngine

func NewGraphEngine(jsonFile string) *GraphEngine

创建一个图引擎

func (*GraphEngine) Process

func (ge *GraphEngine) Process(inputData interface{}, reqId uint64) (interface{}, error)

用于执行一次处理任务 inputData可以在输入节点强制转换为对应结构 reqId用于标识每次处理,最好保证互异

func (*GraphEngine) Release

func (ge *GraphEngine) Release()

/ 释放资源

type GraphNodeConfig

type GraphNodeConfig struct {
	Name     string            `json:"name"`
	NodeType string            `json:"type"`
	Emitters map[string]string `json:"emitters"`
	Depends  map[string]string `json:"depends"`
	Config   map[string]string `json:"config"`
}

节点配置

type GraphOperator

type GraphOperator interface {
	// 设置并记录节点的config信息
	SetConfig(config *GraphNodeConfig) error
	// 建立图结构,主要用于创建依赖和发布的数据结构,只在创建时执行一次
	SetUp(ctx *GraphContext) error
	// 初始化操作,一般用于设置初始化参数,只在创建时执行一次
	Initailize(ctx *GraphContext) error
	// 执行任务,业务逻辑主要封装在这个函数,每次都会执行
	Process(ctx *GraphContext) error
}

所有节点都需要实现的基础接口

func CreateInstance

func CreateInstance(name string) (GraphOperator, error)

根据类型名字创建对象

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL