<commit_before>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package lxdclient

import (
	"fmt"
	"net"
	"net/url"
	"strings"

	"github.com/lxc/lxd"
	"github.com/lxc/lxd/shared"
)

// TODO(ericsnow) Address licensing.

// addServer adds the given remote info to the provided config.
// The implementation is copied from:
//  https://github.com/lxc/lxd/blob/master/lxc/remote.go
// TODO(ericsnow) Remove this once the lxd code exports it.
func addServer(config *lxd.Config, server string, addr string) error {
	addr, err := fixAddr(addr)
	if err != nil {
		return err
	}

	if config.Remotes == nil {
		config.Remotes = make(map[string]lxd.RemoteConfig)
	}

	/* Actually add the remote */
	config.Remotes[server] = lxd.RemoteConfig{Addr: addr}

	return nil
}

func fixAddr(addr string) (string, error) {
	var r_scheme string
	var r_host string
	var r_port string

	/* Complex remote URL parsing */
	remote_url, err := url.Parse(addr)
	if err != nil {
		return "", err
	}

	if remote_url.Scheme != "" {
		if remote_url.Scheme != "unix" && remote_url.Scheme != "https" {
			r_scheme = "https"
		} else {
			r_scheme = remote_url.Scheme
		}
	} else if addr[0] == '/' {
		r_scheme = "unix"
	} else {
		if !shared.PathExists(addr) {
			r_scheme = "https"
		} else {
			r_scheme = "unix"
		}
	}

	if remote_url.Host != "" {
		r_host = remote_url.Host
	} else {
		r_host = addr
	}

	host, port, err := net.SplitHostPort(r_host)
	if err == nil {
		r_host = host
		r_port = port
	} else {
		r_port = shared.DefaultPort
	}

	if r_scheme == "unix" {
		if addr[0:5] == "unix:" {
			if addr[0:7] == "unix://" {
				if len(addr) > 8 {
					r_host = addr[8:]
				} else {
					r_host = ""
				}
			} else {
				r_host = addr[6:]
			}
		}
		r_port = ""
	}

	if strings.Contains(r_host, ":") && !strings.HasPrefix(r_host, "[") {
		r_host = fmt.Sprintf("[%s]", r_host)
	}

	if r_port != "" {
		addr = r_scheme + "://" + r_host + ":" + r_port
	} else {
		addr = r_scheme + "://" + r_host
	}

	return addr, nil
}
<commit_msg>Fix up a TODO.<commit_after>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package lxdclient

import (
	"fmt"
	"net"
	"net/url"
	"strings"

	"github.com/lxc/lxd"
	"github.com/lxc/lxd/shared"
)

// TODO(ericsnow) This file should be removed as soon as possible.
// It is copied from https://github.com/lxc/lxd/blob/master/lxc/remote.go
// and the code there should instead be exported so we could use it here.

// TODO(ericsnow) Address licensing.

// addServer adds the given remote info to the provided config.
// The implementation is derived from:
//  https://github.com/lxc/lxd/blob/master/lxc/remote.go
// Note that some validation code was removed (we don't need it).
func addServer(config *lxd.Config, server string, addr string) error {
	addr, err := fixAddr(addr)
	if err != nil {
		return err
	}

	if config.Remotes == nil {
		config.Remotes = make(map[string]lxd.RemoteConfig)
	}

	/* Actually add the remote */
	config.Remotes[server] = lxd.RemoteConfig{Addr: addr}

	return nil
}

// fixAddr is the portion of the original addServer function that fixes
// up the provided addr to be a fully qualified URL.
func fixAddr(addr string) (string, error) {
	var r_scheme string
	var r_host string
	var r_port string

	/* Complex remote URL parsing */
	remote_url, err := url.Parse(addr)
	if err != nil {
		return "", err
	}

	if remote_url.Scheme != "" {
		if remote_url.Scheme != "unix" && remote_url.Scheme != "https" {
			r_scheme = "https"
		} else {
			r_scheme = remote_url.Scheme
		}
	} else if addr[0] == '/' {
		r_scheme = "unix"
	} else {
		if !shared.PathExists(addr) {
			r_scheme = "https"
		} else {
			r_scheme = "unix"
		}
	}

	if remote_url.Host != "" {
		r_host = remote_url.Host
	} else {
		r_host = addr
	}

	host, port, err := net.SplitHostPort(r_host)
	if err == nil {
		r_host = host
		r_port = port
	} else {
		r_port = shared.DefaultPort
	}

	if r_scheme == "unix" {
		if addr[0:5] == "unix:" {
			if addr[0:7] == "unix://" {
				if len(addr) > 8 {
					r_host = addr[8:]
				} else {
					r_host = ""
				}
			} else {
				r_host = addr[6:]
			}
		}
		r_port = ""
	}

	if strings.Contains(r_host, ":") && !strings.HasPrefix(r_host, "[") {
		r_host = fmt.Sprintf("[%s]", r_host)
	}

	if r_port != "" {
		addr = r_scheme + "://" + r_host + ":" + r_port
	} else {
		addr = r_scheme + "://" + r_host
	}

	return addr, nil
}
<|endoftext|>


<commit_before>package handyfile

import (
	"hash/crc32"
	"io/ioutil"
	"os"
	"io"
)

func Checksum32(path string) uint32 {
	file, _ := os.Open(path)
	defer file.Close()
	c := crc32.NewIEEE()
	bytes, _ := ioutil.ReadAll(file)
	withcrc := c.Sum(bytes)
	return crc32.ChecksumIEEE(withcrc)
}

func Exists(path string) bool {
	_, err := os.Stat(path)
	return os.IsNotExist(err)
}

func Copy(src, dest string) error {
	fsrc, err := os.Open(src)
	if err != nil {
		return err
	}
	defer fsrc.Close()

	fdest, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer fdest.Close()

	if _, err := io.Copy(fdest, fsrc); err != nil {
		return err
	}

	return nil
}
<commit_msg>Go fmt.<commit_after>package handyfile

import (
	"hash/crc32"
	"io"
	"io/ioutil"
	"os"
)

func Checksum32(path string) uint32 {
	file, _ := os.Open(path)
	defer file.Close()
	c := crc32.NewIEEE()
	bytes, _ := ioutil.ReadAll(file)
	withcrc := c.Sum(bytes)
	return crc32.ChecksumIEEE(withcrc)
}

func Exists(path string) bool {
	_, err := os.Stat(path)
	return os.IsNotExist(err)
}

