func (a *Agent) DeregisterProcessor(name string) {
	a.stateLock.Lock()
	defer a.stateLock.Unlock()
	delete(a.processors, name)
}
Deregister a processor per name. It will not fail if the
processor does not exist.
package gossip
import (
	"fmt"
	"net"
	"net/http"
	"sync"
	"time"
	"github.com/bbva/qed/client"
	"github.com/bbva/qed/log"
	"github.com/bbva/qed/metrics"
	"github.com/hashicorp/memberlist"
	"github.com/prometheus/client_golang/prometheus"
)
type Agent struct {
	stateLock sync.Mutex
	config Config
	Self *Peer
	metrics *metrics.Server
	gossip *memberlist.Memberlist
	broadcasts *memberlist.TransmitLimitedQueue
	topology *Topology
	processors map[string]Processor
	timeout *time.Ticker
	Cache Cache
	In MessageBus
	Out MessageBus
	quitCh chan bool
	Qed *client.HTTPClient
	Notifier Notifier
	SnapshotStore SnapshotStore
	Tasks TasksManager
	log log.Logger
}
func NewAgentFromConfig(conf *Config) (agent *Agent, err error) {
	options, err := configToOptions(conf)
	if err != nil {
		return nil, err
	}
	return NewAgent(options...)
}
func NewAgentFromConfigWithLogger(conf *Config, l log.Logger) (agent *Agent, err error) {
	options, err := configToOptions(conf)
	if err != nil {
		return nil, err
	}
	options = append(options, SetLogger(l))
	return NewAgent(options...)
}
func NewDefaultAgent(conf *Config, qed *client.HTTPClient, s SnapshotStore, t TasksManager, n Notifier, l log.Logger) (*Agent, error) {
	options, err := configToOptions(conf)
	if err != nil {
		return nil, err
	}
	options = append(options, SetQEDClient(qed), SetSnapshotStore(s), SetTasksManager(t), SetNotifier(n), SetLogger(l))
	return NewAgent(options...)
}
func NewAgent(options ...AgentOptionF) (*Agent, error) {
	agent := &Agent{
		quitCh:   make(chan bool),
		topology: NewTopology(),
		log:      log.L(),
	}
	for _, option := range options {
		if err := option(agent); err != nil {
			return nil, err
		}
	}
	agent.In = MessageBus{log: agent.log.Named("bus")}
	agent.Out = MessageBus{log: agent.log.Named("bus")}
	bindIP, bindPort, err := agent.config.AddrParts(agent.config.BindAddr)
	if err != nil {
		return nil, fmt.Errorf("Invalid bind address: %s", err)
	}
	var advertiseIP string
	var advertisePort int
	if agent.config.AdvertiseAddr != "" {
		advertiseIP, advertisePort, err = agent.config.AddrParts(agent.config.AdvertiseAddr)
		if err != nil {
			return nil, fmt.Errorf("Invalid advertise address: %s", err)
		}
	}
	agent.config.MemberlistConfig = memberlist.DefaultLocalConfig()
	agent.config.MemberlistConfig.BindAddr = bindIP
	agent.config.MemberlistConfig.BindPort = bindPort
	agent.config.MemberlistConfig.AdvertiseAddr = advertiseIP
	agent.config.MemberlistConfig.AdvertisePort = advertisePort
	agent.config.MemberlistConfig.Name = agent.config.NodeName
	agent.config.MemberlistConfig.Logger = agent.log.StdLogger(&log.StdLoggerOptions{InferLevels: true})
	agent.config.MemberlistConfig.Delegate = newAgentDelegate(agent, agent.log)
	agent.config.MemberlistConfig.Events = &eventDelegate{agent, agent.log}
	agent.Self = NewPeer(agent.config.NodeName, advertiseIP, uint16(advertisePort), agent.config.Role)
	return agent, nil
}
func (a *Agent) Start() {
	var err error
	if a.metrics != nil {
		a.log.Infof("Starting agent metrics server")
		go func() {
			if err := a.metrics.Start(); err != http.ErrServerClosed {
				a.log.Fatalf("Can't start metrics HTTP server: %s", err)
			}
		}()
	}
	if a.Tasks != nil {
		a.log.Infof("Starting task mamanger loop")
		a.Tasks.Start()
	}
	if a.Notifier != nil {
		a.log.Infof("Starting notifier mamanger loop")
		a.Notifier.Start()
	}
	a.log.Infof("Starting memberlist gossip netwotk")
	a.gossip, err = memberlist.Create(a.config.MemberlistConfig)
	if err != nil {
		a.log.Infof("Error creating the memberlist network; %v", err)
		return
	}
	a.Self, err = ParsePeer(a.gossip.LocalNode())
	if err != nil {
		a.log.Fatalf("Cannot parse peer: %v", err)
	}
	a.log.Infof("Local member %+v", a.Self)
	a.broadcasts = &memberlist.TransmitLimitedQueue{
		NumNodes: func() int {
			return a.gossip.NumMembers()
		},
		RetransmitMult: 2,
	}
	if len(a.config.StartJoin) > 0 {
		a.log.Infof("Trying to joing gossip network with peers %v", a.config.StartJoin)
		n, err := a.Join(a.config.StartJoin)
		if n == 0 || err != nil {
			a.log.Fatalf("Unable to join gossip network because %v", err)
		}
		a.log.Infof("Joined gossip network with %d peers", n)
	}
	a.log.Infof("Starting agent sender loop")
	a.sender()
}
func (a *Agent) RegisterProcessor(name string, p Processor) {
	a.stateLock.Lock()
	defer a.stateLock.Unlock()
	a.processors[name] = p
	a.RegisterMetrics(p.Metrics())
}