<commit_before>package watch

import (
	"context"
	"fmt"
	"io"
	"sync"
	"time"

	consulapi "github.com/hashicorp/consul/api"
	"github.com/mitchellh/mapstructure"
)

const DefaultTimeout = 10 * time.Second

// Plan is the parsed version of a watch specification. A watch provides
// the details of a query, which generates a view into the Consul data store.
// This view is watched for changes and a handler is invoked to take any
// appropriate actions.
type Plan struct {
	Datacenter  string
	Token       string
	Type        string
	HandlerType string
	Exempt      map[string]interface{}

	Watcher WatcherFunc
	// Handler is kept for backward compatibility but only supports watches based
	// on index param. To support hash based watches, set HybridHandler instead.
	Handler       HandlerFunc
	HybridHandler HybridHandlerFunc
	LogOutput     io.Writer

	address      string
	client       *consulapi.Client
	lastParamVal BlockingParamVal
	lastResult   interface{}

	stop       bool
	stopCh     chan struct{}
	stopLock   sync.Mutex
	cancelFunc context.CancelFunc
}

type HttpHandlerConfig struct {
	Path          string              `mapstructure:"path"`
	Method        string              `mapstructure:"method"`
	Timeout       time.Duration       `mapstructure:"-"`
	TimeoutRaw    string              `mapstructure:"timeout"`
	Header        map[string][]string `mapstructure:"header"`
	TLSSkipVerify bool                `mapstructure:"tls_skip_verify"`
}

// BlockingParamVal is an interface representing the common operations needed for
// different styles of blocking. It's used to abstract the core watch plan from
// whether we are performing index-based or hash-based blocking.
type BlockingParamVal interface {
	// Equal returns whether the other param value should be considered equal
	// (i.e. representing no change in the watched resource). Equal must not panic
	// if other is nil.
	Equal(other BlockingParamVal) bool

	// Next is called when deciding which value to use on the next blocking call.
	// It assumes the BlockingParamVal value it is called on is the most recent one
	// returned and passes the previous one which may be nil as context. This
	// allows types to customize logic around ordering without assuming there is
	// an order. For example WaitIndexVal can check that the index didn't go
	// backwards and if it did then reset to 0. Most other cases should just
	// return themselves (the most recent value) to be used in the next request.
	Next(previous BlockingParamVal) BlockingParamVal
}

// WaitIndexVal is a type representing a Consul index that implements
// BlockingParamVal.
type WaitIndexVal uint64

// Equal implements BlockingParamVal
func (idx WaitIndexVal) Equal(other BlockingParamVal) bool {
	if otherIdx, ok := other.(WaitIndexVal); ok {
		return idx == otherIdx
	}
	return false
}

// Next implements BlockingParamVal
func (idx WaitIndexVal) Next(previous BlockingParamVal) BlockingParamVal {
	if previous == nil {
		return idx
	}
	prevIdx, ok := previous.(WaitIndexVal)
	if ok && prevIdx > idx {
		// This value is smaller than the previous index, reset.
		return WaitIndexVal(0)
	}
	return idx
}

// WaitHashVal is a type representing a Consul content hash that implements
// BlockingParamVal.
type WaitHashVal string

// Equal implements BlockingParamVal
func (h WaitHashVal) Equal(other BlockingParamVal) bool {
	if otherHash, ok := other.(WaitHashVal); ok {
		return h == otherHash
	}
	return false
}

// Next implements BlockingParamVal
func (h WaitHashVal) Next(previous BlockingParamVal) BlockingParamVal {
	return h
}

// WatcherFunc is used to watch for a diff.<commit_msg>agent: fix watch event behavior (#5265)<commit_after>package watch

import (
	"context"
	"fmt"
	"io"
	"sync"
	"time"

	consulapi "github.com/hashicorp/consul/api"
	"github.com/mitchellh/mapstructure"
)

const DefaultTimeout = 10 * time.Second

// Plan is the parsed version of a watch specification. A watch provides
// the details of a query, which generates a view into the Consul data store.
// This view is watched for changes and a handler is invoked to take any
// appropriate actions.
type Plan struct {
	Datacenter  string
	Token       string
	Type        string
	HandlerType string
	Exempt      map[string]interface{}

	Watcher WatcherFunc
	// Handler is kept for backward compatibility but only supports watches based
	// on index param. To support hash based watches, set HybridHandler instead.
	Handler       HandlerFunc
	HybridHandler HybridHandlerFunc
	LogOutput     io.Writer

	address      string
	client       *consulapi.Client
	lastParamVal BlockingParamVal
	lastResult   interface{}

	stop       bool
	stopCh     chan struct{}
	stopLock   sync.Mutex
	cancelFunc context.CancelFunc
}

type HttpHandlerConfig struct {
	Path          string              `mapstructure:"path"`
	Method        string              `mapstructure:"method"`
	Timeout       time.Duration       `mapstructure:"-"`
	TimeoutRaw    string              `mapstructure:"timeout"`
	Header        map[string][]string `mapstructure:"header"`
	TLSSkipVerify bool                `mapstructure:"tls_skip_verify"`
}

// BlockingParamVal is an interface representing the common operations needed for
// different styles of blocking. It's used to abstract the core watch plan from
// whether we are performing index-based or hash-based blocking.
type BlockingParamVal interface {
	// Equal returns whether the other param value should be considered equal
	// (i.e. representing no change in the watched resource). Equal must not panic
	// if other is nil.
	Equal(other BlockingParamVal) bool

	// Next is called when deciding which value to use on the next blocking call.
	// It assumes the BlockingParamVal value it is called on is the most recent one
	// returned and passes the previous one which may be nil as context. This
	// allows types to customize logic around ordering without assuming there is
	// an order. For example WaitIndexVal can check that the index didn't go
	// backwards and if it did then reset to 0. Most other cases should just
	// return themselves (the most recent value) to be used in the next request.
	Next(previous BlockingParamVal) BlockingParamVal
}

// WaitIndexVal is a type representing a Consul index that implements
// BlockingParamVal.
type WaitIndexVal uint64

// Equal implements BlockingParamVal
func (idx WaitIndexVal) Equal(other BlockingParamVal) bool {
	if otherIdx, ok := other.(WaitIndexVal); ok {
		return idx == otherIdx
	}
	return false
}

// Next implements BlockingParamVal
func (idx WaitIndexVal) Next(previous BlockingParamVal) BlockingParamVal {
	if previous == nil {
		return idx
	}
	prevIdx, ok := previous.(WaitIndexVal)
	if ok && prevIdx == idx {
		// This value is the same as the previous index, reset
		return WaitIndexVal(0)
	}
	return idx
}

// WaitHashVal is a type representing a Consul content hash that implements
// BlockingParamVal.
type WaitHashVal string

// Equal implements BlockingParamVal
func (h WaitHashVal) Equal(other BlockingParamVal) bool {
	if otherHash, ok := other.(WaitHashVal); ok {
		return h == otherHash
	}
	return false
}

// Next implements BlockingParamVal
func (h WaitHashVal) Next(previous BlockingParamVal) BlockingParamVal {
	return h
}

// WatcherFunc is used to watch for a diff.
{'fraction_non_alphanumeric': 0.06641965143406066, 'fraction_numerical': 0.002195690956497873, 'mean_word_length': 3.50990099009901, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, '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': '2439001', 'n_tokens_mistral': 2022, 'n_tokens_neox': 1959, 'n_words': 837}