Component Connection Reuse
For example: multiple identical components reuse the same MQTT connection, the same database connection, or the same HTTP endpoint shares the same port, etc.
# Using Shared Resource Nodes
The endpoint
and node
components both support shared resource nodes, and connections are reused through shared resource nodes.
Shared components must implement the SharedNode
interface. Officially provided components, the basic network connection class supports this method.
Reuse the same connection resource through the following methods:
- Initialize the shared resource node. By providing a rule chain file for initialization, the
endpoint
andnode
component clients defined in the rule chain are registered in the shared resource node and reused by other components. For example:
node_pool.DefaultNodePool.Load(dsl []byte)
Example of a global shared node pool rule chain file:
{
"ruleChain": {
"id": "default_node_pool",
"name": "Global Shared Node Pool"
},
"metadata": {
"endpoints": [
{
"id": "local_endpoint_nats",
"type": "endpoint/nats",
"name": "Local NATS Connection Pool",
"configuration": {
"server": "nats://127.0.0.1:4222"
}
}
],
"nodes": [
{
"id": "local_mqtt_client",
"type": "mqttClient",
"name": "Local MQTT Connection Pool",
"configuration": {
"server": "127.0.0.1:1883"
}
},
{
"id": "local_mysql_client",
"type": "dbClient",
"name": "Local MYSQL-test Database Connection Pool",
"configuration": {
"driverName": "mysql",
"dsn": "root:root@tcp(127.0.0.1:3306)/test"
}
},
{
"id": "local_nats",
"type": "x/natsClient",
"name": "Local NATS Connection Pool",
"configuration": {
"server": "nats://127.0.0.1:4222"
}
},
{
"id": "local_rabbitmq",
"type": "x/rabbitmqClient",
"name": "Local RabbitMQ Connection Pool",
"configuration": {
"autoDelete": true,
"durable": true,
"exchange": "rulego",
"exchangeType": "topic",
"server": "amqp://guest:guest@127.0.0.1:5672/"
}
},
{
"id": "local_redis",
"type": "x/redisClient",
"name": "Local Redis Connection Pool",
"configuration": {
"db": 0,
"server": "127.0.0.1:6379"
}
},
{
"id": "local_opengemini_write",
"type": "x/opengeminiWrite",
"name": "Local opengemini_write Connection Pool",
"configuration": {
"database": "db0",
"server": "127.0.0.1:8086"
}
},
{
"id": "local_opengemini_query",
"type": "x/opengeminiQuery",
"name": "Local opengemini_query Connection Pool",
"configuration": {
"database": "db0",
"server": "127.0.0.1:8086"
}
}
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
Other loading methods for node_pool.DefaultNodePool: refer to node_pool.go (opens new window)
- Other components refer to the shared resource connection client through ref://{resourceId}, for example:
{
"id": "node_2",
"type": "mqttClient",
"name": "Test",
"configuration": {
"maxReconnectInterval": 60,
"qOS": 0,
"server": "ref://local_mqtt_client",
"topic": "/device/msg"
}
}
2
3
4
5
6
7
8
9
10
11
# Custom Shared Resource Node Components
The framework encapsulates shared nodes, making it very convenient to encapsulate a component as a shared resource node. Here is an example of an MQTT client node:
- Inherit base.SharedNode[T], where T is the specific type of reusable resource. Example:
type MqttClientNode struct {
base.SharedNode[*mqtt.Client]
// Node configuration
Config MqttClientNodeConfiguration
// Topic template
topicTemplate str.Template
client *mqtt.Client
}
2
3
4
5
6
7
8
- Initialize SharedNode
// Init initializes
func (x *MqttClientNode) Init(ruleConfig types.Config, configuration types.Configuration) error {
err := maps.Map2Struct(configuration, &x.Config)
if err == nil {
_ = x.SharedNode.Init(ruleConfig, x.Type(), x.Config.Server, true, func() (*mqtt.Client, error) {
return x.initClient()
})
x.topicTemplate = str.NewTemplate(x.Config.Topic)
}
return err
}
2
3
4
5
6
7
8
9
10
11
- Initialize the specific type of client
// initClient initializes the client
func (x *MqttClientNode) initClient() (*mqtt.Client, error) {
if x.client != nil {
return x.client, nil
} else {
ctx, cancel := context.WithTimeout(context.TODO(), 4*time.Second)
x.Locker.Lock()
defer func() {
cancel()
x.Locker.Unlock()
}()
if x.client != nil {
return x.client, nil
}
var err error
x.client, err = mqtt.NewClient(ctx, x.Config.ToMqttConfig())
return x.client, err
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Initialize the global reuse node through
node_pool.DefaultNodePool
Reference through ref://{resourceId}
# Difference between Shared Resource Node Components and Node Reference Nodes
- Node Reference Node fully references a specified node instance, including all configurations of the node.
- Shared Resource Node reuses the node's connection instance, but other configurations of the node are independent. For example, MQTT client node, connection class configurations: MQTT address, reconnection interval, etc., are shared, but other configurations in the node configuration, such as the published topic, are independent for each node.