go-http-peering/memory/store.go

154 lines
2.7 KiB
Go

package memory
import (
"sync"
"time"
peering "forge.cadoles.com/wpetit/go-http-peering"
)
type Store struct {
peers map[peering.PeerID]*peering.Peer
mutex sync.RWMutex
}
func (s *Store) Create(id peering.PeerID, attrs peering.PeerAttributes) (*peering.Peer, error) {
s.mutex.Lock()
defer s.mutex.Unlock()
if _, exists := s.peers[id]; exists {
return nil, peering.ErrPeerExists
}
peer := &peering.Peer{
PeerHeader: peering.PeerHeader{
ID: id,
Status: peering.StatusPending,
},
Attributes: attrs,
}
s.peers[id] = peer
return copy(peer), nil
}
func (s *Store) Get(id peering.PeerID) (*peering.Peer, error) {
s.mutex.RLock()
defer s.mutex.RUnlock()
peer, exists := s.peers[id]
if !exists {
return nil, peering.ErrPeerNotFound
}
return copy(peer), nil
}
func (s *Store) List() ([]peering.PeerHeader, error) {
s.mutex.RLock()
defer s.mutex.RUnlock()
headers := make([]peering.PeerHeader, len(s.peers))
i := 0
for _, p := range s.peers {
headers[i] = p.PeerHeader
i++
}
return headers, nil
}
func (s *Store) UpdateAttributes(id peering.PeerID, attrs peering.PeerAttributes) error {
s.mutex.Lock()
defer s.mutex.Unlock()
peer, exists := s.peers[id]
if !exists {
return peering.ErrPeerNotFound
}
peer.Attributes = attrs
return nil
}
func (s *Store) UpdateLastContact(id peering.PeerID, remoteAddress string, ts time.Time) error {
s.mutex.Lock()
defer s.mutex.Unlock()
peer, exists := s.peers[id]
if !exists {
return peering.ErrPeerNotFound
}
peer.LastAddress = remoteAddress
peer.LastContact = ts
return nil
}
func (s *Store) UpdatePublicKey(id peering.PeerID, publicKey []byte) error {
s.mutex.Lock()
defer s.mutex.Unlock()
peer, exists := s.peers[id]
if !exists {
return peering.ErrPeerNotFound
}
peer.PublicKey = publicKey
return nil
}
func (s *Store) Delete(id peering.PeerID) error {
s.mutex.Lock()
defer s.mutex.Unlock()
if _, exists := s.peers[id]; !exists {
return peering.ErrPeerNotFound
}
delete(s.peers, id)
return nil
}
func (s *Store) Accept(id peering.PeerID) error {
return s.updateStatus(id, peering.StatusPeered)
}
func (s *Store) Forget(id peering.PeerID) error {
return s.updateStatus(id, peering.StatusPending)
}
func (s *Store) Reject(id peering.PeerID) error {
return s.updateStatus(id, peering.StatusRejected)
}
func (s *Store) updateStatus(id peering.PeerID, status peering.PeerStatus) error {
s.mutex.Lock()
defer s.mutex.Unlock()
peer, exists := s.peers[id]
if !exists {
return peering.ErrPeerNotFound
}
peer.Status = status
return nil
}
func NewStore() *Store {
return &Store{
peers: make(map[peering.PeerID]*peering.Peer),
}
}
func copy(p *peering.Peer) *peering.Peer {
copy := *p
return &copy
}