func Copy(src, dest string) error {
	fsrc, err := os.Open(src)
	if err != nil {
		return err
	}
	defer fsrc.Close()

	fdest, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer fdest.Close()

	if _, err := io.Copy(fdest, fsrc); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package authy

// NewUserReq used to make NewUser API call
type NewUserReq struct {
	User *User `json:"user"`
}

// NewUserResp for JSON new user response
type NewUserResp struct {
	User    *User             `json:"user"`
	Errors  map[string]string `json:"errors",omitempty`
	Message string            `json:"message",omitempty`
	Success bool              `json:"success",omitempty`
}

// VerifyReq used to make token verification API call
type VerifyReq struct {
	Token        string `json:"token"`
	AuthyID      int    `json:"authy_id"`
	Force        bool   `json:"-"`
	CustomAction string `json:"-"`
}

// VerifyResp for JSON token verification response
type VerifyResp struct {
	Token   string            `json:"token"`
	Errors  map[string]string `json:"errors",omitempty`
	Message string            `json:"message",omitempty`
	Success bool              `json:"success",omitempty`
}

// SMSReq used to make SMS token API call
type SMSReq struct {
	AuthyID      int    `json:"authy_id"`
	Force        bool   `json:"-"`
	Shortcode    bool   `json:"-"`
	CustomAction string `json:"-"`
}

// SMSResp for JSON SMS token response
type SMSResp struct {
	Errors    map[string]string `json:"errors",omitempty`
	Message   string            `json:"message",omitempty`
	Cellphone string            `json:"cellphone",omitempty`
	Success   bool              `json:"success",omitempty`
}

// CallReq for phone call token API call
type CallReq struct {
	AuthyID int  `json:"authy_id"`
	Force   bool `json:"-"`
}

// CallResp for JSON call token response
type CallResp struct {
	Errors  map[string]string `json:"errors",omitempty`
	Message string            `json:"message",omitempty`
	Success bool              `json:"success",omitempty`
}

// UsersStatus nested JSON user status response
type UsersStatus struct {
	AuthyID     int      `json:"authy_id"`
	Confirmed   bool     `json:"confirmed"`
	Registered  bool     `json:"registered"`
	CountryCode int      `json:"country_code"`
	PhoneNumber string   `json:"phone_number"`
	Devices     []string `json:"devices"`
}

// UserStatusReq for user status API call
type UserStatusReq struct {
	AuthyID int `json:"authy_id"`
}

// UserStatusResp for JSON user status response
type UserStatusResp struct {
	Status  *UsersStatus `json:"status"`
	Message string       `json:"message",omitempty`
	Success bool         `json:"success",omitempty`
}

// UserRemoveReq for delete user API call
type UserRemoveReq struct {
	AuthyID int `json:"authy_id"`
}

// UserRemoveResp for JSON delete user response
type UserRemoveResp struct {
	Message string `json:"message",omitempty`
	Success bool   `json:"success",omitempty`
}

// AppDetails for App details JSON response
type AppDetails struct {
	Name       string `json:"name"`
	Plan       string `json:"plan"`
	SmsEnabled bool   `json:"sms_enabled"`
	WhiteLabel bool   `json:"white_label"`
}

// AppDetailsResp for JSON app details response
type AppDetailsResp struct {
	App     *AppDetails `json:"app"`
	Message string      `json:"message",omitempty`
	Success bool        `json:"success",omitempty`
}

// AppStat returned as slice in AppStatsResp
type AppStat struct {
	SmsCount   int    `json"sms_count"`
	UsersCount int    `json:"users_count"`
	Month      string `json"month"`
	Year       int    `json:"year"`
}

// AppStatsResp for JSON app stats response
type AppStatsResp struct {
	Stats   []*AppStat `json:"stats"`
	Message string     `json:"message",omitempty`
	Success bool       `json:"success",omitempty`
}

// RegisterActivityResp for JSON activity response
type RegisterActivityResp struct {
	Message string            `json:"message",omitempty`
	Success bool              `json:"success",omitempty`
	Errors  map[string]string `json:"errors",omitempty`
}
<commit_msg>Add cellphone to call api response<commit_after>package authy

// NewUserReq used to make NewUser API call
type NewUserReq struct {
	User *User `json:"user"`
}

// NewUserResp for JSON new user response
type NewUserResp struct {
	User    *User             `json:"user"`
	Errors  map[string]string `json:"errors",omitempty`
	Message string            `json:"message",omitempty`
	Success bool              `json:"success",omitempty`
}

// VerifyReq used to make token verification API call
type VerifyReq struct {
	Token        string `json:"token"`
	AuthyID      int    `json:"authy_id"`
	Force        bool   `json:"-"`
	CustomAction string `json:"-"`
}

// VerifyResp for JSON token verification response
type VerifyResp struct {
	Token   string            `json:"token"`
	Errors  map[string]string `json:"errors",omitempty`
	Message string            `json:"message",omitempty`
	Success bool              `json:"success",omitempty`
}

// SMSReq used to make SMS token API call
type SMSReq struct {
	AuthyID      int    `json:"authy_id"`
	Force        bool   `json:"-"`
	Shortcode    bool   `json:"-"`
	CustomAction string `json:"-"`
}

// SMSResp for JSON SMS token response
type SMSResp struct {
	Errors    map[string]string `json:"errors",omitempty`
	Message   string            `json:"message",omitempty`
	Cellphone string            `json:"cellphone",omitempty`
	Success   bool              `json:"success",omitempty`
}

// CallReq for phone call token API call
type CallReq struct {
	AuthyID int  `json:"authy_id"`
	Force   bool `json:"-"`
}

// CallResp for JSON call token response
type CallResp struct {
	Errors    map[string]string `json:"errors",omitempty`
	Message   string            `json:"message",omitempty`
	Success   bool              `json:"success",omitempty`
	Cellphone string            `json:"cellphone",omitempty`
}

// UsersStatus nested JSON user status response
type UsersStatus struct {
	AuthyID     int      `json:"authy_id"`
	Confirmed   bool     `json:"confirmed"`
	Registered  bool     `json:"registered"`
	CountryCode int      `json:"country_code"`
	PhoneNumber string   `json:"phone_number"`
	Devices     []string `json:"devices"`
}

// UserStatusReq for user status API call
type UserStatusReq struct {
	AuthyID int `json:"authy_id"`
}

// UserStatusResp for JSON user status response
type UserStatusResp struct {
	Status  *UsersStatus `json:"status"`
	Message string       `json:"message",omitempty`
	Success bool         `json:"success",omitempty`
}

// UserRemoveReq for delete user API call
type UserRemoveReq struct {
	AuthyID int `json:"authy_id"`
}

// UserRemoveResp for JSON delete user response
type UserRemoveResp struct {
	Message string `json:"message",omitempty`
	Success bool   `json:"success",omitempty`
}

// AppDetails for App details JSON response
type AppDetails struct {
	Name       string `json:"name"`
	Plan       string `json:"plan"`
	SmsEnabled bool   `json:"sms_enabled"`
	WhiteLabel bool   `json:"white_label"`
}

// AppDetailsResp for JSON app details response
type AppDetailsResp struct {
	App     *AppDetails `json:"app"`
	Message string      `json:"message",omitempty`
	Success bool        `json:"success",omitempty`
}

// AppStat returned as slice in AppStatsResp
type AppStat struct {
	SmsCount   int    `json"sms_count"`
	UsersCount int    `json:"users_count"`
	Month      string `json"month"`
	Year       int    `json:"year"`
}

// AppStatsResp for JSON app stats response
type AppStatsResp struct {
	Stats   []*AppStat `json:"stats"`
	Message string     `json:"message",omitempty`
	Success bool       `json:"success",omitempty`
}

// RegisterActivityResp for JSON activity response
type RegisterActivityResp struct {
	Message string            `json:"message",omitempty`
	Success bool              `json:"success",omitempty`
	Errors  map[string]string `json:"errors",omitempty`
}
<|endoftext|>


<commit_before>package config_service

import (
	"strings"
	cfgsvc "github.com/Flipkart/config-service/client-go"
	"github.com/kelseyhightower/confd/log"
	"errors"
	"os"
	"io/ioutil"
	"encoding/json"
)
func defaultConfig() map[string]string {
	config := make(map[string]string)
	defaultConfigFilename := os.Getenv("DEFAULT_CONFIG")
	if _, err := os.Stat(defaultConfigFilename); os.IsNotExist(err) {
		log.Error("File doesn't exist " + defaultConfigFilename)
		return config
	}

	content, err := ioutil.ReadFile(defaultConfigFilename)
	if err!=nil{
		log.Error("Can't read file " + defaultConfigFilename)
		return config
	}

	err=json.Unmarshal(content, &config)
	if err!=nil{
		log.Error("Error:" + err.Error())
	}

	return config

}

// Client provides a wrapper around the zookeeper client
type Client struct {
	client *cfgsvc.ConfigServiceClient
	defaultConfig map[string]string
}

type BucketListener struct{
	watchResp chan *watchResponse
	currentIndex uint64
}

type watchResponse struct {
	waitIndex uint64
	err       error
}

func (this *BucketListener) Connected(bucketName string) {
	log.Info("Connected! " + bucketName)
}

func (this *BucketListener) Disconnected(bucketName string, err error) {
	log.Info("Disconnected! " + bucketName)
	this.watchResp <- &watchResponse{waitIndex:this.currentIndex, err: err}
}

func (this *BucketListener) Deleted(bucketName string) {
	log.Info("deleted " + bucketName)
	this.watchResp <- &watchResponse{waitIndex: 0, err: errors.New(bucketName + " was deleted")}
}

func (this *BucketListener) Updated(oldBucket *cfgsvc.Bucket, newBucket *cfgsvc.Bucket) {
	this.watchResp <- &watchResponse{waitIndex:this.currentIndex+1, err: nil}
}

func NewConfigClient(machines []string) (*Client, error) {
	c, err := cfgsvc.NewConfigServiceClient(machines[0], 50) //*10)
	if err != nil {
		panic(err)
	}
	return &Client{client:c, defaultConfig: defaultConfig()}, nil
}

func (c *Client) GetValues(keys []string) (map[string]string, error) {
	vars := make(map[string]string)
	for k, v := range c.defaultConfig {
		vars[k] = v
	}
	for _, v := range keys {
		bucketKeys := strings.Split(v[1:], "/")

		dynamicBuckets, err := c.getDynamicBuckets(strings.Split(bucketKeys[0], ","))
		if err != nil {
			return vars, err
		}

		for _, dynamicBucket := range dynamicBuckets {
			val := dynamicBucket.GetKeys()[bucketKeys[1]]
			if val != nil {
				value := val.(string)
				vars[bucketKeys[1]] = value
			}
		}

	}
	return vars, nil
}

func (c *Client) getDynamicBuckets(buckets []string) ([]*cfgsvc.DynamicBucket, error) {
	var dynamicBuckets []*cfgsvc.DynamicBucket
	for _, bucket := range buckets {
		bucketName := strings.TrimSpace(bucket)
		dynamicBucket, err := c.client.GetDynamicBucket(bucketName)
		if err != nil {
			return dynamicBuckets, err
		}
		dynamicBuckets = append(dynamicBuckets, dynamicBucket)
	}
	return dynamicBuckets, nil
}

func setupDynamicBucketListeners(dynamicBuckets []*cfgsvc.DynamicBucket, bucketListener *BucketListener) {
	for _, dynamicBucket := range dynamicBuckets {
		dynamicBucket.AddListeners(bucketListener)
	}
}

func removeDynamicBucketListeners(dynamicBuckets []*cfgsvc.DynamicBucket, bucketListener *BucketListener) {
	for _, dynamicBucket := range dynamicBuckets {
		dynamicBucket.RemoveListeners(bucketListener)
	}
}

func (c *Client) WatchPrefix(prefix string, waitIndex uint64, stopChan chan bool) (uint64, error) {
	prefix = strings.TrimPrefix(prefix, "/")
	prefixes := strings.Split(prefix, ",")
	dynamicBuckets, err := c.getDynamicBuckets(prefixes)
	if err != nil {
		return waitIndex, err
	}

	if waitIndex == 0 {
		return waitIndex+1, nil
	}  else {
		watchResp := make(chan *watchResponse)
		bucketListener := &BucketListener{watchResp: watchResp, currentIndex: waitIndex}
		setupDynamicBucketListeners(dynamicBuckets, bucketListener)
		select {
			case watchResp := <- watchResp:
				removeDynamicBucketListeners(dynamicBuckets, bucketListener)
		 		return watchResp.waitIndex, watchResp.err
		    case <-stopChan:
				removeDynamicBucketListeners(dynamicBuckets, bucketListener)
				return 0, nil
		}
	}
}

<commit_msg>Remove default config file<commit_after>package config_service

import (
	"strings"
	cfgsvc "github.com/Flipkart/config-service/client-go"
	"github.com/kelseyhightower/confd/log"
	"errors"
)

// Client provides a wrapper around the zookeeper client
type Client struct {
	client *cfgsvc.ConfigServiceClient
}

type BucketListener struct{
	watchResp chan *watchResponse
	currentIndex uint64
}

type watchResponse struct {
	waitIndex uint64
	err       error
}

func (this *BucketListener) Connected(bucketName string) {
	log.Info("Connected! " + bucketName)
}

func (this *BucketListener) Disconnected(bucketName string, err error) {
	log.Info("Disconnected! " + bucketName)
	this.watchResp <- &watchResponse{waitIndex:this.currentIndex, err: err}
}

func (this *BucketListener) Deleted(bucketName string) {
	log.Info("deleted " + bucketName)
	this.watchResp <- &watchResponse{waitIndex: 0, err: errors.New(bucketName + " was deleted")}
}

func (this *BucketListener) Updated(oldBucket *cfgsvc.Bucket, newBucket *cfgsvc.Bucket) {
	this.watchResp <- &watchResponse{waitIndex:this.currentIndex+1, err: nil}
}

func NewConfigClient(machines []string) (*Client, error) {
	c, err := cfgsvc.NewConfigServiceClient(machines[0], 50) //*10)
	if err != nil {
		panic(err)
	}
	return &Client{c}, nil
}

func (c *Client) GetValues(keys []string) (map[string]string, error) {
	vars := make(map[string]string)
	for _, v := range keys {
		bucketKeys := strings.Split(v[1:], "/")

		dynamicBuckets, err := c.getDynamicBuckets(strings.Split(bucketKeys[0], ","))
		if err != nil {
			return vars, err
		}

		for _, dynamicBucket := range dynamicBuckets {
			val := dynamicBucket.GetKeys()[bucketKeys[1]]
			if val != nil {
				value := val.(string)
				vars[bucketKeys[1]] = value
			}
		}

	}
	return vars, nil
}

func (c *Client) getDynamicBuckets(buckets []string) ([]*cfgsvc.DynamicBucket, error) {
	var dynamicBuckets []*cfgsvc.DynamicBucket
	for _, bucket := range buckets {
		bucketName := strings.TrimSpace(bucket)
		dynamicBucket, err := c.client.GetDynamicBucket(bucketName)
		if err != nil {
			return dynamicBuckets, err
		}
		dynamicBuckets = append(dynamicBuckets, dynamicBucket)
	}
	return dynamicBuckets, nil
}

func setupDynamicBucketListeners(dynamicBuckets []*cfgsvc.DynamicBucket, bucketListener *BucketListener) {
	for _, dynamicBucket := range dynamicBuckets {
		dynamicBucket.AddListeners(bucketListener)
	}
}

func removeDynamicBucketListeners(dynamicBuckets []*cfgsvc.DynamicBucket, bucketListener *BucketListener) {
	for _, dynamicBucket := range dynamicBuckets {
		dynamicBucket.RemoveListeners(bucketListener)
	}
}

func (c *Client) WatchPrefix(prefix string, waitIndex uint64, stopChan chan bool) (uint64, error) {
	prefix = strings.TrimPrefix(prefix, "/")
	prefixes := strings.Split(prefix, ",")
	dynamicBuckets, err := c.getDynamicBuckets(prefixes)
	if err != nil {
		return waitIndex, err
	}

	if waitIndex == 0 {
		return waitIndex+1, nil
	}  else {
		watchResp := make(chan *watchResponse)
		bucketListener := &BucketListener{watchResp: watchResp, currentIndex: waitIndex}
		setupDynamicBucketListeners(dynamicBuckets, bucketListener)
		select {
			case watchResp := <- watchResp:
				removeDynamicBucketListeners(dynamicBuckets, bucketListener)
		 		return watchResp.waitIndex, watchResp.err
		    case <-stopChan:
				removeDynamicBucketListeners(dynamicBuckets, bucketListener)
				return 0, nil
		}
	}
}

<|endoftext|>


<commit_before>package delayd2

import (
	"errors"
	"log"
	"strconv"

	"github.com/aws/aws-sdk-go/service/sqs"
	"github.com/nabeken/aws-go-sqs/queue"
	"github.com/nabeken/aws-go-sqs/queue/option"
)

var ErrInvalidAttributes = errors.New("delayd2: invalid attributes")

const (
	sqsMessageDurationKey = "delayd2-delay"
	sqsMessageRelayToKey  = "delayd2-relay-to"
)

// Consumer represents a SQS message consumer.
type Consumer struct {
	workerID string
	driver   Driver
	queue    *queue.Queue
}

func NewConsumer(workerID string, driver Driver, queue *queue.Queue) *Consumer {
	return &Consumer{
		workerID: workerID,
		driver:   driver,
		queue:    queue,
	}
}

// ConsumeMessages consumes messages in SQS queue.
// It returns the number of consumed message in success.
func (c *Consumer) ConsumeMessages() (int64, error) {
	messages, err := c.queue.ReceiveMessage(
		option.MaxNumberOfMessages(10),
		option.UseAllAttribute(),
	)
	if err != nil {
		return 0, err
	}

	var n int64

	succeededReceiptHandles := make([]*string, 0, len(messages))
	for _, m := range messages {
		duration, relayTo, err := extractDelayd2MessageAttributes(m)
		if err != nil {
			log.Printf("consumer: %s: unable to extract attributes. skipping.", *m.MessageId)
			continue
		}

		err = c.driver.Enqueue(*m.MessageId, duration, relayTo, *m.Body)
		if err != nil && err != ErrMessageDuplicated {
			log.Printf("consumer: %s: unable to enqueue this message. skipping", *m.MessageId)
			continue
		}
		if err == ErrMessageDuplicated {
			// delete immediately if duplicated
			log.Printf("consumer: %s: %s", *m.MessageId, err)
		} else {
			n++
		}

		succeededReceiptHandles = append(succeededReceiptHandles, m.ReceiptHandle)
	}

	if len(succeededReceiptHandles) > 0 {
		if err := c.queue.DeleteMessageBatch(succeededReceiptHandles...); err != nil {
			log.Printf("consumer: unable to delete messages in batch but continuing since messages will appear again: %s", err)
		}
	}
	return n, nil
}

func extractDelayd2MessageAttributes(message *sqs.Message) (int64, string, error) {
	var duration int64
	var relayTo string
	var err error

	durationAttr, found := message.MessageAttributes[sqsMessageDurationKey]
	if !found || *durationAttr.DataType != option.DataTypeNumber {
		return 0, "", ErrInvalidAttributes
	}
	duration, err = strconv.ParseInt(*durationAttr.StringValue, 10, 64)
	if err != nil {
		return 0, "", err
	}

	relayToAttr, found := message.MessageAttributes[sqsMessageRelayToKey]
	if !found || *relayToAttr.DataType != option.DataTypeString {
		return 0, "", ErrInvalidAttributes
	}
	relayTo = *relayToAttr.StringValue

	return duration, relayTo, nil
}
<commit_msg>consumer: Fix not to delete failed message...<commit_after>package delayd2

import (
	"errors"
	"log"
	"strconv"

	"github.com/aws/aws-sdk-go/service/sqs"
	"github.com/nabeken/aws-go-sqs/queue"
	"github.com/nabeken/aws-go-sqs/queue/option"
)

var ErrInvalidAttributes = errors.New("delayd2: invalid attributes")

const (
	sqsMessageDurationKey = "delayd2-delay"
	sqsMessageRelayToKey  = "delayd2-relay-to"
)

// Consumer represents a SQS message consumer.
type Consumer struct {
	workerID string
	driver   Driver
	queue    *queue.Queue
}

func NewConsumer(workerID string, driver Driver, queue *queue.Queue) *Consumer {
	return &Consumer{
		workerID: workerID,
		driver:   driver,
		queue:    queue,
	}
}

// ConsumeMessages consumes messages in SQS queue.
// It returns the number of consumed message in success.
func (c *Consumer) ConsumeMessages() (int64, error) {
	messages, err := c.queue.ReceiveMessage(
		option.MaxNumberOfMessages(10),
		option.UseAllAttribute(),
	)
	if err != nil {
		return 0, err
	}

	var n int64

	succeededReceiptHandles := make([]*string, 0, len(messages))
	for _, m := range messages {
		duration, relayTo, err := extractDelayd2MessageAttributes(m)
		if err != nil {
			log.Printf("consumer: %s: unable to extract attributes. skipping.", *m.MessageId)
			continue
		}

		err = c.driver.Enqueue(*m.MessageId, duration, relayTo, *m.Body)
		if err != nil && err != ErrMessageDuplicated {
			log.Printf("consumer: %s: unable to enqueue this message. skipping", *m.MessageId)
			continue
		}
		if err == ErrMessageDuplicated {
			// delete immediately if duplicated
			log.Printf("consumer: %s: %s", *m.MessageId, err)
		} else {
			succeededReceiptHandles = append(succeededReceiptHandles, m.ReceiptHandle)
			n++
		}
	}

	if len(succeededReceiptHandles) > 0 {
		if err := c.queue.DeleteMessageBatch(succeededReceiptHandles...); err != nil {
			log.Printf("consumer: unable to delete messages in batch but continuing since messages will appear again: %s", err)
		}
	}
	return n, nil
}

func extractDelayd2MessageAttributes(message *sqs.Message) (int64, string, error) {
	var duration int64
	var relayTo string
	var err error

	durationAttr, found := message.MessageAttributes[sqsMessageDurationKey]
	if !found || *durationAttr.DataType != option.DataTypeNumber {
		return 0, "", ErrInvalidAttributes
	}
	duration, err = strconv.ParseInt(*durationAttr.StringValue, 10, 64)
	if err != nil {
		return 0, "", err
	}

	relayToAttr, found := message.MessageAttributes[sqsMessageRelayToKey]
	if !found || *relayToAttr.DataType != option.DataTypeString {
		return 0, "", ErrInvalidAttributes
	}
	relayTo = *relayToAttr.StringValue

	return duration, relayTo, nil
}
<|endoftext|>


<commit_before>package mesoslib

import (
	"fmt"
	"strings"

	"code.google.com/p/goprotobuf/proto"
	"github.com/Sirupsen/logrus"
	"github.com/VoltFramework/volt/mesosproto"
)

func createTaskInfo(offer *mesosproto.Offer, resources []*mesosproto.Resource, args []string, ID, image string) *mesosproto.TaskInfo {
	taskInfo := mesosproto.TaskInfo{
		Name: proto.String(fmt.Sprintf("volt-task-%s", ID)),
		TaskId: &mesosproto.TaskID{
			Value: &ID,
		},
		SlaveId:   offer.SlaveId,
		Resources: resources,
		Command: &mesosproto.CommandInfo{
			Shell: proto.Bool(false),
		},
	}

	// Set value only if provided
	if args[0] != "" {
		taskInfo.Command.Value = &args[0]
	}

	// Set args only if they exist
	if len(args) > 1 {
		taskInfo.Command.Arguments = args[1:]
	}

	// Set the docker image if specified
	if image != "" {
		taskInfo.Container = &mesosproto.ContainerInfo{
			Type: mesosproto.ContainerInfo_DOCKER.Enum(),
			Docker: &mesosproto.ContainerInfo_DockerInfo{
				Image: &image,
			},
		}
	}
	return &taskInfo
}

func (m *MesosLib) LaunchTask(offer *mesosproto.Offer, resources []*mesosproto.Resource, command, ID, image string) error {
	m.Log.WithFields(logrus.Fields{"ID": ID, "command": command, "offerId": offer.Id, "dockerImage": image}).Info("Launching task...")

	taskInfo := createTaskInfo(offer, resources, strings.Split(command, " "), ID, image)

	return m.send(&mesosproto.LaunchTasksMessage{
		FrameworkId: m.frameworkInfo.Id,
		Tasks:       []*mesosproto.TaskInfo{taskInfo},
		OfferIds: []*mesosproto.OfferID{
			offer.Id,
		},
		Filters: &mesosproto.Filters{},
	}, "mesos.internal.LaunchTasksMessage")
}

func (m *MesosLib) KillTask(ID string) error {
	m.Log.WithFields(logrus.Fields{"ID": ID}).Info("Killing task...")

	return m.send(&mesosproto.KillTaskMessage{
		FrameworkId: m.frameworkInfo.Id,
		TaskId: &mesosproto.TaskID{
			Value: &ID,
		},
	}, "mesos.internal.KillTaskMessage")
}
<commit_msg>fix shell behavior<commit_after>package mesoslib

import (
	"fmt"
	"strings"

	"code.google.com/p/goprotobuf/proto"
	"github.com/Sirupsen/logrus"
	"github.com/VoltFramework/volt/mesosproto"
)

func createTaskInfo(offer *mesosproto.Offer, resources []*mesosproto.Resource, args []string, ID, image string) *mesosproto.TaskInfo {
	taskInfo := mesosproto.TaskInfo{
		Name: proto.String(fmt.Sprintf("volt-task-%s", ID)),
		TaskId: &mesosproto.TaskID{
			Value: &ID,
		},
		SlaveId:   offer.SlaveId,
		Resources: resources,
		Command:   &mesosproto.CommandInfo{},
	}

	// Set value only if provided
	if args[0] != "" {
		taskInfo.Command.Value = &args[0]
	}

	// Set args only if they exist
	fmt.Println(len(args))
	if len(args) > 1 {
		taskInfo.Command.Arguments = args[1:]
	}

	// Set the docker image if specified
	if image != "" {
		taskInfo.Container = &mesosproto.ContainerInfo{
			Type: mesosproto.ContainerInfo_DOCKER.Enum(),
			Docker: &mesosproto.ContainerInfo_DockerInfo{
				Image: &image,
			},
		}
		taskInfo.Command.Shell = proto.Bool(false)
	}
	return &taskInfo
}

func (m *MesosLib) LaunchTask(offer *mesosproto.Offer, resources []*mesosproto.Resource, command, ID, image string) error {
	m.Log.WithFields(logrus.Fields{"ID": ID, "command": command, "offerId": offer.Id, "dockerImage": image}).Info("Launching task...")

	taskInfo := createTaskInfo(offer, resources, strings.Split(command, " "), ID, image)

	return m.send(&mesosproto.LaunchTasksMessage{
		FrameworkId: m.frameworkInfo.Id,
		Tasks:       []*mesosproto.TaskInfo{taskInfo},
		OfferIds: []*mesosproto.OfferID{
			offer.Id,
		},
		Filters: &mesosproto.Filters{},
	}, "mesos.internal.LaunchTasksMessage")
}

func (m *MesosLib) KillTask(ID string) error {
	m.Log.WithFields(logrus.Fields{"ID": ID}).Info("Killing task...")

	return m.send(&mesosproto.KillTaskMessage{
		FrameworkId: m.frameworkInfo.Id,
		TaskId: &mesosproto.TaskID{
			Value: &ID,
		},
	}, "mesos.internal.KillTaskMessage")
}
<|endoftext|>


<commit_before>// Package loggables includes a bunch of translator functions for
// commonplace/stdlib objects. This is boilerplate code that shouldn't change
// much, and not sprinkled all over the place (i.e. gather it here).
//
// NOTE: it may make sense to put all stdlib Loggable functions in the eventlog
// package. Putting it here for now in case we don't want to pollute it.
package loggables

import (
	"net"

	uuid "github.com/satori/go.uuid"

	ma "gx/ipfs/QmcobAGsCjYt5DXoq9et9L8yR8er7o7Cu3DTvpaq12jYSz/go-multiaddr"

	logging "gx/ipfs/QmaDNZ4QMdBdku1YZWBysufYyoQt1negQGNav6PLYarbY8/go-log"

	peer "gx/ipfs/QmZwZjMVGss5rqYsJVGy18gNbkTJffFyq2x1uJ4e4p3ZAt/go-libp2p-peer"
)

// NetConn returns an eventlog.Metadata with the conn addresses
func NetConn(c net.Conn) logging.Loggable {
	return logging.Metadata{
		"localAddr":  c.LocalAddr(),
		"remoteAddr": c.RemoteAddr(),
	}
}

// Error returns an eventlog.Metadata with an error
func Error(e error) logging.Loggable {
	return logging.Metadata{
		"error": e.Error(),
	}
}

func Uuid(key string) logging.Metadata {
	return logging.Metadata{
		key: uuid.NewV4().String(),
	}
}

// Dial metadata is metadata for dial events
func Dial(sys string, lid, rid peer.ID, laddr, raddr ma.Multiaddr) DeferredMap {
	m := DeferredMap{}
	m["subsystem"] = sys
	if lid != "" {
		m["localPeer"] = func() interface{} { return lid.Pretty() }
	}
	if laddr != nil {
		m["localAddr"] = func() interface{} { return laddr.String() }
	}
	if rid != "" {
		m["remotePeer"] = func() interface{} { return rid.Pretty() }
	}
	if raddr != nil {
		m["remoteAddr"] = func() interface{} { return raddr.String() }
	}
	return m
}

// DeferredMap is a Loggable which may contain deferred values.
type DeferredMap map[string]interface{}

// Loggable describes objects that can be marshalled into Metadata for logging
func (m DeferredMap) Loggable() map[string]interface{} {
	m2 := map[string]interface{}{}
	for k, v := range m {

		if vf, ok := v.(func() interface{}); ok {
			// if it's a DeferredVal, call it.
			m2[k] = vf()

		} else {
			// else use the value as is.
			m2[k] = v
		}
	}
	return m2
}
<commit_msg>Make sure uuid is vendored<commit_after>// Package loggables includes a bunch of translator functions for
// commonplace/stdlib objects. This is boilerplate code that shouldn't change
// much, and not sprinkled all over the place (i.e. gather it here).
//
// NOTE: it may make sense to put all stdlib Loggable functions in the eventlog
// package. Putting it here for now in case we don't want to pollute it.
package loggables

import (
	"net"

	uuid "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/satori/go.uuid"

	ma "gx/ipfs/QmcobAGsCjYt5DXoq9et9L8yR8er7o7Cu3DTvpaq12jYSz/go-multiaddr"

	logging "gx/ipfs/QmaDNZ4QMdBdku1YZWBysufYyoQt1negQGNav6PLYarbY8/go-log"

	peer "gx/ipfs/QmZwZjMVGss5rqYsJVGy18gNbkTJffFyq2x1uJ4e4p3ZAt/go-libp2p-peer"
)

// NetConn returns an eventlog.Metadata with the conn addresses
func NetConn(c net.Conn) logging.Loggable {
	return logging.Metadata{
		"localAddr":  c.LocalAddr(),
		"remoteAddr": c.RemoteAddr(),
	}
}

// Error returns an eventlog.Metadata with an error
func Error(e error) logging.Loggable {
	return logging.Metadata{
		"error": e.Error(),
	}
}

func Uuid(key string) logging.Metadata {
	return logging.Metadata{
		key: uuid.NewV4().String(),
	}
}

// Dial metadata is metadata for dial events
func Dial(sys string, lid, rid peer.ID, laddr, raddr ma.Multiaddr) DeferredMap {
	m := DeferredMap{}
	m["subsystem"] = sys
	if lid != "" {
		m["localPeer"] = func() interface{} { return lid.Pretty() }
	}
	if laddr != nil {
		m["localAddr"] = func() interface{} { return laddr.String() }
	}
	if rid != "" {
		m["remotePeer"] = func() interface{} { return rid.Pretty() }
	}
	if raddr != nil {
		m["remoteAddr"] = func() interface{} { return raddr.String() }
	}
	return m
}

// DeferredMap is a Loggable which may contain deferred values.
type DeferredMap map[string]interface{}

// Loggable describes objects that can be marshalled into Metadata for logging
func (m DeferredMap) Loggable() map[string]interface{} {
	m2 := map[string]interface{}{}
	for k, v := range m {

		if vf, ok := v.(func() interface{}); ok {
			// if it's a DeferredVal, call it.
			m2[k] = vf()

		} else {
			// else use the value as is.
			m2[k] = v
		}
	}
	return m2
}
<|endoftext|>


<commit_before>// Copyright 2016 Hajime Hoshi
//
// 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 main

import (
	"fmt"
	"image/color"
	"log"
	"time"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
	"github.com/hajimehoshi/ebiten/exp/audio"
	"github.com/hajimehoshi/ebiten/exp/audio/vorbis"
)

const (
	screenWidth  = 320
	screenHeight = 240
)

var (
	playerBarImage     *ebiten.Image
	playerCurrentImage *ebiten.Image
)

func init() {
	var err error
	playerBarImage, err = ebiten.NewImage(300, 4, ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	playerBarImage.Fill(&color.RGBA{0x80, 0x80, 0x80, 0xff})

	playerCurrentImage, err = ebiten.NewImage(4, 10, ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	playerCurrentImage.Fill(&color.RGBA{0xff, 0xff, 0xff, 0xff})
}

var (
	audioContext     *audio.Context
	audioLoadingDone chan struct{}
	audioLoaded      bool
	audioPlayer      *audio.Player
	total            time.Duration
)

func update(screen *ebiten.Image) error {
	audioContext.Update()
	if !audioLoaded {
		select {
		case <-audioLoadingDone:
			audioLoaded = true
		default:
		}
	}

	op := &ebiten.DrawImageOptions{}
	w, h := playerBarImage.Size()
	x := float64(screenWidth-w) / 2
	y := float64(screenHeight - h - 16)
	op.GeoM.Translate(x, y)
	screen.DrawImage(playerBarImage, op)
	if audioLoaded && audioPlayer.IsPlaying() {
		c := audioPlayer.Current()
		w, _ := playerBarImage.Size()
		cw, ch := playerCurrentImage.Size()
		cx := float64(w)*float64(c)/float64(total) + x - float64(cw)/2
		cy := y - float64(ch-h)/2
		op := &ebiten.DrawImageOptions{}
		op.GeoM.Translate(cx, cy)
		screen.DrawImage(playerCurrentImage, op)
	}

	msg := fmt.Sprintf("FPS: %0.2f", ebiten.CurrentFPS())
	if !audioLoaded {
		msg += "\nNow Loading..."
	}
	ebitenutil.DebugPrint(screen, msg)
	return nil
}

func main() {
	// Use a FLAC file so far: I couldn't find any good OGG/Vorbis decoder in pure Go.
	f, err := ebitenutil.OpenFile("_resources/audio/ragtime.ogg")
	if err != nil {
		log.Fatal(err)
	}
	// TODO: sampleRate should be obtained from the ogg file.
	audioContext = audio.NewContext(22050)
	audioLoadingDone = make(chan struct{})
	// TODO: This doesn't work synchronously on browsers because of decoding. Fix this.
	go func() {
		var err error
		s, err := vorbis.Decode(audioContext, f)
		if err != nil {
			log.Fatal(err)
			return
		}
		total = s.Len()
		audioPlayer, err = audioContext.NewPlayer(s)
		if err != nil {
			log.Fatal(err)
			return
		}
		close(audioLoadingDone)
		audioPlayer.Play()
	}()
	if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Audio (Ebiten Demo)"); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>examples/audio: Add the player bar<commit_after>// Copyright 2016 Hajime Hoshi
//
// 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 main

import (
	"fmt"
	"image/color"
	"log"
	"time"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
	"github.com/hajimehoshi/ebiten/exp/audio"
	"github.com/hajimehoshi/ebiten/exp/audio/vorbis"
)

const (
	screenWidth  = 320
	screenHeight = 240
)

var (
	playerBarImage     *ebiten.Image
	playerCurrentImage *ebiten.Image
)

func init() {
	var err error
	playerBarImage, err = ebiten.NewImage(300, 4, ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	playerBarImage.Fill(&color.RGBA{0x80, 0x80, 0x80, 0xff})

	playerCurrentImage, err = ebiten.NewImage(4, 10, ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	playerCurrentImage.Fill(&color.RGBA{0xff, 0xff, 0xff, 0xff})
}

var (
	audioContext     *audio.Context
	audioLoadingDone chan struct{}
	audioLoaded      bool
	audioPlayer      *audio.Player
	total            time.Duration
)

func update(screen *ebiten.Image) error {
	audioContext.Update()
	if !audioLoaded {
		select {
		case <-audioLoadingDone:
			audioLoaded = true
		default:
		}
	}

	op := &ebiten.DrawImageOptions{}
	w, h := playerBarImage.Size()
	x := float64(screenWidth-w) / 2
	y := float64(screenHeight - h - 16)
	op.GeoM.Translate(x, y)
	screen.DrawImage(playerBarImage, op)
	currentTimeStr := ""
	if audioLoaded && audioPlayer.IsPlaying() {
		c := audioPlayer.Current()

		// Current Time
		m := (c / time.Minute) % 100
		s := (c / time.Second) % 60
		currentTimeStr = fmt.Sprintf("%02d:%02d", m, s)

		// Bar
		w, _ := playerBarImage.Size()
		cw, ch := playerCurrentImage.Size()
		cx := float64(w)*float64(c)/float64(total) + x - float64(cw)/2
		cy := y - float64(ch-h)/2
		op := &ebiten.DrawImageOptions{}
		op.GeoM.Translate(cx, cy)
		screen.DrawImage(playerCurrentImage, op)
	}

	msg := fmt.Sprintf(`FPS: %0.2f
%s`, ebiten.CurrentFPS(), currentTimeStr)
	if !audioLoaded {
		msg += "\nNow Loading..."
	}
	ebitenutil.DebugPrint(screen, msg)
	return nil
}

func main() {
	// Use a FLAC file so far: I couldn't find any good OGG/Vorbis decoder in pure Go.
	f, err := ebitenutil.OpenFile("_resources/audio/ragtime.ogg")
	if err != nil {
		log.Fatal(err)
	}
	// TODO: sampleRate should be obtained from the ogg file.
	audioContext = audio.NewContext(22050)
	audioLoadingDone = make(chan struct{})
	// TODO: This doesn't work synchronously on browsers because of decoding. Fix this.
	go func() {
		var err error
		s, err := vorbis.Decode(audioContext, f)
		if err != nil {
			log.Fatal(err)
			return
		}
		total = s.Len()
		audioPlayer, err = audioContext.NewPlayer(s)
		if err != nil {
			log.Fatal(err)
			return
		}
		close(audioLoadingDone)
		audioPlayer.Play()
	}()
	if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Audio (Ebiten Demo)"); err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package haproxy

import (
	"log"
	"os"
	"os/exec"
	"strconv"
	"sync"
	"time"
)

type Event int
type Action int

const (
	HasStarted Event = 1 << iota
	HasStopped
	HasReloaded
)

const (
	WantsReload Action = 1 << iota
	WantsStop
)

type Server struct {
	Socket     string
	ActionChan chan Action
	cmd        *exec.Cmd
	sync.RWMutex
}

const BINARYPATH = "/usr/local/bin/haproxy"

func (h *Server) createProcess() {
	h.cmd = exec.Command(BINARYPATH, "-f", "config/haproxy.conf")
}

func (h *Server) setupStdout() {
	h.cmd.Stdout = os.Stdout
	h.cmd.Stderr = os.Stderr
}

func (h *Server) runProcess() error {
	return h.cmd.Start()
}

func (h *Server) Start(notify chan Event, action chan Action) {
	h.Lock()
	h.createProcess()
	h.setupStdout()

	err := h.runProcess()

	if err != nil {
		log.Fatal(err)
	}

	h.ActionChan = action
	h.Unlock()

	notify <- HasStarted

	// Wait for a stop signal, reload signal, or process death
	for {
		switch <-action {
		case WantsReload:
			h.reloadProcess()
			notify <- HasReloaded
		case WantsStop:
			h.stopProcess()
			notify <- HasStopped
			return
		}
	}
}

func (h *Server) reloadProcess() error {

	h.Lock()

	// Grab pid of current running process
	old := h.cmd
	pid := strconv.Itoa(h.cmd.Process.Pid)

	// Start a new process, telling it to replace the old process
	// This will signal the current process and tell it shutdown, which is why
	// we don't need to do it here.
	cmd := exec.Command(BINARYPATH, "-f", "config/haproxy.conf", "-sf", pid)

	// Start the new process and check for errors. We bail out if there is
	// an error and DON'T replace the old process.
	err := cmd.Start()

	if err != nil {
		return err
	}

	// No errors? Replace the old process
	h.cmd = cmd
	h.finishOrKill(10*time.Second, old)

	return nil
}

func (h *Server) finishOrKill(waitFor time.Duration, old *exec.Cmd) {
	// Create a channel and wait for the old process
	// to finish itself
	didFinish := make(chan error, 1)
	go func() {
		didFinish <- old.Wait()
	}()

	// Wait for the didFinish channel or force kill the process
	// if it takes longer than 10 seconds
	select {
	case <-time.After(waitFor):
		log.Println("manually killing process")
		if err := old.Process.Kill(); err != nil {
			log.Println("failed to kill ", err)
		}
	case err := <-didFinish:
		if err != nil {
			log.Println("process finished with error", err)
		}
	}
}

func (h *Server) stopProcess() error {
	return h.cmd.Process.Kill()
}
<commit_msg>don't hardcode config path<commit_after>package haproxy

import (
	"log"
	"os"
	"os/exec"
	"strconv"
	"sync"
	"time"
)

type Event int
type Action int

const (
	HasStarted Event = 1 << iota
	HasStopped
	HasReloaded
)

const (
	WantsReload Action = 1 << iota
	WantsStop
)

type Server struct {
	Socket     string
	ActionChan chan Action
	cmd        *exec.Cmd
	sync.RWMutex
}

const BINARYPATH = "/usr/local/bin/haproxy"
const CONFIGPATH = "config/haproxy.conf"

func (h *Server) createProcess() {
	h.cmd = exec.Command(BINARYPATH, "-f", CONFIGPATH)
}

func (h *Server) setupStdout() {
	h.cmd.Stdout = os.Stdout
	h.cmd.Stderr = os.Stderr
}

func (h *Server) runProcess() error {
	return h.cmd.Start()
}

func (h *Server) Start(notify chan Event, action chan Action) {
	h.Lock()
	h.createProcess()
	h.setupStdout()

	err := h.runProcess()

	if err != nil {
		log.Fatal(err)
	}

	h.ActionChan = action
	h.Unlock()

	notify <- HasStarted

	// Wait for a stop signal, reload signal, or process death
	for {
		switch <-action {
		case WantsReload:
			h.reloadProcess()
			notify <- HasReloaded
		case WantsStop:
			h.stopProcess()
			notify <- HasStopped
			return
		}
	}
}

func (h *Server) reloadProcess() error {

	h.Lock()

	// Grab pid of current running process
	old := h.cmd
	pid := strconv.Itoa(h.cmd.Process.Pid)

	// Start a new process, telling it to replace the old process
	// This will signal the current process and tell it shutdown, which is why
	// we don't need to do it here.
	cmd := exec.Command(BINARYPATH, "-f", CONFIGPATH, "-sf", pid)

	// Start the new process and check for errors. We bail out if there is
	// an error and DON'T replace the old process.
	err := cmd.Start()

	if err != nil {
		return err
	}

	// No errors? Replace the old process
	h.cmd = cmd
	h.finishOrKill(10*time.Second, old)

	return nil
}

func (h *Server) finishOrKill(waitFor time.Duration, old *exec.Cmd) {
	// Create a channel and wait for the old process
	// to finish itself
	didFinish := make(chan error, 1)
	go func() {
		didFinish <- old.Wait()
	}()

	// Wait for the didFinish channel or force kill the process
	// if it takes longer than 10 seconds
	select {
	case <-time.After(waitFor):
		log.Println("manually killing process")
		if err := old.Process.Kill(); err != nil {
			log.Println("failed to kill ", err)
		}
	case err := <-didFinish:
		if err != nil {
			log.Println("process finished with error", err)
		}
	}
}

func (h *Server) stopProcess() error {
	return h.cmd.Process.Kill()
}
<|endoftext|>


<commit_before>package client

import (
	"bytes"
	"fmt"
	"text/template"

	"github.com/Masterminds/sprig"
	"github.com/kubernetes/helm/pkg/kube"
)

// Installer installs tiller into Kubernetes
//
// See InstallYAML.
type Installer struct {

	// Metadata holds any global metadata attributes for the resources
	Metadata map[string]interface{}

	// Tiller specific metadata
	Tiller map[string]interface{}
}

// NewInstaller creates a new Installer
func NewInstaller() *Installer {
	return &Installer{
		Metadata: map[string]interface{}{},
		Tiller:   map[string]interface{}{},
	}
}

// Install uses kubernetes client to install tiller
//
// Returns the string output received from the operation, and an error if the
// command failed.
//
// If verbose is true, this will print the manifest to stdout.
//
// If createNS is true, this will also create the namespace.
func (i *Installer) Install(verbose, createNS bool) error {

	var b bytes.Buffer
	t := template.New("manifest").Funcs(sprig.TxtFuncMap())

	// Add namespace
	if createNS {
		if err := template.Must(t.Parse(NamespaceYAML)).Execute(&b, i); err != nil {
			return err
		}
	}

	// Add main install YAML
	if err := template.Must(t.Parse(InstallYAML)).Execute(&b, i); err != nil {
		return err
	}

	if verbose {
		fmt.Println(b.String())
	}

	return kube.New(nil).Create(i.Tiller["Namespace"].(string), &b)
}

// NamespaceYAML is the installation for a namespace.
const NamespaceYAML = `
---{{$namespace := default "helm" .Tiller.Namespace}}
apiVersion: v1
kind: Namespace
metadata:
  labels:
    app: helm
    name: helm-namespace
  name: {{$namespace}}
`

// InstallYAML is the installation YAML for DM.
const InstallYAML = `
---{{$namespace := default "helm" .Tiller.Namespace}}
apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    app: helm
    name: tiller
  name: tiller-rc
  namespace: {{$namespace}}
spec:
  replicas: 1
  selector:
    app: helm
    name: tiller
  template:
    metadata:
      labels:
        app: helm
        name: tiller
    spec:
      containers:
      - env:
          - name: DEFAULT_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        image: {{default "gcr.io/kubernetes-helm/tiller:canary" .Tiller.Image}}
        name: tiller
        ports:
        - containerPort: 44134
          name: tiller
        imagePullPolicy: Always
`
<commit_msg>Add probes to the the embedded Tiller manifest<commit_after>package client

import (
	"bytes"
	"fmt"
	"text/template"

	"github.com/Masterminds/sprig"
	"github.com/kubernetes/helm/pkg/kube"
)

// Installer installs tiller into Kubernetes
//
// See InstallYAML.
type Installer struct {

	// Metadata holds any global metadata attributes for the resources
	Metadata map[string]interface{}

	// Tiller specific metadata
	Tiller map[string]interface{}
}

// NewInstaller creates a new Installer
func NewInstaller() *Installer {
	return &Installer{
		Metadata: map[string]interface{}{},
		Tiller:   map[string]interface{}{},
	}
}

// Install uses kubernetes client to install tiller
//
// Returns the string output received from the operation, and an error if the
// command failed.
//
// If verbose is true, this will print the manifest to stdout.
//
// If createNS is true, this will also create the namespace.
func (i *Installer) Install(verbose, createNS bool) error {

	var b bytes.Buffer
	t := template.New("manifest").Funcs(sprig.TxtFuncMap())

	// Add namespace
	if createNS {
		if err := template.Must(t.Parse(NamespaceYAML)).Execute(&b, i); err != nil {
			return err
		}
	}

	// Add main install YAML
	if err := template.Must(t.Parse(InstallYAML)).Execute(&b, i); err != nil {
		return err
	}

	if verbose {
		fmt.Println(b.String())
	}

	return kube.New(nil).Create(i.Tiller["Namespace"].(string), &b)
}

// NamespaceYAML is the installation for a namespace.
const NamespaceYAML = `
---{{$namespace := default "helm" .Tiller.Namespace}}
apiVersion: v1
kind: Namespace
metadata:
  labels:
    app: helm
    name: helm-namespace
  name: {{$namespace}}
`

// InstallYAML is the installation YAML for DM.
const InstallYAML = `
---{{$namespace := default "helm" .Tiller.Namespace}}
apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    app: helm
    name: tiller
  name: tiller-rc
  namespace: {{$namespace}}
spec:
  replicas: 1
  selector:
    app: helm
    name: tiller
  template:
    metadata:
      labels:
        app: helm
        name: tiller
    spec:
      containers:
      - env:
          - name: DEFAULT_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        image: {{default "gcr.io/kubernetes-helm/tiller:canary" .Tiller.Image}}
        name: tiller
        ports:
        - containerPort: 44134
          name: tiller
        imagePullPolicy: Always
				livenessProbe:
					httpGet:
						path: /liveness
						port: 44135
					initialDelaySeconds: 1
					timeoutSeconds: 1
				readinessProbe:
					httpGet:
						path: /readiness
						port: 44135
					initialDelaySeconds: 1
					timeoutSeconds:1
`
<|endoftext|>


<commit_before>// +build OMIT

package main

import (
	"fmt"
	"strings"
)

func main() {
	// Create a tic-tac-toe board.
	game := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
	}

	// The players take turns.
	game[0][0] = "X"
	game[2][2] = "O"
	game[2][0] = "X"
	game[1][0] = "O"
	game[0][2] = "X"

	printBoard(game)
}

func printBoard(s [][]string) {
	for i := 0; i < len(s); i++ {
		fmt.Printf("%s\n", strings.Join(s[i], " "))
	}
}
<commit_msg>content: clean up slice of slices code example<commit_after>// +build OMIT

package main

import (
	"fmt"
	"strings"
)

func main() {
	// Create a tic-tac-toe board.
	board := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
	}

	// The players take turns.
	board[0][0] = "X"
	board[2][2] = "O"
	board[2][0] = "X"
	board[1][0] = "O"
	board[0][2] = "X"

	for i := 0; i < len(board); i++ {
		fmt.Printf("%s\n", strings.Join(board[i], " "))
	}
}
<|endoftext|>


<commit_before>package cony

import (
	"fmt"
	"os"

	"github.com/streadway/amqp"
)

// ConsumerOpt is a consumer's functional option type
type ConsumerOpt func(*Consumer)

// Consumer holds definition for AMQP consumer
type Consumer struct {
	q          *Queue
	deliveries chan amqp.Delivery
	errs       chan error
	qos        int
	tag        string
	autoAck    bool
	exclusive  bool
	noLocal    bool
	stop       chan struct{}
}

// Deliveries return deliveries shipped to this consumer
// this channel never closed, even on disconnects
func (c *Consumer) Deliveries() <-chan amqp.Delivery {
	return c.deliveries
}

// Errors returns channel with AMQP channel level errors
func (c *Consumer) Errors() <-chan error {
	return c.errs
}

// Cancel this consumer
func (c *Consumer) Cancel() {
	select {
	case c.stop <- struct{}{}:
	default:
	}
}

func (c *Consumer) reportErr(err error) bool {
	if err != nil {
		select {
		case c.errs <- err:
		default:
		}
		return true
	}
	return false
}

func (c *Consumer) serve(client mqDeleter, ch mqChannel) {
	if c.reportErr(ch.Qos(c.qos, 0, false)) {
		return
	}

	deliveries, err2 := ch.Consume(c.q.Name,
		c.tag,       // consumer tag
		c.autoAck,   // autoAck,
		c.exclusive, // exclusive,
		c.noLocal,   // noLocal,
		false,       // noWait,
		nil,         // args Table
	)
	if c.reportErr(err2) {
		return
	}

	for {
		select {
		case <-c.stop:
			client.deleteConsumer(c)
			ch.Close()
			return
		case d, ok := <-deliveries: // deliveries will be closed once channel is closed (disconnected from network)
			if !ok {
				return
			}
			c.deliveries <- d
		}
	}
}

// NewConsumer Consumer's constructor
func NewConsumer(q *Queue, opts ...ConsumerOpt) *Consumer {
	c := &Consumer{
		q:          q,
		deliveries: make(chan amqp.Delivery),
		errs:       make(chan error, 100),
		stop:       make(chan struct{}),
	}
	for _, o := range opts {
		o(c)
	}
	return c
}

// Qos on channel
func Qos(count int) ConsumerOpt {
	return func(c *Consumer) {
		c.qos = count
	}
}

// Tag the consumer
func Tag(tag string) ConsumerOpt {
	return func(c *Consumer) {
		c.tag = tag
	}
}

// AutoTag set automatically generated tag like this
//	fmt.Sprintf(QueueName+"-pid-%d@%s", os.Getpid(), os.Hostname())
func AutoTag() ConsumerOpt {
	return func(c *Consumer) {
		host, _ := os.Hostname()
		tag := fmt.Sprintf(c.q.Name+"-pid-%d@%s", os.Getpid(), host)
		Tag(tag)(c)
	}
}

// AutoAck set this consumer in AutoAck mode
func AutoAck() ConsumerOpt {
	return func(c *Consumer) {
		c.autoAck = true
	}
}

// Exclusive set this consumer in exclusive mode
func Exclusive() ConsumerOpt {
	return func(c *Consumer) {
		c.exclusive = true
	}
}

// NoLocal set this consumer in NoLocal mode.
func NoLocal() ConsumerOpt {
	return func(c *Consumer) {
		c.noLocal = true
	}
}
<commit_msg>Consumer will close its delivery channel once Close()-ed<commit_after>package cony

import (
	"fmt"
	"os"
	"sync"

	"github.com/streadway/amqp"
)

// ConsumerOpt is a consumer's functional option type
type ConsumerOpt func(*Consumer)

// Consumer holds definition for AMQP consumer
type Consumer struct {
	q          *Queue
	deliveries chan amqp.Delivery
	errs       chan error
	qos        int
	tag        string
	autoAck    bool
	exclusive  bool
	noLocal    bool
	stop       chan struct{}
	dead       bool
	m          sync.Mutex
}

// Deliveries return deliveries shipped to this consumer
// this channel never closed, even on disconnects
func (c *Consumer) Deliveries() <-chan amqp.Delivery {
	return c.deliveries
}

// Errors returns channel with AMQP channel level errors
func (c *Consumer) Errors() <-chan error {
	return c.errs
}

// Cancel this consumer
func (c *Consumer) Cancel() {
	c.m.Lock()
	defer c.m.Unlock()

	if !c.dead {
		close(c.deliveries)
		close(c.stop)
		c.dead = true
	}
}

func (c *Consumer) reportErr(err error) bool {
	if err != nil {
		select {
		case c.errs <- err:
		default:
		}
		return true
	}
	return false
}

func (c *Consumer) serve(client mqDeleter, ch mqChannel) {
	if c.reportErr(ch.Qos(c.qos, 0, false)) {
		return
	}

	deliveries, err2 := ch.Consume(c.q.Name,
		c.tag,       // consumer tag
		c.autoAck,   // autoAck,
		c.exclusive, // exclusive,
		c.noLocal,   // noLocal,
		false,       // noWait,
		nil,         // args Table
	)
	if c.reportErr(err2) {
		return
	}

	for {
		select {
		case <-c.stop:
			client.deleteConsumer(c)
			ch.Close()
			return
		case d, ok := <-deliveries: // deliveries will be closed once channel is closed (disconnected from network)
			if !ok {
				return
			}
			c.deliveries <- d
		}
	}
}

// NewConsumer Consumer's constructor
func NewConsumer(q *Queue, opts ...ConsumerOpt) *Consumer {
	c := &Consumer{
		q:          q,
		deliveries: make(chan amqp.Delivery),
		errs:       make(chan error, 100),
		stop:       make(chan struct{}),
	}
	for _, o := range opts {
		o(c)
	}
	return c
}

// Qos on channel
func Qos(count int) ConsumerOpt {
	return func(c *Consumer) {
		c.qos = count
	}
}

// Tag the consumer
func Tag(tag string) ConsumerOpt {
	return func(c *Consumer) {
		c.tag = tag
	}
}

// AutoTag set automatically generated tag like this
//	fmt.Sprintf(QueueName+"-pid-%d@%s", os.Getpid(), os.Hostname())
func AutoTag() ConsumerOpt {
	return func(c *Consumer) {
		host, _ := os.Hostname()
		tag := fmt.Sprintf(c.q.Name+"-pid-%d@%s", os.Getpid(), host)
		Tag(tag)(c)
	}
}

// AutoAck set this consumer in AutoAck mode
func AutoAck() ConsumerOpt {
	return func(c *Consumer) {
		c.autoAck = true
	}
}

// Exclusive set this consumer in exclusive mode
func Exclusive() ConsumerOpt {
	return func(c *Consumer) {
		c.exclusive = true
	}
}

// NoLocal set this consumer in NoLocal mode.
func NoLocal() ConsumerOpt {
	return func(c *Consumer) {
		c.noLocal = true
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"time"

	"../../goble"
)

func main() {
	verbose := flag.Bool("verbose", false, "dump all events")
	dups := flag.Bool("allow-duplicates", false, "allow duplicates when scanning")
	flag.Parse()

	ble := goble.New()
	ble.SetVerbose(*verbose)

	if *verbose {
		ble.On(goble.ALL, func(ev goble.Event) {
			log.Println("event", ev)
		})
	}

	ble.On("stateChange", func(ev goble.Event) {
		if ev.State == "poweredOn" {
			ble.StartScanning(nil, *dups)
		} else {
			ble.StopScanning()
		}
	})

	ble.On("discover", func(ev goble.Event) {
		fmt.Println("peripheral discovered (", ev.DeviceUUID, "):")
		fmt.Println("\thello my local name is:")
		fmt.Println("\t\t", ev.Peripheral.Advertisement.LocalName)
		fmt.Println("\tcan I interest you in any of the following advertised services:")
		fmt.Println("\t\t", ev.Peripheral.Services)

                serviceData := ev.Peripheral.Advertisement.ServiceData
                if len(serviceData) > 0 {
                    fmt.Println("\there is my service data:")
                    for _, d := range serviceData {
	                fmt.Println("\t\t", d.Uuid, ":", d.Data)
	            }
	        }
	})

	/*
	   if (peripheral.advertisement.manufacturerData) {
	     console.log('\there is my manufacturer data:');
	     console.log('\t\t' + JSON.stringify(peripheral.advertisement.manufacturerData.toString('hex')));
	   }
	   if (peripheral.advertisement.txPowerLevel !== undefined) {
	     console.log('\tmy TX power level is:');
	     console.log('\t\t' + peripheral.advertisement.txPowerLevel);
	   }

	   console.log();
	*/

	if *verbose {
		log.Println("Init...")
	}

	ble.Init()

	time.Sleep(60 * time.Second)
	log.Println("Goodbye!")
}
<commit_msg>fixed display of advertised services<commit_after>package main

import (
	"flag"
	"fmt"
	"log"

	"../../goble"
)

func main() {
	verbose := flag.Bool("verbose", false, "dump all events")
	dups := flag.Bool("allow-duplicates", false, "allow duplicates when scanning")
	flag.Parse()

	ble := goble.New()
	ble.SetVerbose(*verbose)

	if *verbose {
		ble.On(goble.ALL, func(ev goble.Event) {
			log.Println("Event", ev)
		})
	}

	ble.On("stateChange", func(ev goble.Event) {
		if ev.State == "poweredOn" {
			ble.StartScanning(nil, *dups)
		} else {
			ble.StopScanning()
		}
	})

	ble.On("discover", func(ev goble.Event) {
		fmt.Println()
		fmt.Println("peripheral discovered (", ev.DeviceUUID, "):")
		fmt.Println("\thello my local name is:")
		fmt.Println("\t\t", ev.Peripheral.Advertisement.LocalName)
		fmt.Println("\tcan I interest you in any of the following advertised services:")
		fmt.Println("\t\t", ev.Peripheral.Advertisement.ServiceUuids)

		serviceData := ev.Peripheral.Advertisement.ServiceData
		if len(serviceData) > 0 {
			fmt.Println("\there is my service data:")
			for _, d := range serviceData {
				fmt.Println("\t\t", d.Uuid, ":", d.Data)
			}
		}

		if len(ev.Peripheral.Advertisement.ManufacturerData) > 0 {
			fmt.Println("\there is my manufacturer data:")
			fmt.Println("\t\t", ev.Peripheral.Advertisement.ManufacturerData)
		}

		if ev.Peripheral.Advertisement.TxPowerLevel != 0 {
			fmt.Println("\tmy TX power level is:")
			fmt.Println("\t\t", ev.Peripheral.Advertisement.TxPowerLevel)
		}
	})

	if *verbose {
		log.Println("Init...")
	}

	ble.Init()

	var done chan bool
	<-done
}
<|endoftext|>


<commit_before>package cloudflare

import "time"

// Zone - Cloudflare Zone.
type Zone struct {
	ID              string `json:"id,omitempty"`
	Name            string `json:"name,omitempty"`
	Status          string `json:"status,omitempty"`
	Paused          bool   `json:"paused,omitempty"`
	Type            string `json:"type,omitempty"`
	DevelopmentMode int    `json:"development_mode,omitempty"`

	NameServers         []string `json:"name_servers,omitempty"`
	OriginalNameServers []string `json:"original_name_servers,omitempty"`

	ModifiedOn time.Time `json:"modified_on,omitempty"`
	CreatedOn  time.Time `json:"created_on,omitempty"`
	CheckedOn  time.Time `json:"checked_on,omitempty"`

	Meta  *ZoneMeta  `json:"meta,omitempty"`
	Owner *ZoneOwner `json:"owner,omitempty"`
	Plan  *ZonePlan  `json:"plan,omitempty"`

	Permissions []string `json:"permissions,omitempty"`
}

// ZoneOwner -
type ZoneOwner struct {
	Type  string `json:"type,omitempty"`
	ID    string `json:"id,omitempty"`
	Email string `json:"email,omitempty"`
}

// ZoneMeta -
type ZoneMeta struct {
	Step                    int    `json:"step,omitempty"`
	PageRuleQuota           string `json:"page_rule_quota,omitempty"`
	CustomCertificateQuota  string `json:"custom_certificate_quota,omitempty"`
	WildcardProxiable       bool   `json:"wildcard_proxiable,omitempty"`
	PhishingDetected        bool   `json:"phishing_detected,omitempty"`
	MultipleRailgunsAllowed bool   `json:"multiple_railguns_allowed,omitempty"`
}

// ZonePlan -
type ZonePlan struct {
	ID                string `json:"id,omitempty"`
	Name              string `json:"name,omitempty"`
	Price             int    `json:"price,omitempty"`
	Currency          string `json:"currency,omitempty"`
	Frequency         string `json:"frequency,omitempty"`
	LegacyID          string `json:"legacy_id,omitempty"`
	IsSubscribed      bool   `json:"is_subscribed,omitempty"`
	CanSubscribe      bool   `json:"can_subscribe,omitempty"`
	ExternallyManaged bool   `json:"externally_managed,omitempty"`
}

// ZonePatch -
type ZonePatch struct {
	Plan              *ZonePlan `json:"plan,omitempty"`
	Paused            bool      `json:"paused,omitempty"`
	VanityNameServers []string  `json:"vanity_name_servers,omitempty"`
}
<commit_msg>Account for inconsistent type for quota field<commit_after>package cloudflare

import (
	"bytes"
	"encoding/json"
	"time"
)

// Zone - Cloudflare Zone.
type Zone struct {
	ID              string `json:"id,omitempty"`
	Name            string `json:"name,omitempty"`
	Status          string `json:"status,omitempty"`
	Paused          bool   `json:"paused,omitempty"`
	Type            string `json:"type,omitempty"`
	DevelopmentMode int    `json:"development_mode,omitempty"`

	NameServers         []string `json:"name_servers,omitempty"`
	OriginalNameServers []string `json:"original_name_servers,omitempty"`

	ModifiedOn time.Time `json:"modified_on,omitempty"`
	CreatedOn  time.Time `json:"created_on,omitempty"`
	CheckedOn  time.Time `json:"checked_on,omitempty"`

	Meta  *ZoneMeta  `json:"meta,omitempty"`
	Owner *ZoneOwner `json:"owner,omitempty"`
	Plan  *ZonePlan  `json:"plan,omitempty"`

	Permissions []string `json:"permissions,omitempty"`
}

// ZoneOwner -
type ZoneOwner struct {
	Type  string `json:"type,omitempty"`
	ID    string `json:"id,omitempty"`
	Email string `json:"email,omitempty"`
}

// ZoneMeta -
type ZoneMeta struct {
	Step                    int    `json:"step,omitempty"`
	PageRuleQuota           string `json:"page_rule_quota,omitempty"`
	CustomCertificateQuota  int    `json:"custom_certificate_quota,omitempty"`
	WildcardProxiable       bool   `json:"wildcard_proxiable,omitempty"`
	PhishingDetected        bool   `json:"phishing_detected,omitempty"`
	MultipleRailgunsAllowed bool   `json:"multiple_railguns_allowed,omitempty"`
}

func (m *ZoneMeta) UnmarshalJSON(data []byte) error {
	f := struct {
		Step                    int          `json:"step,omitempty"`
		PageRuleQuota           string       `json:"page_rule_quota,omitempty"`
		CustomCertificateQuota  *maybeNumber `json:"custom_certificate_quota,omitempty"`
		WildcardProxiable       bool         `json:"wildcard_proxiable,omitempty"`
		PhishingDetected        bool         `json:"phishing_detected,omitempty"`
		MultipleRailgunsAllowed bool         `json:"multiple_railguns_allowed,omitempty"`
	}{}

	err := json.Unmarshal(data, &f)
	if err != nil {
		return err
	}

	m.CustomCertificateQuota = f.CustomCertificateQuota.value
	m.MultipleRailgunsAllowed = f.MultipleRailgunsAllowed
	m.PageRuleQuota = f.PageRuleQuota
	m.PhishingDetected = f.PhishingDetected
	m.Step = f.Step
	m.WildcardProxiable = f.WildcardProxiable

	return nil
}

// ZonePlan -
type ZonePlan struct {
	ID                string `json:"id,omitempty"`
	Name              string `json:"name,omitempty"`
	Price             int    `json:"price,omitempty"`
	Currency          string `json:"currency,omitempty"`
	Frequency         string `json:"frequency,omitempty"`
	LegacyID          string `json:"legacy_id,omitempty"`
	IsSubscribed      bool   `json:"is_subscribed,omitempty"`
	CanSubscribe      bool   `json:"can_subscribe,omitempty"`
	ExternallyManaged bool   `json:"externally_managed,omitempty"`
}

// ZonePatch -
type ZonePatch struct {
	Plan              *ZonePlan `json:"plan,omitempty"`
	Paused            bool      `json:"paused,omitempty"`
	VanityNameServers []string  `json:"vanity_name_servers,omitempty"`
}

// maybeNumber is an intermediate type to cope with the inconsistent responses
// for CustomCertificateQuota which can be a string or a number.
type maybeNumber struct {
	value int
}

func (m *maybeNumber) UnmarshalJSON(data []byte) error {
	data = bytes.Trim(data, `"`)

	return json.Unmarshal(data, &m.value)
}
<|endoftext|>


<commit_before>package rabbitgo

import (
  //"errors"
  "time"
  "fmt"
  "github.com/streadway/amqp"
  log "github.com/koding/logging"
)

type Consumer struct {
	conn        *Connection
	ch          *amqp.Channel
  e           *Exchange
  q           *Queue
	deliveries  <-chan amqp.Delivery
  handler     func(amqp.Delivery)
	handlerRPC  func(amqp.Delivery)([]byte, string)
  cc          *ConsumerConfig
  bc          *BindingConfig
  closed      bool
	// A notifiyng channel for publishings
	// will be used for sync. between close channel and consume handler
	done        chan error
}

type ConsumerConfig struct {
	Tag            string
  PrefetchCount  int
  PrefetchSize   int
  Timeout        int
	AutoAck        bool
	Exclusive      bool
	NoLocal        bool
	NoWait         bool
	Args           amqp.Table
}

type BindingConfig struct {
	RoutingKey string
	NoWait bool
	Args amqp.Table
}

func (c *Consumer) Deliveries() <-chan amqp.Delivery {
	return c.deliveries
}

// NewConsumer is a constructor for consumer creation
// Accepts Exchange, Queue, BindingOptions and ConsumerOptions
func (c *Connection) NewConsumer(e *Exchange, q *Queue, bc *BindingConfig, cc *ConsumerConfig) (*Consumer, error) {
  ch, err := c.conn.Channel()
  if err != nil {
    return nil, err
  }
	consumer := &Consumer {
    conn: c,
    ch:   ch,
		done: make(chan error),
    cc:   cc,
    bc:   bc,
		e:    e,
    q:    q,
	}
	if err := consumer.connect(); err != nil {
		return nil, err
	}
	return consumer, nil
}

// connect internally declares the exchanges and queues
func (c *Consumer) connect() error {
	_, err := c.ch.QueueDeclare(
		c.q.Name,       // name of the queue
		c.q.Durable,    // durable
		c.q.AutoDelete, // delete when usused
		c.q.Exclusive,  // exclusive
		c.q.NoWait,     // noWait
		c.q.Args,       // arguments
	)
	if err != nil {
		return err
	}
  err = c.ch.Qos(
    c.cc.PrefetchCount,     // prefetch count
    c.cc.PrefetchSize,     // prefetch size
    false,               // global
  )
  if err != nil {
    return err
  }
  if c.e != nil {
    err := c.ch.ExchangeDeclare(
      c.e.Name,       // name of the exchange
      c.e.Type,       // type
      c.e.Durable,    // durable
      c.e.AutoDelete, // delete when complete
      c.e.Internal,   // internal
      c.e.NoWait,     // noWait
      c.e.Args,       // arguments
    )
    if err != nil {
      return err
    }
    err = c.ch.QueueBind(
  		// bind to real queue
  		c.q.Name,        // name of the queue
  		c.bc.RoutingKey, // bindingKey
  		c.e.Name,        // sourceExchange
  		c.bc.NoWait,     // noWait
  		c.bc.Args,       // arguments
  	)
    if err != nil {
  		return err
  	}
  }
	return nil
}

func (c *Consumer) consume() error {
  deliveries, err := c.ch.Consume(
    c.q.Name,       // name
    c.cc.Tag,       // consumerTag,
    c.cc.AutoAck,   // autoAck
    c.cc.Exclusive, // exclusive
    c.cc.NoLocal,   // noLocal
    c.cc.NoWait,    // noWait
    c.cc.Args,      // arguments
  )
  // should we stop streaming, in order not to consume from server?
  c.deliveries = deliveries
  return err
}

// Consume accepts a handler function for every message streamed from RabbitMq
// will be called within this handler func
func (c *Consumer) Consume(handler func(delivery amqp.Delivery)) error {
  err := c.consume()
  if err != nil {
    return err
  }
  go func() {
    if timeout := c.cc.Timeout; timeout > 0 {
      time.Sleep(time.Duration(timeout) * time.Millisecond)
      if c.closed == false {
        log.Error(fmt.Sprintf("Timeout in %d ms", timeout))
        c.Shutdown()
      }
    }
  }()
	c.handler = handler
	log.Info("handle: deliveries channel starting")
	// handle all consumer errors, if required re-connect
	// there are problems with reconnection logic for now
  for delivery := range c.deliveries {
		handler(delivery)
	}
	log.Info("handle: deliveries channel closed")
  //This was blocking the flow. Not sure how needed is.
	//c.done <- nil
	return nil
}

// ConsumeRPC accepts a handler function for every message streamed from RabbitMq
// will be called within this handler func.
// It returns the message to send and the content type.
func (c *Consumer) ConsumeRPC(handler func(delivery amqp.Delivery)([]byte, string)) error {
	deliveries, err := c.ch.Consume(
		c.q.Name,       // name
		c.cc.Tag,       // consumerTag,
		c.cc.AutoAck,   // autoAck
		c.cc.Exclusive, // exclusive
		c.cc.NoLocal,   // noLocal
		c.cc.NoWait,    // noWait
		c.cc.Args,      // arguments
	)
	if err != nil {
		return err
	}

	// should we stop streaming, in order not to consume from server?
	c.deliveries = deliveries
	c.handlerRPC = handler

	log.Info("handle: deliveries channel starting")

	// handle all consumer errors, if required re-connect
	// there are problems with reconnection logic for now
	for delivery := range c.deliveries {
    body, contentType := handler(delivery)
    replyTo := delivery.ReplyTo
    if replyTo != "" {
      err := c.ch.Publish(
    		"",
    		replyTo,
    		false,
    		false,
    		amqp.Publishing{
    			ContentType:   contentType,
    			CorrelationId: delivery.CorrelationId,
    			Body:          body,
    		},
    	)
      if err != nil {
        // TODO: What if err != nil?
      }
    }
	}

	log.Info("handle: deliveries channel closed")
	c.done <- nil
	return nil
}

// QOS controls how many messages the server will try to keep on the network for
// consumers before receiving delivery acks.  The intent of Qos is to make sure
// the network buffers stay full between the server and client.
func (c *Consumer) QOS(messageCount int) error {
	return c.ch.Qos(messageCount, 0, false)
}

// ConsumeMessage accepts a handler function and only consumes one message
// stream from RabbitMq
func (c *Consumer) Get(handler func(delivery amqp.Delivery)) error {
	message, ok, err := c.ch.Get(c.q.Name, c.cc.AutoAck)
	if err != nil {
		return err
	}
	c.handler = handler
	if ok {
		fmt.Println("Message received")
		handler(message)
	} else {
		fmt.Println("No message received")
	}
	// TODO maybe we should return ok too?
	return nil
}

func (c *Consumer) Shutdown() error {
	co := c.cc
	if err := shutdownChannel(c.ch, co.Tag); err != nil {
		return err
	}
	fmt.Println("Waiting for Consumer handler to exit")
	// if we have not called the Consume yet, we can return here
	if c.deliveries == nil {
		close(c.done)
	}
  fmt.Printf("deliveries %s", c.deliveries)
  c.closed = true
  fmt.Println("Consumer shutdown OK")
	// this channel is here for finishing the consumer's ranges of
	// delivery chans.  We need every delivery to be processed, here make
	// sure to wait for all consumers goroutines to finish before exiting our
	// process.
	return nil
}
<commit_msg>Handler for ConsumerRPC now should return a pointer to a amqp.Publishing struct or an error.<commit_after>package rabbitgo

import (
  //"errors"
  "time"
  "fmt"
  "github.com/streadway/amqp"
  log "github.com/koding/logging"
)

type Consumer struct {
	conn        *Connection
	ch          *amqp.Channel
  e           *Exchange
  q           *Queue
	deliveries  <-chan amqp.Delivery
  handler     func(amqp.Delivery)
	handlerRPC  func(amqp.Delivery)(*amqp.Publishing, error)
  cc          *ConsumerConfig
  bc          *BindingConfig
  closed      bool
	// A notifiyng channel for publishings
	// will be used for sync. between close channel and consume handler
	done        chan error
}

type ConsumerConfig struct {
	Tag            string
  PrefetchCount  int
  PrefetchSize   int
  Timeout        int
	AutoAck        bool
	Exclusive      bool
	NoLocal        bool
	NoWait         bool
	Args           amqp.Table
}

type BindingConfig struct {
	RoutingKey string
	NoWait bool
	Args amqp.Table
}

func (c *Consumer) Deliveries() <-chan amqp.Delivery {
	return c.deliveries
}

// NewConsumer is a constructor for consumer creation
// Accepts Exchange, Queue, BindingOptions and ConsumerOptions
func (c *Connection) NewConsumer(e *Exchange, q *Queue, bc *BindingConfig, cc *ConsumerConfig) (*Consumer, error) {
  ch, err := c.conn.Channel()
  if err != nil {
    return nil, err
  }
	consumer := &Consumer {
    conn: c,
    ch:   ch,
		done: make(chan error),
    cc:   cc,
    bc:   bc,
		e:    e,
    q:    q,
	}
	if err := consumer.connect(); err != nil {
		return nil, err
	}
	return consumer, nil
}

// connect internally declares the exchanges and queues
func (c *Consumer) connect() error {
	_, err := c.ch.QueueDeclare(
		c.q.Name,       // name of the queue
		c.q.Durable,    // durable
		c.q.AutoDelete, // delete when usused
		c.q.Exclusive,  // exclusive
		c.q.NoWait,     // noWait
		c.q.Args,       // arguments
	)
	if err != nil {
		return err
	}
  err = c.ch.Qos(
    c.cc.PrefetchCount,     // prefetch count
    c.cc.PrefetchSize,     // prefetch size
    false,               // global
  )
  if err != nil {
    return err
  }
  if c.e != nil {
    err := c.ch.ExchangeDeclare(
      c.e.Name,       // name of the exchange
      c.e.Type,       // type
      c.e.Durable,    // durable
      c.e.AutoDelete, // delete when complete
      c.e.Internal,   // internal
      c.e.NoWait,     // noWait
      c.e.Args,       // arguments
    )
    if err != nil {
      return err
    }
    err = c.ch.QueueBind(
  		// bind to real queue
  		c.q.Name,        // name of the queue
  		c.bc.RoutingKey, // bindingKey
  		c.e.Name,        // sourceExchange
  		c.bc.NoWait,     // noWait
  		c.bc.Args,       // arguments
  	)
    if err != nil {
  		return err
  	}
  }
	return nil
}

func (c *Consumer) consume() error {
  deliveries, err := c.ch.Consume(
    c.q.Name,       // name
    c.cc.Tag,       // consumerTag,
    c.cc.AutoAck,   // autoAck
    c.cc.Exclusive, // exclusive
    c.cc.NoLocal,   // noLocal
    c.cc.NoWait,    // noWait
    c.cc.Args,      // arguments
  )
  // should we stop streaming, in order not to consume from server?
  c.deliveries = deliveries
  return err
}

// Consume accepts a handler function for every message streamed from RabbitMq
// will be called within this handler func
func (c *Consumer) Consume(handler func(delivery amqp.Delivery)) error {
  err := c.consume()
  if err != nil {
    return err
  }
  go func() {
    if timeout := c.cc.Timeout; timeout > 0 {
      time.Sleep(time.Duration(timeout) * time.Millisecond)
      if c.closed == false {
        log.Error(fmt.Sprintf("Timeout in %d ms", timeout))
        c.Shutdown()
      }
    }
  }()
	c.handler = handler
	log.Info("handle: deliveries channel starting")
	// handle all consumer errors, if required re-connect
	// there are problems with reconnection logic for now
  for delivery := range c.deliveries {
		handler(delivery)
	}
	log.Info("handle: deliveries channel closed")
  //This was blocking the flow. Not sure how needed is.
	//c.done <- nil
	return nil
}

// ConsumeRPC accepts a handler function for every message streamed from RabbitMq
// will be called within this handler func.
// It returns the message to send and the content type.
func (c *Consumer) ConsumeRPC(handler func(delivery amqp.Delivery)(*amqp.Publishing, error)) error {
	deliveries, err := c.ch.Consume(
		c.q.Name,       // name
		c.cc.Tag,       // consumerTag,
		c.cc.AutoAck,   // autoAck
		c.cc.Exclusive, // exclusive
		c.cc.NoLocal,   // noLocal
		c.cc.NoWait,    // noWait
		c.cc.Args,      // arguments
	)
	if err != nil {
		return err
	}

	// should we stop streaming, in order not to consume from server?
	c.deliveries = deliveries
	c.handlerRPC = handler

	log.Info("handle: deliveries channel starting")

	// handle all consumer errors, if required re-connect
	// there are problems with reconnection logic for now
	for delivery := range c.deliveries {
    var publishing *amqp.Publishing
    publishing, err := handler(delivery)
    publishing.CorrelationId = delivery.CorrelationId
    // TODO: allow to break the handler execution in order to Nack or
    // Reject the message.
    if err != nil {
      log.Error(err.Error())
      continue
    }
    replyTo := delivery.ReplyTo
    if replyTo != "" {
      err := c.ch.Publish(
    		"",
    		replyTo,
    		false,
    		false,
    		*publishing,
    	)
      if err != nil {
        // TODO: What if err != nil?
      }
    }
	}

	log.Info("handle: deliveries channel closed")
	c.done <- nil
	return nil
}

// QOS controls how many messages the server will try to keep on the network for
// consumers before receiving delivery acks.  The intent of Qos is to make sure
// the network buffers stay full between the server and client.
func (c *Consumer) QOS(messageCount int) error {
	return c.ch.Qos(messageCount, 0, false)
}

// ConsumeMessage accepts a handler function and only consumes one message
// stream from RabbitMq
func (c *Consumer) Get(handler func(delivery amqp.Delivery)) error {
	message, ok, err := c.ch.Get(c.q.Name, c.cc.AutoAck)
	if err != nil {
		return err
	}
	c.handler = handler
	if ok {
		fmt.Println("Message received")
		handler(message)
	} else {
		fmt.Println("No message received")
	}
	// TODO maybe we should return ok too?
	return nil
}

func (c *Consumer) Shutdown() error {
	co := c.cc
	if err := shutdownChannel(c.ch, co.Tag); err != nil {
		return err
	}
	fmt.Println("Waiting for Consumer handler to exit")
	// if we have not called the Consume yet, we can return here
	if c.deliveries == nil {
		close(c.done)
	}
  fmt.Printf("deliveries %s", c.deliveries)
  c.closed = true
  fmt.Println("Consumer shutdown OK")
	// this channel is here for finishing the consumer's ranges of
	// delivery chans.  We need every delivery to be processed, here make
	// sure to wait for all consumers goroutines to finish before exiting our
	// process.
	return nil
}
<|endoftext|>