<commit_before>package serf

import (
	"fmt"
	"github.com/hashicorp/memberlist"
	"log"
	"sync"
	"time"
)

type MemberStatus int

const (
	StatusNone MemberStatus = iota
	StatusAlive
	StatusLeaving
	StatusLeft
	StatusFailed
	StatusPartitioned // Partitioned is a best guess, should be treated as failed
)

type Serf struct {
	conf       *Config
	memberlist *memberlist.Memberlist
	joinCh     chan *memberlist.Node
	leaveCh    chan *memberlist.Node
	shutdownCh chan struct{}

	memberLock sync.RWMutex
	members    []*Member
	memberMap  map[string]*Member

	detector partitionDetector

	broadcasts *memberlist.TransmitLimitedQueue

	changeCh chan statusChange
}

// Member represents a single member in the gossip pool
type Member struct {
	Name   string
	Addr   []byte
	Role   string
	Status MemberStatus
}

type EventDelegate interface {
	// MembersJoined invoked when members have joined the cluster
	MembersJoined([]*Member)

	// MembersLeft invoked when members have left the cluster gracefully
	MembersLeft([]*Member)

	// MembersFailed invoked when members are unreachable by the cluster without
	// previously announcing their intention to leave
	MembersFailed([]*Member)

	// MembersPartitioned invoked when members are unreachable by cluster without
	// previously announcing their intention to leave. Partitions are impossible
	// to tell apart from failures, so this is more of a heuristic based on the
	// likelyhood of simultaneous failures. It should not be treated as exact.
	MembersPartitioned([]*Member)
}

// newSerf is used to construct a serf struct from its config
func newSerf(conf *Config) *Serf {
	serf := &Serf{
		conf:       conf,
		joinCh:     make(chan *memberlist.Node, 64),
		leaveCh:    make(chan *memberlist.Node, 64),
		shutdownCh: make(chan struct{}),
		memberMap:  make(map[string]*Member),
		changeCh:   make(chan statusChange, 1024),
	}

	// Select a partition detector
	if conf.PartitionCount > 0 && conf.PartitionInterval > 0 {<commit_msg>Added comment about thread safety. Increase channel buffers.<commit_after>package serf

import (
	"fmt"
	"github.com/hashicorp/memberlist"
	"log"
	"sync"
	"time"
)

type MemberStatus int

const (
	StatusNone MemberStatus = iota
	StatusAlive
	StatusLeaving
	StatusLeft
	StatusFailed
	StatusPartitioned // Partitioned is a best guess, should be treated as failed
)

type Serf struct {
	conf       *Config
	memberlist *memberlist.Memberlist
	joinCh     chan *memberlist.Node
	leaveCh    chan *memberlist.Node
	shutdownCh chan struct{}

	memberLock sync.RWMutex
	members    []*Member
	memberMap  map[string]*Member

	detector partitionDetector

	broadcasts *memberlist.TransmitLimitedQueue

	changeCh chan statusChange
}

// Member represents a single member in the gossip pool
type Member struct {
	Name   string
	Addr   []byte
	Role   string
	Status MemberStatus
}

// EventDelegate is the interface that must be implemented by a client that wants to
// receive coalesced event notifications. These methods will never be called concurrently.
// New events will not be coalesced until the delegate returns, so the delegate should minimize
// time spent in the callbacks.
type EventDelegate interface {
	// MembersJoined invoked when members have joined the cluster
	MembersJoined([]*Member)

	// MembersLeft invoked when members have left the cluster gracefully
	MembersLeft([]*Member)

	// MembersFailed invoked when members are unreachable by the cluster without
	// previously announcing their intention to leave
	MembersFailed([]*Member)

	// MembersPartitioned invoked when members are unreachable by cluster without
	// previously announcing their intention to leave. Partitions are impossible
	// to tell apart from failures, so this is more of a heuristic based on the
	// likelyhood of simultaneous failures. It should not be treated as exact.
	MembersPartitioned([]*Member)
}

// newSerf is used to construct a serf struct from its config
func newSerf(conf *Config) *Serf {
	serf := &Serf{
		conf:       conf,
		joinCh:     make(chan *memberlist.Node, 128),
		leaveCh:    make(chan *memberlist.Node, 128),
		shutdownCh: make(chan struct{}),
		memberMap:  make(map[string]*Member),
		changeCh:   make(chan statusChange, 4096),
	}

	// Select a partition detector
	if conf.PartitionCount > 0 && conf.PartitionInterval > 0 {
{'fraction_non_alphanumeric': 0.07157796885893562, 'fraction_numerical': 0.005112712061352545, 'mean_word_length': 4.136038186157518, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '171988', 'n_tokens_mistral': 1278, 'n_tokens_neox': 1204, 'n_words': 468}