1// Copyright 2015 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package rafthttp
16
17import (
18	"fmt"
19	"sync"
20	"time"
21
22	"github.com/coreos/etcd/pkg/types"
23)
24
25type failureType struct {
26	source string
27	action string
28}
29
30type peerStatus struct {
31	id     types.ID
32	mu     sync.Mutex // protect variables below
33	active bool
34	since  time.Time
35}
36
37func newPeerStatus(id types.ID) *peerStatus {
38	return &peerStatus{
39		id: id,
40	}
41}
42
43func (s *peerStatus) activate() {
44	s.mu.Lock()
45	defer s.mu.Unlock()
46	if !s.active {
47		plog.Infof("peer %s became active", s.id)
48		s.active = true
49		s.since = time.Now()
50	}
51}
52
53func (s *peerStatus) deactivate(failure failureType, reason string) {
54	s.mu.Lock()
55	defer s.mu.Unlock()
56	msg := fmt.Sprintf("failed to %s %s on %s (%s)", failure.action, s.id, failure.source, reason)
57	if s.active {
58		plog.Errorf(msg)
59		plog.Infof("peer %s became inactive (message send to peer failed)", s.id)
60		s.active = false
61		s.since = time.Time{}
62		return
63	}
64	plog.Debugf(msg)
65}
66
67func (s *peerStatus) isActive() bool {
68	s.mu.Lock()
69	defer s.mu.Unlock()
70	return s.active
71}
72
73func (s *peerStatus) activeSince() time.Time {
74	s.mu.Lock()
75	defer s.mu.Unlock()
76	return s.since
77}
78