maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

 1package module
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6	"sync"
 7)
 8
 9// ModSpecificData is a container that allows modules to attach
10// additional context data to framework objects such as SMTP connections
11// without conflicting with each other and ensuring each module
12// gets its own namespace.
13//
14// It must not be used to store stateful objects that may need
15// a specific cleanup routine as ModSpecificData does not provide
16// any lifetime management.
17//
18// Stored data must be serializable to JSON for state persistence
19// e.g. when message is stored in a on-disk queue.
20type ModSpecificData struct {
21	modDataLck sync.RWMutex
22	modData    map[string]interface{}
23}
24
25func (msd *ModSpecificData) modKey(m Module, perInstance bool) string {
26	if !perInstance {
27		return m.Name()
28	}
29	instName := m.InstanceName()
30	if instName == "" {
31		instName = fmt.Sprintf("%x", m)
32	}
33	return m.Name() + "/" + instName
34}
35
36func (msd *ModSpecificData) MarshalJSON() ([]byte, error) {
37	msd.modDataLck.RLock()
38	defer msd.modDataLck.RUnlock()
39	return json.Marshal(msd.modData)
40}
41
42func (msd *ModSpecificData) UnmarshalJSON(b []byte) error {
43	msd.modDataLck.Lock()
44	defer msd.modDataLck.Unlock()
45	return json.Unmarshal(b, &msd.modData)
46}
47
48func (msd *ModSpecificData) Set(m Module, perInstance bool, value interface{}) {
49	key := msd.modKey(m, perInstance)
50	msd.modDataLck.Lock()
51	defer msd.modDataLck.Unlock()
52	if msd.modData == nil {
53		msd.modData = make(map[string]interface{})
54	}
55	msd.modData[key] = value
56}
57
58func (msd *ModSpecificData) Get(m Module, perInstance bool) interface{} {
59	key := msd.modKey(m, perInstance)
60	msd.modDataLck.RLock()
61	defer msd.modDataLck.RUnlock()
62	return msd.modData[key]
63}