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
相关推荐
懂点Tech6 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
云和数据.ChenGuang6 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
美狐美颜SDK开放平台7 小时前
视频美颜SDK试用DEMO阶段应该测试什么?直播APP接入实操指南
开发语言·人工智能·深度学习·音视频·美颜sdk·直播美颜sdk·第三方美颜sdk
dtq04247 小时前
C++小案例 - 日志实战
开发语言·c++
星夜离尘568 小时前
MATLAB ADC 码流触顶诊断:命中数、缺口分段与削顶不可辨识性
开发语言·matlab
码匠许师傅8 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
Cosolar9 小时前
不收费、不加水印、数据归你:我做了个开源的在线简历工具
后端·面试·前端框架
码匠许师傅9 小时前
【C++三方组件】POCO:跨平台系统编程全家桶
开发语言·c++
bkspiderx10 小时前
基于Socket的广播通信及C语言实现详解
c语言·开发语言·socket·广播·socket的广播通信
小王C语言10 小时前
Qt常用控件:输入类控件,单行/多行输入框、下拉框、(日期)微调框、旋钮、滑动条
开发语言·qt