Hunter0x7c7
2022-08-11 b8230139fb40edea387617b6accd8371e37eda58
1
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
85
package taggedfeatures
 
import (
    "context"
    "reflect"
    "sync"
 
    "github.com/v2fly/v2ray-core/v5/common/task"
    "github.com/v2fly/v2ray-core/v5/features"
)
 
type Holder struct {
    access     *sync.RWMutex
    features   map[string]features.Feature
    memberType reflect.Type
    ctx        context.Context
}
 
func NewHolder(ctx context.Context, memberType interface{}) *Holder {
    return &Holder{
        ctx:        ctx,
        access:     &sync.RWMutex{},
        features:   make(map[string]features.Feature),
        memberType: reflect.TypeOf(memberType),
    }
}
 
func (h *Holder) GetFeaturesByTag(tag string) (features.Feature, error) {
    h.access.RLock()
    defer h.access.RUnlock()
    feature, ok := h.features[tag]
    if !ok {
        return nil, newError("unable to find feature with tag")
    }
    return feature, nil
}
 
func (h *Holder) AddFeaturesByTag(tag string, feature features.Feature) error {
    h.access.Lock()
    defer h.access.Unlock()
    featureType := reflect.TypeOf(feature.Type())
    if !featureType.AssignableTo(h.memberType) {
        return newError("feature is not assignable to the base type")
    }
    h.features[tag] = feature
    return nil
}
 
func (h *Holder) RemoveFeaturesByTag(tag string) error {
    h.access.Lock()
    defer h.access.Unlock()
    delete(h.features, tag)
    return nil
}
 
func (h *Holder) GetFeaturesTag() ([]string, error) {
    h.access.RLock()
    defer h.access.RUnlock()
    var ret []string
    for key := range h.features {
        ret = append(ret, key)
    }
    return ret, nil
}
 
func (h *Holder) Start() error {
    h.access.Lock()
    defer h.access.Unlock()
    var startTasks []func() error
    for _, v := range h.features {
        startTasks = append(startTasks, v.Start)
    }
    return task.Run(h.ctx, startTasks...)
}
 
func (h *Holder) Close() error {
    h.access.Lock()
    defer h.access.Unlock()
 
    var closeTasks []func() error
    for _, v := range h.features {
        closeTasks = append(closeTasks, v.Close)
    }
    return task.Run(h.ctx, closeTasks...)
}