Go运行Grule引擎实现计费规则管理

Go运行Grule引擎实现计费规则管理

  • github位置: https://github.com/hyperjumptech/grule-rule-engine
shell 复制代码
# 安装grule模块
go get -u github.com/hyperjumptech/grule-rule-engine

Grule的示例代码

  • 示例位置: https://github.com/hyperjumptech/grule-rule-engine/tree/master/examples

    • 使用 go test 运行
    shell 复制代码
    cd examples
    $ go test NumberExponentExample_test.go 
    ok      command-line-arguments  0.011s
  • Grule规则

    • rule {} 表示规则
    • salience 10 表示优先级为10
      • 优先级高的先执行
go 复制代码
type ExponentData struct {
	Check float64
	Set   float64
}

/*
    条件部分 (when):
    当ExponentData 结构体中的 Check 等于 6.67428e-11 时,规则会触发
    动作部分 (then):
    当条件满足时,将 ExponentData 结构体中的 Set 设置为 .12345E+5
    然後,使用 Retract("ExponentCheck") 將這個规则從工作记忆中移除,
    以防止它再次被觸發。
*/

const ExponentRule = `
rule  ExponentCheck  "User Related Rule"  salience 10 {
	when 
		ExponentData.Check == 6.67428e-11
	Then
		ExponentData.Set = .12345E+5;
		Retract("ExponentCheck");
}
`
// 往下是 运行"github.com/stretchr/testify/assert"的测试代码, 忽略
func TestEvaluateAndAssignExponentNumber(t *testing.T) {
	exponent := &ExponentData{
		Check: 6.67428e-11,
		Set:   0,
	}
	...
}
  • 总结:Grule规则使用 when 判断条件, 当条件满足时执行 then

编写计费规则代码

  • 仿照示例代码,编写计费规则代码

    • 对云服务器 cpu 计费, 每小时 0.05元 * 核数
    • 对云服务器 内存 计费, 每小时 0.01元 * GB
    go 复制代码
    const (
      rule = `
      rule CalculateCost "Calculate the total cost based on CPU and Memory usage" {
        when 
            CloudResource.CPU > 0 &&
            CloudResource.Memory > 0
        then
            costPerCPUHour = 0.05;
            costPerGBMemoryHour = 0.01;
            cpuCost = CloudResource.CPU * costPerCPUHour;
            memoryCost = CloudResource.Memory * costPerGBMemoryHour;
            CloudResource.TotalCost = cpuCost + memoryCost;
            Retract("CalculateCost");
      }
      `
    )
    • cpu 内存 总费用 封装为结构体
    go 复制代码
    type CloudResource struct {
        CPU       float64
        Memory    float64
        TotalCost float64
    }
  • 使用 go test 执行完整代码

go 复制代码
package example

import (
    "testing"

    "github.com/hyperjumptech/grule-rule-engine/ast"
    "github.com/hyperjumptech/grule-rule-engine/builder"
    "github.com/hyperjumptech/grule-rule-engine/engine"
    "github.com/hyperjumptech/grule-rule-engine/pkg"
    "github.com/stretchr/testify/assert"
)

const (
    rule = `
rule CalculateCost "Calculate the total cost based on CPU and Memory usage" {
    when 
        CloudResource.CPU > 0 &&
        CloudResource.Memory > 0
    then
        costPerCPUHour = 0.05;
        costPerGBMemoryHour = 0.01;
        cpuCost = CloudResource.CPU * costPerCPUHour;
        memoryCost = CloudResource.Memory * costPerGBMemoryHour;
        CloudResource.TotalCost = cpuCost + memoryCost;
        Retract("CalculateCost");
}
`
)

type CloudResource struct {
    CPU       float64
    Memory    float64
    TotalCost float64
}

func TestCloudResource(t *testing.T) {
    myResource := &CloudResource{
        CPU:    2,
        Memory: 4,
    }
    dataContext := ast.NewDataContext()
    err := dataContext.Add("CloudResource", myResource)
    if err != nil {
        t.Fatal(err)
    }
    lib := ast.NewKnowledgeLibrary()
    ruleBuilder := builder.NewRuleBuilder(lib)
    err = ruleBuilder.BuildRuleFromResource("Test", "0.1.1", pkg.NewBytesResource([]byte(rule)))
    assert.NoError(t, err)
    kb, err := lib.NewKnowledgeBaseInstance("Test", "0.1.1")
    assert.NoError(t, err)
    eng1 := &engine.GruleEngine{MaxCycle: 1}
    err = eng1.Execute(dataContext, kb)
    assert.NoError(t, err)

    // 檢查計算出的總成本
    expectedTotalCost := (2 * 0.05) + (4 * 0.01)
    assert.Equal(t, expectedTotalCost, myResource.TotalCost)
}
  • 总结: 使用 assert.Equal 校验 expectedTotalCost ,最后得出结果
shell 复制代码
$ go test
PASS
ok      grule_study/example/test        0.007s
相关推荐
Highcharts.js1 小时前
缺失数据可视化图表开发实战|Highcharts创建人员出生统计面积图表示例
开发语言·前端·javascript·信息可视化·highcharts·图表开发
测试员周周6 小时前
【Appium 系列】第16节-WebView-H5上下文切换 — 混合应用的自动化难点
运维·开发语言·人工智能·功能测试·appium·自动化·测试用例
Mahir088 小时前
Spring 循环依赖深度解密:从问题本质到三级缓存源码级解析
java·后端·spring·缓存·面试·循环依赖·三级缓存
杜子不疼.8 小时前
【C++ AI 大模型接入 SDK】 - DeepSeek 模型接入(上)
开发语言·c++·chatgpt
加号38 小时前
【C#】 串口通信技术深度解析及实现
开发语言·c#
sycmancia9 小时前
Qt——编辑交互功能的实现
开发语言·qt
石山代码9 小时前
C++ 内存分区 堆区
java·开发语言·c++
无风听海10 小时前
C# 隐式转换深度解析
java·开发语言·c#
一只大袋鼠10 小时前
Git 进阶(二):分支管理、暂存栈、远程仓库与多人协作
java·开发语言·git
LuminousCPP11 小时前
数据结构 - 线性表第四篇:C 语言通讯录优化升级全记录(踩坑 + 思考)
c语言·开发语言·数据结构·经验分享·笔记·学习