<commit_before>// Copyright (c) 2016 Pulcy.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package service

import (
	"time"

	"github.com/coreos/etcd/client"
	"github.com/giantswarm/retry-go"
	"golang.org/x/net/context"
)

const (
	maxRecentWatcherErrors = 5 // Number of recent errors before the watcher is discarded and rebuild
)

// tryBecomeMaster tries to create a value in ETCD under the master key.
// On success, we're the master, otherwise we're the slave.
func (s *Service) tryBecomeMaster() (bool, string, error) {
	kAPI := client.NewKeysAPI(s.client)
	options := &client.SetOptions{
		PrevExist: client.PrevNoExist,
		TTL:       s.MasterTTL,
	}
	if _, err := kAPI.Set(context.Background(), s.masterKey, s.ourRedisUrl, options); isEtcdError(err, client.ErrorCodeNodeExist) {
		// Node already exists, we're not the master
		// Try to read the current master URL and return it
		resp, err := kAPI.Get(context.Background(), s.masterKey, nil)
		if err != nil {
			return false, "", maskAny(err)
		}
		return false, resp.Node.Value, nil
	} else if err != nil {
		// Another error occurred
		return false, "", maskAny(err)
	}

	// Success, we're the master
	return true, "", nil
}

// updateMaster tries to update the master key
func (s *Service) updateMaster() error {
	update := func() error {
		kAPI := client.NewKeysAPI(s.client)
		options := &client.SetOptions{
			PrevValue: s.ourRedisUrl,
			PrevExist: client.PrevExist,
			TTL:       s.MasterTTL,
			//Refresh:   true,
		}
		if _, err := kAPI.Set(context.Background(), s.masterKey, s.ourRedisUrl, options); err != nil {
			// An error occurred
			return maskAny(err)
		}
		return nil
	}

	if err := retry.Do(update,<commit_msg>Fail faster on key-not-found errors<commit_after>// Copyright (c) 2016 Pulcy.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package service

import (
	"time"

	"github.com/coreos/etcd/client"
	"github.com/giantswarm/retry-go"
	"golang.org/x/net/context"
)

const (
	maxRecentWatcherErrors = 5 // Number of recent errors before the watcher is discarded and rebuild
)

// tryBecomeMaster tries to create a value in ETCD under the master key.
// On success, we're the master, otherwise we're the slave.
func (s *Service) tryBecomeMaster() (bool, string, error) {
	kAPI := client.NewKeysAPI(s.client)
	options := &client.SetOptions{
		PrevExist: client.PrevNoExist,
		TTL:       s.MasterTTL,
	}
	if _, err := kAPI.Set(context.Background(), s.masterKey, s.ourRedisUrl, options); isEtcdError(err, client.ErrorCodeNodeExist) {
		// Node already exists, we're not the master
		// Try to read the current master URL and return it
		resp, err := kAPI.Get(context.Background(), s.masterKey, nil)
		if err != nil {
			return false, "", maskAny(err)
		}
		return false, resp.Node.Value, nil
	} else if err != nil {
		// Another error occurred
		return false, "", maskAny(err)
	}

	// Success, we're the master
	return true, "", nil
}

// updateMaster tries to update the master key
func (s *Service) updateMaster() error {
	update := func() error {
		kAPI := client.NewKeysAPI(s.client)
		options := &client.SetOptions{
			PrevValue: s.ourRedisUrl,
			PrevExist: client.PrevExist,
			TTL:       s.MasterTTL,
			//Refresh:   true,
		}
		if _, err := kAPI.Set(context.Background(), s.masterKey, s.ourRedisUrl, options); err != nil {
			// An error occurred
			return maskAny(err)
		}
		return nil
	}

	if err := retry.Do(update,
		// Make sure we fail asap on key-not-found errors
		retry.RetryChecker(func(err error) bool { return !isEtcdError(err, client.ErrorCodeKeyNotFound) }),
{'fraction_non_alphanumeric': 0.1185589519650655, 'fraction_numerical': 0.003930131004366812, 'mean_word_length': 3.5088582677165356, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3342630', 'n_tokens_mistral': 1532, 'n_tokens_neox': 1437, 'n_words': 501}