5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-12-23 02:55:39 +00:00

Make threadsafe, add cache

This commit is contained in:
Neil Alexander 2018-12-15 10:39:31 +00:00
parent cdd2e7910a
commit 8b63e841ea
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
2 changed files with 40 additions and 11 deletions

View File

@ -829,16 +829,13 @@ func (a *admin) admin_getMeta(keyString, coordString string) (metadataPayload, e
}
response := make(chan *metadataPayload, 1)
sendMetaRequest := func() {
a.core.metadata.callbacks[key] = metadataCallback{
created: time.Now(),
call: func(meta *metadataPayload) {
defer func() { recover() }()
select {
case response <- meta:
default:
}
},
}
a.core.metadata.addCallback(key, func(meta *metadataPayload) {
defer func() { recover() }()
select {
case response <- meta:
default:
}
})
a.core.metadata.sendMetadata(key, coords, false)
}
a.core.router.doAdmin(sendMetaRequest)

View File

@ -10,7 +10,9 @@ type metadata struct {
myMetadata metadataPayload
myMetadataMutex sync.RWMutex
callbacks map[boxPubKey]metadataCallback
callbacksMutex sync.Mutex
cache map[boxPubKey]metadataPayload
cacheMutex sync.RWMutex
}
type metadataPayload []byte
@ -38,8 +40,20 @@ func (m *metadata) init(core *Core) {
}()
}
// Add a callback
func (m *metadata) addCallback(sender boxPubKey, call func(meta *metadataPayload)) {
m.callbacksMutex.Lock()
defer m.callbacksMutex.Unlock()
m.callbacks[sender] = metadataCallback{
created: time.Now(),
call: call,
}
}
// Handles the callback, if there is one
func (m *metadata) callback(sender boxPubKey, meta metadataPayload) {
m.callbacksMutex.Lock()
defer m.callbacksMutex.Unlock()
if callback, ok := m.callbacks[sender]; ok {
callback.call(&meta)
delete(m.callbacks, sender)
@ -60,10 +74,28 @@ func (m *metadata) setMetadata(meta metadataPayload) {
m.myMetadata = meta
}
// Add metadata into the cache for a node
func (m *metadata) addCachedMetadata(key boxPubKey, payload metadataPayload) {
m.cacheMutex.Lock()
defer m.cacheMutex.Unlock()
m.cache[key] = payload
}
// Get a metadata entry from the cache
func (m *metadata) getCachedMetadata(key boxPubKey) metadataPayload {
m.cacheMutex.RLock()
defer m.cacheMutex.RUnlock()
if meta, ok := m.cache[key]; ok {
return meta
}
return metadataPayload{}
}
// Handles a meta request/response.
func (m *metadata) handleMetadata(meta *sessionMeta) {
if meta.IsResponse {
m.core.metadata.callback(meta.SendPermPub, meta.Metadata)
m.callback(meta.SendPermPub, meta.Metadata)
m.addCachedMetadata(meta.SendPermPub, meta.Metadata)
} else {
m.sendMetadata(meta.SendPermPub, meta.SendCoords, true)
}