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
相关推荐
brzhang11 分钟前
宝藏发现:Sim Studio,一款让AI工作流搭建变简单的开源利器
前端·后端·github
这里有鱼汤13 分钟前
出大事了!0.1 + 0.2 居然不等于 0.3,Python我再也不敢用了…
后端·python
刚入门的大一新生13 分钟前
C++初阶-模板初阶
开发语言·数据结构·c++
学了就忘23 分钟前
Axios 传参与 Spring Boot 接收参数完全指南
java·spring boot·后端·vue
这里有鱼汤26 分钟前
我用Python做了个“灵犀剪贴”:可以自动记录复制的文本,然后保存到本地
后端·python
冼紫菜33 分钟前
[特殊字符] SpringCloud项目中使用OpenFeign进行微服务远程调用详解(含连接池与日志配置)
java·后端·spring cloud
-白 泽-38 分钟前
2个小时1.5w字| React & Golang 全栈微服务实战
react.js·微服务·golang
Dxy12393102161 小时前
Python对字典列表按某个字段排序
开发语言·python
.hopeful.1 小时前
基于QT的仿QQ音乐播放器
开发语言·c++·qt
风象南1 小时前
SpringBoot中4种登录验证码实现方案
java·spring boot·后端