<commit_before>package backpressure_tests

import (
	"context"
	"io"
	"math/rand"
	"testing"
	"time"

	bhost "github.com/libp2p/go-libp2p/p2p/host/basic"

	u "github.com/ipfs/go-ipfs-util"
	logging "github.com/ipfs/go-log"
	host "github.com/libp2p/go-libp2p-host"
	inet "github.com/libp2p/go-libp2p-net"
	peer "github.com/libp2p/go-libp2p-peer"
	protocol "github.com/libp2p/go-libp2p-protocol"
	swarmt "github.com/libp2p/go-libp2p-swarm/testing"
)

var log = logging.Logger("backpressure")

// TestBackpressureStreamHandler tests whether mux handler
// ratelimiting works. Meaning, since the handler is sequential
// it should block senders.
//
// Important note: spdystream (which peerstream uses) has a set
// of n workers (n=spdsystream.FRAME_WORKERS) which handle new
// frames, including those starting new streams. So all of them
// can be in the handler at one time. Also, the sending side
// does not rate limit unless we call stream.Wait()
//
//
// Note: right now, this happens muxer-wide. the muxer should
// learn to flow control, so handlers cant block each other.
func TestBackpressureStreamHandler(t *testing.T) {
	t.Skip(`Sadly, as cool as this test is, it doesn't work
Because spdystream doesnt handle stream open backpressure
well IMO. I'll see about rewriting that part when it becomes
a problem.
`)

	// a number of concurrent request handlers
	limit := 10

	// our way to signal that we're done with 1 request
	requestHandled := make(chan struct{})

	// handler rate limiting
	receiverRatelimit := make(chan struct{}, limit)
	for i := 0; i < limit; i++ {
		receiverRatelimit <- struct{}{}
	}

	// sender counter of successfully opened streams
	senderOpened := make(chan struct{}, limit*100)

	// sender signals it's done (errored out)
	senderDone := make(chan struct{})

	// the receiver handles requests with some rate limiting
	receiver := func(s inet.Stream) {
		log.Debug("receiver received a stream")

		<-receiverRatelimit // acquire
		go func() {
			// our request handler. can do stuff here. we
			// simulate something taking time by waiting
			// on requestHandled
			log.Debug("request worker handling...")
			<-requestHandled
			log.Debug("request worker done!")
			receiverRatelimit <- struct{}{} // release
		}()
	}

	// the sender opens streams as fast as possible
	sender := func(host host.Host, remote peer.ID) {
		var s inet.Stream
		var err error
		defer func() {
			t.Error(err)
			log.Debug("sender error. exiting.")
			senderDone <- struct{}{}
		}()

		for {
			s, err = host.NewStream(context.Background(), remote, protocol.TestingID)
			if err != nil {
				return
			}

			_ = s
			// if err = s.SwarmStream().Stream().Wait(); err != nil {
			// 	return
			// }

			// "count" another successfully opened stream
			// (large buffer so shouldn't block in normal operation)
			log.Debug("sender opened another stream!")
			senderOpened <- struct{}{}
		}
	}

	// count our senderOpened events
	countStreamsOpenedBySender := func(min int) int {
		opened := 0
		for opened < min {
			log.Debugf("countStreamsOpenedBySender got %d (min %d)", opened, min)
			select {
			case <-senderOpened:
				opened++
			case <-time.After(10 * time.Millisecond):
			}
		}
		return opened
	}

	// count our received events
	// waitForNReceivedStreams := func(n int) {
	// 	for n > 0 {
	// 		log.Debugf("waiting for %d received streams...", n)
	// 		select {
	// 		case <-receiverRatelimit:
	// 			n--
	// 		}
	// 	}
	// }

	testStreamsOpened := func(expected int) {
		log.Debugf("testing rate limited to %d streams", expected)
		if n := countStreamsOpenedBySender(expected); n != expected {
			t.Fatalf("rate limiting did not work :( -- %d != %d", expected, n)
		}
	}

	// ok that's enough setup. let's do it!

	ctx := context.Background()
	h1 := bhost.New(swarmt.GenSwarm(t, ctx))
	h2 := bhost.New(swarmt.GenSwarm(t, ctx))

	// setup receiver handler
	h1.SetStreamHandler(protocol.TestingID, receiver)

	h2pi := h2.Peerstore().PeerInfo(h2.ID())
	log.Debugf("dialing %s", h2pi.Addrs)
	if err := h1.Connect(ctx, h2pi); err != nil {
		t.Fatal("Failed to connect:", err)
	}

	// launch sender!
	go sender(h2, h1.ID())

	// ok, what do we expect to happen? the receiver should
	// receive 10 requests and stop receiving, blocking the sender.
	// we can test this by counting 10x senderOpened requests

	<-senderOpened // wait for the sender to successfully open some.
	testStreamsOpened(limit - 1)

	// let's "handle" 3 requests.
	<-requestHandled
	<-requestHandled
	<-requestHandled
	// the sender should've now been able to open exactly 3 more.

	testStreamsOpened(3)

	// shouldn't have opened anything more
	testStreamsOpened(0)

	// let's "handle" 100 requests in batches of 5
	for i := 0; i < 20; i++ {
		<-requestHandled
		<-requestHandled
		<-requestHandled
		<-requestHandled
		<-requestHandled
		testStreamsOpened(5)
	}

	// success!

	// now for the sugar on top: let's tear down the receiver. it should
	// exit the sender.
	h1.Close()

	// shouldn't have opened anything more
	testStreamsOpened(0)

	select {
	case <-time.After(100 * time.Millisecond):
		t.Error("receiver shutdown failed to exit sender")
	case <-senderDone:
		log.Info("handler backpressure works!")
	}
}

// TestStBackpressureStreamWrite tests whether streams see proper
// backpressure when writing data over the network streams.
func TestStBackpressureStreamWrite(t *testing.T) {

	// senderWrote signals that the sender wrote bytes to remote.
	// the value is the count of bytes written.
	senderWrote := make(chan int, 10000)

	// sender signals it's done (errored out)
	senderDone := make(chan struct{})

	// writeStats lets us listen to all the writes and return
	// how many happened and how much was written
	writeStats := func() (int, int) {
		t.Helper()
		writes := 0
		bytes := 0
		for {
			select {
			case n := <-senderWrote:
				writes++
				bytes = bytes + n
			default:
				log.Debugf("stats: sender wrote %d bytes, %d writes", bytes, writes)
				return bytes, writes
			}
		}
	}

	// sender attempts to write as fast as possible, signaling on the
	// completion of every write. This makes it possible to see how
	// fast it's actually writing. We pair this with a receiver
	// that waits for a signal to read.
	sender := func(s inet.Stream) {
		defer func() {
			s.Close()
			senderDone <- struct{}{}
		}()

		// ready a buffer of random data
		buf := make([]byte, 65536)
		u.NewTimeSeededRand().Read(buf)

		for {
			// send a randomly sized subchunk
			from := rand.Intn(len(buf) / 2)
			to := rand.Intn(len(buf) / 2)
			sendbuf := buf[from : from+to]

			n, err := s.Write(sendbuf)
			if err != nil {
				log.Debug("sender error. exiting:", err)
				return
			}

			log.Debugf("sender wrote %d bytes", n)
			senderWrote <- n
		}
	}

	// receive a number of bytes from a stream.
	// returns the number of bytes written.
	receive := func(s inet.Stream, expect int) {
		t.Helper()
		log.Debugf("receiver to read %d bytes", expect)
		rbuf := make([]byte, expect)
		n, err := io.ReadFull(s, rbuf)
		if err != nil {
			t.Error("read failed:", err)
		}
		if expect != n {
			t.Errorf("read len differs: %d != %d", expect, n)
		}
	}

	// ok let's do it!

	// setup the networks
	ctx := context.Background()
	h1 := bhost.New(swarmt.GenSwarm(t, ctx))
	h2 := bhost.New(swarmt.GenSwarm(t, ctx))

	// setup sender handler on 1
	h1.SetStreamHandler(protocol.TestingID, sender)

	h2pi := h2.Peerstore().PeerInfo(h2.ID())
	log.Debugf("dialing %s", h2pi.Addrs)
	if err := h1.Connect(ctx, h2pi); err != nil {
		t.Fatal("Failed to connect:", err)
	}

	// open a stream, from 2->1, this is our reader
	s, err := h2.NewStream(context.Background(), h1.ID(), protocol.TestingID)
	if err != nil {
		t.Fatal(err)
	}

	// let's make sure r/w works.
	testSenderWrote := func(bytesE int) {
		t.Helper()
		bytesA, writesA := writeStats()
		if bytesA != bytesE {
			t.Errorf("numbers failed: %d =?= %d bytes, via %d writes", bytesA, bytesE, writesA)
		}
	}

	// trigger lazy connection handshaking
	_, err = s.Read(nil)
	if err != nil {
		t.Fatal(err)
	}

	// 500ms rounds of lockstep write + drain
	roundsStart := time.Now()
	roundsTotal := 0
	for roundsTotal < (2 << 20) {
		// let the sender fill its buffers, it will stop sending.
		<-time.After(400 * time.Millisecond)
		b, _ := writeStats()
		testSenderWrote(0)
		testSenderWrote(0)

		// drain it all, wait again
		receive(s, b)
		roundsTotal = roundsTotal + b
	}
	roundsTime := time.Since(roundsStart)

	// now read continously, while we measure stats.
	stop := make(chan struct{})
	contStart := time.Now()

	go func() {
		for {
			select {
			case <-stop:
				return
			default:
				receive(s, 2<<15)
			}
		}
	}()

	contTotal := 0
	for contTotal < (2 << 20) {
		n := <-senderWrote
		contTotal += n
	}
	stop <- struct{}{}
	contTime := time.Since(contStart)

	// now compare! continuous should've been faster AND larger
	if roundsTime < contTime {
		t.Error("continuous should have been faster")
	}

	if roundsTotal < contTotal {
		t.Error("continuous should have been larger, too!")
	}

	// and a couple rounds more for good measure ;)
	for i := 0; i < 3; i++ {
		// let the sender fill its buffers, it will stop sending.
		<-time.After(400 * time.Millisecond)
		b, _ := writeStats()
		testSenderWrote(0)
		testSenderWrote(0)

		// drain it all, wait again
		receive(s, b)
	}

	// this doesn't work :(:
	// // now for the sugar on top: let's tear down the receiver. it should
	// // exit the sender.
	// n1.Close()
	// testSenderWrote(0)
	// testSenderWrote(0)
	// select {
	// case <-time.After(2 * time.Second):
	// 	t.Error("receiver shutdown failed to exit sender")
	// case <-senderDone:
	// 	log.Info("handler backpressure works!")
	// }
}
<commit_msg>test: increase delay for backpressure<commit_after>package backpressure_tests

import (
	"context"
	"io"
	"math/rand"
	"testing"
	"time"

	bhost "github.com/libp2p/go-libp2p/p2p/host/basic"

	u "github.com/ipfs/go-ipfs-util"
	logging "github.com/ipfs/go-log"
	host "github.com/libp2p/go-libp2p-host"
	inet "github.com/libp2p/go-libp2p-net"
	peer "github.com/libp2p/go-libp2p-peer"
	protocol "github.com/libp2p/go-libp2p-protocol"
	swarmt "github.com/libp2p/go-libp2p-swarm/testing"
)

var log = logging.Logger("backpressure")

// TestBackpressureStreamHandler tests whether mux handler
// ratelimiting works. Meaning, since the handler is sequential
// it should block senders.
//
// Important note: spdystream (which peerstream uses) has a set
// of n workers (n=spdsystream.FRAME_WORKERS) which handle new
// frames, including those starting new streams. So all of them
// can be in the handler at one time. Also, the sending side
// does not rate limit unless we call stream.Wait()
//
//
// Note: right now, this happens muxer-wide. the muxer should
// learn to flow control, so handlers cant block each other.
func TestBackpressureStreamHandler(t *testing.T) {
	t.Skip(`Sadly, as cool as this test is, it doesn't work
Because spdystream doesnt handle stream open backpressure
well IMO. I'll see about rewriting that part when it becomes
a problem.
`)

	// a number of concurrent request handlers
	limit := 10

	// our way to signal that we're done with 1 request
	requestHandled := make(chan struct{})

	// handler rate limiting
	receiverRatelimit := make(chan struct{}, limit)
	for i := 0; i < limit; i++ {
		receiverRatelimit <- struct{}{}
	}

	// sender counter of successfully opened streams
	senderOpened := make(chan struct{}, limit*100)

	// sender signals it's done (errored out)
	senderDone := make(chan struct{})

	// the receiver handles requests with some rate limiting
	receiver := func(s inet.Stream) {
		log.Debug("receiver received a stream")

		<-receiverRatelimit // acquire
		go func() {
			// our request handler. can do stuff here. we
			// simulate something taking time by waiting
			// on requestHandled
			log.Debug("request worker handling...")
			<-requestHandled
			log.Debug("request worker done!")
			receiverRatelimit <- struct{}{} // release
		}()
	}

	// the sender opens streams as fast as possible
	sender := func(host host.Host, remote peer.ID) {
		var s inet.Stream
		var err error
		defer func() {
			t.Error(err)
			log.Debug("sender error. exiting.")
			senderDone <- struct{}{}
		}()

		for {
			s, err = host.NewStream(context.Background(), remote, protocol.TestingID)
			if err != nil {
				return
			}

			_ = s
			// if err = s.SwarmStream().Stream().Wait(); err != nil {
			// 	return
			// }

			// "count" another successfully opened stream
			// (large buffer so shouldn't block in normal operation)
			log.Debug("sender opened another stream!")
			senderOpened <- struct{}{}
		}
	}

	// count our senderOpened events
	countStreamsOpenedBySender := func(min int) int {
		opened := 0
		for opened < min {
			log.Debugf("countStreamsOpenedBySender got %d (min %d)", opened, min)
			select {
			case <-senderOpened:
				opened++
			case <-time.After(10 * time.Millisecond):
			}
		}
		return opened
	}

	// count our received events
	// waitForNReceivedStreams := func(n int) {
	// 	for n > 0 {
	// 		log.Debugf("waiting for %d received streams...", n)
	// 		select {
	// 		case <-receiverRatelimit:
	// 			n--
	// 		}
	// 	}
	// }

	testStreamsOpened := func(expected int) {
		log.Debugf("testing rate limited to %d streams", expected)
		if n := countStreamsOpenedBySender(expected); n != expected {
			t.Fatalf("rate limiting did not work :( -- %d != %d", expected, n)
		}
	}

	// ok that's enough setup. let's do it!

	ctx := context.Background()
	h1 := bhost.New(swarmt.GenSwarm(t, ctx))
	h2 := bhost.New(swarmt.GenSwarm(t, ctx))

	// setup receiver handler
	h1.SetStreamHandler(protocol.TestingID, receiver)

	h2pi := h2.Peerstore().PeerInfo(h2.ID())
	log.Debugf("dialing %s", h2pi.Addrs)
	if err := h1.Connect(ctx, h2pi); err != nil {
		t.Fatal("Failed to connect:", err)
	}

	// launch sender!
	go sender(h2, h1.ID())

	// ok, what do we expect to happen? the receiver should
	// receive 10 requests and stop receiving, blocking the sender.
	// we can test this by counting 10x senderOpened requests

	<-senderOpened // wait for the sender to successfully open some.
	testStreamsOpened(limit - 1)

	// let's "handle" 3 requests.
	<-requestHandled
	<-requestHandled
	<-requestHandled
	// the sender should've now been able to open exactly 3 more.

	testStreamsOpened(3)

	// shouldn't have opened anything more
	testStreamsOpened(0)

	// let's "handle" 100 requests in batches of 5
	for i := 0; i < 20; i++ {
		<-requestHandled
		<-requestHandled
		<-requestHandled
		<-requestHandled
		<-requestHandled
		testStreamsOpened(5)
	}

	// success!

	// now for the sugar on top: let's tear down the receiver. it should
	// exit the sender.
	h1.Close()

	// shouldn't have opened anything more
	testStreamsOpened(0)

	select {
	case <-time.After(100 * time.Millisecond):
		t.Error("receiver shutdown failed to exit sender")
	case <-senderDone:
		log.Info("handler backpressure works!")
	}
}

// TestStBackpressureStreamWrite tests whether streams see proper
// backpressure when writing data over the network streams.
func TestStBackpressureStreamWrite(t *testing.T) {

	// senderWrote signals that the sender wrote bytes to remote.
	// the value is the count of bytes written.
	senderWrote := make(chan int, 10000)

	// sender signals it's done (errored out)
	senderDone := make(chan struct{})

	// writeStats lets us listen to all the writes and return
	// how many happened and how much was written
	writeStats := func() (int, int) {
		t.Helper()
		writes := 0
		bytes := 0
		for {
			select {
			case n := <-senderWrote:
				writes++
				bytes = bytes + n
			default:
				log.Debugf("stats: sender wrote %d bytes, %d writes", bytes, writes)
				return bytes, writes
			}
		}
	}

	// sender attempts to write as fast as possible, signaling on the
	// completion of every write. This makes it possible to see how
	// fast it's actually writing. We pair this with a receiver
	// that waits for a signal to read.
	sender := func(s inet.Stream) {
		defer func() {
			s.Close()
			senderDone <- struct{}{}
		}()

		// ready a buffer of random data
		buf := make([]byte, 65536)
		u.NewTimeSeededRand().Read(buf)

		for {
			// send a randomly sized subchunk
			from := rand.Intn(len(buf) / 2)
			to := rand.Intn(len(buf) / 2)
			sendbuf := buf[from : from+to]

			n, err := s.Write(sendbuf)
			if err != nil {
				log.Debug("sender error. exiting:", err)
				return
			}

			log.Debugf("sender wrote %d bytes", n)
			select {
			case senderWrote <- n:
			default:
				t.Error("sender wrote channel full")
			}
		}
	}

	// receive a number of bytes from a stream.
	// returns the number of bytes written.
	receive := func(s inet.Stream, expect int) {
		t.Helper()
		log.Debugf("receiver to read %d bytes", expect)
		rbuf := make([]byte, expect)
		n, err := io.ReadFull(s, rbuf)
		if err != nil {
			t.Error("read failed:", err)
		}
		if expect != n {
			t.Errorf("read len differs: %d != %d", expect, n)
		}
	}

	// ok let's do it!

	// setup the networks
	ctx := context.Background()
	h1 := bhost.New(swarmt.GenSwarm(t, ctx))
	h2 := bhost.New(swarmt.GenSwarm(t, ctx))

	// setup sender handler on 1
	h1.SetStreamHandler(protocol.TestingID, sender)

	h2pi := h2.Peerstore().PeerInfo(h2.ID())
	log.Debugf("dialing %s", h2pi.Addrs)
	if err := h1.Connect(ctx, h2pi); err != nil {
		t.Fatal("Failed to connect:", err)
	}

	// open a stream, from 2->1, this is our reader
	s, err := h2.NewStream(context.Background(), h1.ID(), protocol.TestingID)
	if err != nil {
		t.Fatal(err)
	}

	// let's make sure r/w works.
	testSenderWrote := func(bytesE int) {
		t.Helper()
		bytesA, writesA := writeStats()
		if bytesA != bytesE {
			t.Errorf("numbers failed: %d =?= %d bytes, via %d writes", bytesA, bytesE, writesA)
		}
	}

	// trigger lazy connection handshaking
	_, err = s.Read(nil)
	if err != nil {
		t.Fatal(err)
	}

	// 500ms rounds of lockstep write + drain
	roundsStart := time.Now()
	roundsTotal := 0
	for roundsTotal < (2 << 20) {
		// let the sender fill its buffers, it will stop sending.
		<-time.After(time.Second)
		b, _ := writeStats()
		testSenderWrote(0)
		<-time.After(100 * time.Millisecond)
		testSenderWrote(0)

		// drain it all, wait again
		receive(s, b)
		roundsTotal = roundsTotal + b
	}
	roundsTime := time.Since(roundsStart)

	// now read continously, while we measure stats.
	stop := make(chan struct{})
	contStart := time.Now()

	go func() {
		for {
			select {
			case <-stop:
				return
			default:
				receive(s, 2<<15)
			}
		}
	}()

	contTotal := 0
	for contTotal < (2 << 20) {
		n := <-senderWrote
		contTotal += n
	}
	stop <- struct{}{}
	contTime := time.Since(contStart)

	// now compare! continuous should've been faster AND larger
	if roundsTime < contTime {
		t.Error("continuous should have been faster")
	}

	if roundsTotal < contTotal {
		t.Error("continuous should have been larger, too!")
	}

	// and a couple rounds more for good measure ;)
	for i := 0; i < 3; i++ {
		// let the sender fill its buffers, it will stop sending.
		<-time.After(time.Second)
		b, _ := writeStats()
		testSenderWrote(0)
		<-time.After(100 * time.Millisecond)
		testSenderWrote(0)

		// drain it all, wait again
		receive(s, b)
	}

	// this doesn't work :(:
	// // now for the sugar on top: let's tear down the receiver. it should
	// // exit the sender.
	// n1.Close()
	// testSenderWrote(0)
	// testSenderWrote(0)
	// select {
	// case <-time.After(2 * time.Second):
	// 	t.Error("receiver shutdown failed to exit sender")
	// case <-senderDone:
	// 	log.Info("handler backpressure works!")
	// }
}
<|endoftext|>


<commit_before>// +build ignore

package main

import (
	"encoding/binary"
	"fmt"
	"net/http"
	"os"
	"sync"
)

func panicIfError(err error) {
	if err != nil {
		fmt.Println("Fatal error ", err.Error())
		os.Exit(1)
	}
}

type Promise interface {
	Then(func(value interface{}) Promise) Promise
}

type AsyncRequest struct {
	Promise
	body int64
}

func (aReq *AsyncRequest) Then(chain func(value interface{}) Promise) Promise {
	return chain(aReq.body)
}

func (aReq *AsyncRequest) Get(path string) Promise {
	wait := make(chan int64)
	go func() {
		res, err := http.Get(path)
		defer res.Body.Close()
		panicIfError(err)
		var answer int64
		err = binary.Read(res.Body, binary.LittleEndian, &answer)
		panicIfError(err)
		wait <- answer
	}()
	aReq.body = <-wait
	return aReq
}

func main() {
	req := &AsyncRequest{}
	var wg sync.WaitGroup
	for i := 1; i <= 100; i++ {
		wg.Add(1)
		go func(r *AsyncRequest, iter int) {
			fmt.Println("Asynchronous Gets")
			r.Get("http://localhost:3000/odd").Then(func(response interface{}) Promise {
				fmt.Fprintf(os.Stdout, "(ODD) From Promise %d value => %v\n", iter, response)
				req2 := &AsyncRequest{}
				return req2.Get("http://localhost:3000/pair").Then(func(response interface{}) Promise {
					fmt.Fprintf(os.Stdout, "(PAIR) From Innert Promise %d value => %v\n", iter, response)
					wg.Done()
					return nil
				})
			})
		}(req, i)
	}
	wg.Wait()
}
<commit_msg>Do not block promise, let it run and sen it's answer over channels<commit_after>// +build ignore

package main

import (
	"encoding/binary"
	"fmt"
	"net/http"
	"os"
	"sync"
)

func panicIfError(err error) {
	if err != nil {
		fmt.Println("Fatal error ", err.Error())
		os.Exit(1)
	}
}

type Promise interface {
	Then(func(value interface{}) Promise) Promise
}

type AsyncRequest struct {
	Promise
	body chan int64
}

func NewAsyncRequest() *AsyncRequest {
	return &AsyncRequest{
		body: make(chan int64),
	}
}

func (aReq *AsyncRequest) Then(chain func(value interface{}) Promise) Promise {
	return chain(<-aReq.body)
}

func (aReq *AsyncRequest) Get(path string) Promise {
	go func() {
		res, err := http.Get(path)
		defer res.Body.Close()
		panicIfError(err)
		var answer int64
		err = binary.Read(res.Body, binary.LittleEndian, &answer)
		panicIfError(err)
		aReq.body <- answer
	}()
	return aReq
}

func main() {
	req := NewAsyncRequest()
	var wg sync.WaitGroup
	for i := 1; i <= 100; i++ {
		wg.Add(1)
		go func(r *AsyncRequest, iter int) {
			fmt.Println("Asynchronous Gets")
			r.Get("http://localhost:3000/odd").Then(func(response interface{}) Promise {
				fmt.Fprintf(os.Stdout, "(ODD) From Promise %d value => %v\n", iter, response)
				req2 := NewAsyncRequest()
				return req2.Get("http://localhost:3000/pair").Then(func(response interface{}) Promise {
					fmt.Fprintf(os.Stdout, "(PAIR) From Innert Promise %d value => %v\n", iter, response)
					wg.Done()
					return nil
				})
			})
		}(req, i)
	}
	wg.Wait()
}
<|endoftext|>


<commit_before>package manta

var huf HuffmanTree

func init() {
	if huf == nil {
		huf = newFieldpathHuffman()
	}
}

// Properties is an instance of a set of properties containing key-value data.
type Properties struct {
	KV map[string]interface{}
}

// Creates a new instance of Properties.
func NewProperties() *Properties {
	return &Properties{
		KV: map[string]interface{}{},
	}
}

// Merge another set of Properties into an existing instance. Values from the
// other (merging) set overwrite those in the existing instance.
func (p *Properties) Merge(p2 *Properties) {
	for k, v := range p2.KV {
		p.KV[k] = v
	}
}

// Fetch a value by key.
func (p *Properties) Fetch(k string) (interface{}, bool) {
	v, ok := p.KV[k]
	return v, ok
}

// Reads properties using a given reader and serializer.
func ReadProperties(r *Reader, ser *dt) (result *Properties) {
	// Return type
	result = NewProperties()

	// Create fieldpath
	fieldPath := newFieldpath(ser, &huf)

	// Get a list of the included fields
	fieldPath.walk(r)

	// iterate all the fields and set their corresponding values
	for _, f := range fieldPath.fields {
		_debugfl(6, "Decoding field %d %s %s %s", r.pos, f.Name, f.Field.Type, f.Field.Encoder)
		// r.dumpBits(1)

		if f.Field.Serializer.DecodeContainer != nil {
			_debugfl(6, "Decoding container %v", f.Field.Name)
			result.KV[f.Name] = f.Field.Serializer.DecodeContainer(r, f.Field)
		} else if f.Field.Serializer.Decode == nil {
			result.KV[f.Name] = r.readVarUint32()
			_debugfl(6, "Decoded default: %d %s %s %v", r.pos, f.Name, f.Field.Type, result.KV[f.Name])
			continue
		} else {
			result.KV[f.Name] = f.Field.Serializer.Decode(r, f.Field)
		}

		_debugfl(6, "Decoded: %d %s %s %v", r.pos, f.Name, f.Field.Type, result.KV[f.Name])
	}

	return result
}
<commit_msg>Add safe typed fetch convenience methods to Properties<commit_after>package manta

var huf HuffmanTree

func init() {
	if huf == nil {
		huf = newFieldpathHuffman()
	}
}

// Properties is an instance of a set of properties containing key-value data.
type Properties struct {
	KV map[string]interface{}
}

// Creates a new instance of Properties.
func NewProperties() *Properties {
	return &Properties{
		KV: map[string]interface{}{},
	}
}

// Merge another set of Properties into an existing instance. Values from the
// other (merging) set overwrite those in the existing instance.
func (p *Properties) Merge(p2 *Properties) {
	for k, v := range p2.KV {
		p.KV[k] = v
	}
}

// Fetch a value by key.
func (p *Properties) Fetch(k string) (interface{}, bool) {
	v, ok := p.KV[k]
	return v, ok
}

// Fetch a bool by key.
func (p *Properties) FetchBool(k string) (bool, bool) {
	if v, ok := p.KV[k]; ok {
		if x, ok := v.(bool); ok {
			return x, true
		}
	}
	return false, false
}

// Fetch an int32 by key.
func (p *Properties) FetchInt32(k string) (int32, bool) {
	if v, ok := p.KV[k]; ok {
		if x, ok := v.(int32); ok {
			return x, true
		}
	}
	return 0, false
}

// Fetch a uint32 by key.
func (p *Properties) FetchUint32(k string) (uint32, bool) {
	if v, ok := p.KV[k]; ok {
		if x, ok := v.(uint32); ok {
			return x, true
		}
	}
	return 0, false
}

// Fetch a uint64 by key.
func (p *Properties) FetchUint64(k string) (uint64, bool) {
	if v, ok := p.KV[k]; ok {
		if x, ok := v.(uint64); ok {
			return x, true
		}
	}
	return 0, false
}

// Fetch a float32 by key.
func (p *Properties) FetchFloat32(k string) (float32, bool) {
	if v, ok := p.KV[k]; ok {
		if x, ok := v.(float32); ok {
			return x, true
		}
	}
	return 0.0, false
}

// Fetch a string by key.
func (p *Properties) FetchString(k string) (string, bool) {
	if v, ok := p.KV[k]; ok {
		if x, ok := v.(string); ok {
			return x, true
		}
	}
	return "", false
}

// Reads properties using a given reader and serializer.
func ReadProperties(r *Reader, ser *dt) (result *Properties) {
	// Return type
	result = NewProperties()

	// Create fieldpath
	fieldPath := newFieldpath(ser, &huf)

	// Get a list of the included fields
	fieldPath.walk(r)

	// iterate all the fields and set their corresponding values
	for _, f := range fieldPath.fields {
		_debugfl(6, "Decoding field %d %s %s %s", r.pos, f.Name, f.Field.Type, f.Field.Encoder)
		// r.dumpBits(1)

		if f.Field.Serializer.DecodeContainer != nil {
			_debugfl(6, "Decoding container %v", f.Field.Name)
			result.KV[f.Name] = f.Field.Serializer.DecodeContainer(r, f.Field)
		} else if f.Field.Serializer.Decode == nil {
			result.KV[f.Name] = r.readVarUint32()
			_debugfl(6, "Decoded default: %d %s %s %v", r.pos, f.Name, f.Field.Type, result.KV[f.Name])
			continue
		} else {
			result.KV[f.Name] = f.Field.Serializer.Decode(r, f.Field)
		}

		_debugfl(6, "Decoded: %d %s %s %v", r.pos, f.Name, f.Field.Type, result.KV[f.Name])
	}

	return result
}
<|endoftext|>


<commit_before>package QesyGo

import (
	"github.com/golang/protobuf/proto"
)

func Unmarshal(data []byte, pbStruct proto.Message) error {
	return proto.Unmarshal(data[4:], pbStruct)
}

func Marshal(ProtoId int32, pbStruct proto.Message) ([]byte, error) {
	return proto.Marshal(pbStruct)
}
<commit_msg>fix bugs<commit_after>package QesyGo

import (
	"github.com/golang/protobuf/proto"
)

func Unmarshal(data []byte, pbStruct proto.Message) error {
	return proto.Unmarshal(data[4:], pbStruct)
}

func Marshal(ProtoId int32, pbStruct proto.Message) ([]byte, error) {
	data := []byte{}
	if msg, err := proto.Marshal(pbStruct); err != nil {
		return msg, err
	} else {
		PidByte := IntToBytes(ProtoId)
		data = append(data, PidByte...)
		data = append(data, msg...)
	}
	return data, nil
}
<|endoftext|>


<commit_before>package main

import (
        "encoding/json"
        "flag"
        "fmt"
        "io/ioutil"
        "net/http"
        "strings"
        "time"
        "os"
)

type Stop struct {
        V            int     `json:"__v,int"`
        Id           string  `json:"_id"`
        City         string
        Name         string
        Sort_id      int
        Destinations []Destination
}

type Destination struct {
        V            int     `json:"__v,int"`
        Id           string  `json:"_id"`
        City         string
        Name         string
        Sort_id      int
        Destinations []string
}

type Time struct {
        FromId  string
        From    string
        ToId    string
        To      string
        Date    string
        //Arrival string
        Route   int
        Busstop string
        Hash    string
        Id      string  `json:"_id"`
        V       int     `json:"__v"`
}

func main() {
        busStopsURL := "http://rutebuss.no/stops/Tromsø"

        resp, err := http.Get(busStopsURL)
        if err != nil {
                fmt.Print("Bus stops could not be downlaoded...", err)
                return
        }

        body, err := ioutil.ReadAll(resp.Body)

        if err != nil {
                fmt.Println("Could not read body ", err)
                return
        }

        stops := make([]Stop, 100)

        err = json.Unmarshal(body, &stops)

        if err != nil {
                fmt.Println("Error contacting rutebuss.no")
                return
        }

        fromString := flag.String("from", "UiT",
                "The bus stop you are traveling from")
        toString := flag.String("to", "Sentrum",
                "The bus stop you are traveling to")

        invert := flag.Bool("i", false,
            "Switch the from and to values with each other")

        specificTime := flag.String("time", "now",
                "Specific time of departure. Formatted as hour:minute")

        flag.Usage = func(){
            fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
            flag.PrintDefaults()
            fmt.Fprintf(os.Stderr, "\nAvailible stops: \n")//+availibleStops)
            for i, _ := range stops {
                if i%2 == 0 {
                    if i == len(stops) - 1 {
                        fmt.Fprintln(os.Stderr, stops[i].Name)
                    } else {
                        fmt.Fprintf(os.Stderr, "%-20s%s\n", stops[i].Name, stops[i+1].Name)
                    }
                }
            }
        }

        flag.Parse()
        if *invert {
            tmp := fromString
            fromString = toString
            toString = tmp
        }

        fmt.Println("From", *fromString, "to", *toString)

        var from, to string

        for _, stop := range stops {
                if strings.ToLower(stop.Name) == strings.ToLower(*fromString) {
                        from = stop.Id
                }
                if strings.ToLower(stop.Name) == strings.ToLower(*toString) {
                        to = stop.Id
                }
        }

        if from == "" && to == "" {
                fmt.Println("Bus route ", from, "-", to, "does not exist")
                return
        }

        var t time.Time
        var timeString string

        if *specificTime != "now" {
            const layout = "15:04"

            location, _ := time.LoadLocation("Local")

            t, err = time.ParseInLocation(layout, *specificTime, location)

            if err != nil {
                fmt.Println("Error: Could not parse time:", *specificTime)
                fmt.Println(t)
                //flag.Usage()
                return
            }

            t_now := time.Now()
            y,m,d := t_now.Date()

            // date() gave day and month +1 :(
            d = d - 1
            mnth := int(m) - 1

            // since t object is 0000-00-00Thour:minute we need to add today's
            // date and everything.
            t = t.AddDate(y,mnth,d)

            timeString = t.UTC().Format(time.RFC3339)
        } else {
            t = time.Now()
            timeString = t.UTC().Format(time.RFC3339)
        }

        travelURL :=
                "http://rutebuss.no/departure?from=" + from + "&to=" + to + "&date=" + timeString

        resp, err = http.Get(travelURL)
        if err != nil {
                fmt.Print("Bus times could not be downlaoded...", err)
                return
        }

        body, err = ioutil.ReadAll(resp.Body)

        if err != nil {
                fmt.Println("Could not read body ", err)
                return
        }

        times := make([]Time, 10)

        err = json.Unmarshal(body, &times)

        if err != nil {
                fmt.Println("Bus route ", *fromString, "-", *toString, "does not exist")
                return
        }

        if len(times) == 0 {
                fmt.Println("Bus route ", *fromString, "-", *toString, "does not exist")
        }

        for _, departure_time := range times {

                departure, err := time.Parse(time.RFC3339, departure_time.Date)

                if err != nil {
                        fmt.Println("Parsing of date went horrible... ", err)
                }

                untilDeparture := departure.Sub(time.Now())
                untilDString := untilDeparture.String()
                untilDString = strings.Split(untilDString, ".")[0]
                untilDString = untilDString + "s"

                hour := time.Hour
                departure = departure.Add(hour)
                // Daylight savings bug. We'll have to look at it later.
                departure = departure.Add(hour)

                tm := departure.Format(time.Kitchen)
                fmt.Println("Bus", departure_time.Route, "leaves at", tm, "in",
                        untilDString, "from", departure_time.Busstop)
        }

}
<commit_msg>Daylight saving commit<commit_after>package main

import (
        "encoding/json"
        "flag"
        "fmt"
        "io/ioutil"
        "net/http"
        "strings"
        "time"
        "os"
)

type Stop struct {
        V            int     `json:"__v,int"`
        Id           string  `json:"_id"`
        City         string
        Name         string
        Sort_id      int
        Destinations []Destination
}

type Destination struct {
        V            int     `json:"__v,int"`
        Id           string  `json:"_id"`
        City         string
        Name         string
        Sort_id      int
        Destinations []string
}

type Time struct {
        FromId  string
        From    string
        ToId    string
        To      string
        Date    string
        //Arrival string
        Route   int
        Busstop string
        Hash    string
        Id      string  `json:"_id"`
        V       int     `json:"__v"`
}

func main() {
        busStopsURL := "http://rutebuss.no/stops/Tromsø"

        resp, err := http.Get(busStopsURL)
        if err != nil {
                fmt.Print("Bus stops could not be downlaoded...", err)
                return
        }

        body, err := ioutil.ReadAll(resp.Body)

        if err != nil {
                fmt.Println("Could not read body ", err)
                return
        }

        stops := make([]Stop, 100)

        err = json.Unmarshal(body, &stops)

        if err != nil {
                fmt.Println("Error contacting rutebuss.no")
                return
        }

        fromString := flag.String("from", "UiT",
                "The bus stop you are traveling from")
        toString := flag.String("to", "Sentrum",
                "The bus stop you are traveling to")

        invert := flag.Bool("i", false,
            "Switch the from and to values with each other")

        specificTime := flag.String("time", "now",
                "Specific time of departure. Formatted as hour:minute")

        flag.Usage = func(){
            fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
            flag.PrintDefaults()
            fmt.Fprintf(os.Stderr, "\nAvailible stops: \n")//+availibleStops)
            for i, _ := range stops {
                if i%2 == 0 {
                    if i == len(stops) - 1 {
                        fmt.Fprintln(os.Stderr, stops[i].Name)
                    } else {
                        fmt.Fprintf(os.Stderr, "%-20s%s\n", stops[i].Name, stops[i+1].Name)
                    }
                }
            }
        }

        flag.Parse()
        if *invert {
            tmp := fromString
            fromString = toString
            toString = tmp
        }

        fmt.Println("From", *fromString, "to", *toString)

        var from, to string
        for _, stop := range stops {
                if strings.ToLower(stop.Name) == strings.ToLower(*fromString) {
                        from = stop.Id
                }
                if strings.ToLower(stop.Name) == strings.ToLower(*toString) {
                        to = stop.Id
                }
        }

        if from == "" && to == "" {
                fmt.Println("Bus route ", from, "-", to, "does not exist")
                return
        }

        var t time.Time
        var timeString string

        if *specificTime != "now" {
            const layout = "15:04"

            location, _ := time.LoadLocation("Local")

            t, err = time.ParseInLocation(layout, *specificTime, location)

            if err != nil {
                fmt.Println("Error: Could not parse time:", *specificTime)
                fmt.Println(t)
                //flag.Usage()
                return
            }

            t_now := time.Now()
            y,m,d := t_now.Date()

            // date() gave day and month +1 :(
            d = d - 1
            mnth := int(m) - 1

            // since t object is 0000-00-00Thour:minute we need to add today's
            // date and everything.
            t = t.AddDate(y,mnth,d)

            timeString = t.UTC().Format(time.RFC3339)
        } else {
            t = time.Now()
            timeString = t.UTC().Format(time.RFC3339)
        }

        travelURL :=
                "http://rutebuss.no/departure?from=" + from + "&to=" + to + "&date=" + timeString

        resp, err = http.Get(travelURL)
        if err != nil {
                fmt.Print("Bus times could not be downlaoded...", err)
                return
        }

        body, err = ioutil.ReadAll(resp.Body)

        if err != nil {
                fmt.Println("Could not read body ", err)
                return
        }

        times := make([]Time, 10)

        err = json.Unmarshal(body, &times)

        if err != nil {
                fmt.Println("Bus route ", *fromString, "-", *toString, "does not exist")
                return
        }

        if len(times) == 0 {
                fmt.Println("Bus route ", *fromString, "-", *toString, "does not exist")
        }

        for _, departure_time := range times {

                departure, err := time.Parse(time.RFC3339, departure_time.Date)

                if err != nil {
                        fmt.Println("Parsing of date went horrible... ", err)
                }

                untilDeparture := departure.Sub(time.Now())
                untilDString := untilDeparture.String()
                untilDString = strings.Split(untilDString, ".")[0]
                untilDString = untilDString + "s"

                hour := time.Hour
                departure = departure.Add(hour)
                // Daylight savings bug. We'll have to look at it later.
                // departure = departure.Add(hour)

                tm := departure.Format(time.Kitchen)
                fmt.Println("Bus", departure_time.Route, "leaves at", tm, "in",
                        untilDString, "from", departure_time.Busstop)
        }

}
<|endoftext|>


<commit_before>package uik

import (
	"github.com/skelterjohn/go.wde"
	"code.google.com/p/draw2d/draw2d"
	"image/color"
)

type Button struct {
	Block
	Label *Label
	pressed bool

	Click chan<- wde.Button
	click chan wde.Button
}

func NewButton(label string) (b *Button) {
	b = new(Button)
	b.MakeChannels()
	b.Label = NewLabel(label)

	b.Min = Coord{0, 0}
	b.Size = Coord{100, 50}

	b.click = make(chan wde.Button)
	b.Click = b.click

	go b.handleEvents()
	go b.handleState()

	b.Paint = func(gc draw2d.GraphicContext) {
		b.draw(gc)
	}

	return
}

func safeRect(path draw2d.GraphicContext, min, max Coord) {
	x1, y1 := min.X, min.Y
	x2, y2 := max.X, max.Y
	x, y := path.LastPoint()
    path.MoveTo(x1, y1)
    path.LineTo(x2, y1)
    path.LineTo(x2, y2)
    path.LineTo(x1, y2)
    path.Close()
    path.MoveTo(x, y)
}

func (b *Button) draw(gc draw2d.GraphicContext) {
	gc.SetStrokeColor(color.Black)
	if b.pressed {
		gc.SetFillColor(color.RGBA{150, 150, 150, 255})
	} else {
		gc.SetFillColor(color.White)
	}
	safeRect(gc, Coord{0, 0}, b.Size)
	gc.FillStroke()
}

func (b *Button) handleState() {
	for {
		select {
		case <-b.click:
			b.Label.TextCh <- "clicked!"
		}
	}
}

func (b *Button) handleEvents() {
	b.ListenedChannels[b.MouseDownEvents] = true
	b.ListenedChannels[b.MouseUpEvents] = true
	for {
		select {
		case <-b.MouseDownEvents:
			b.pressed = true
			b.Parent.Redraw <- b.BoundsInParent()
		case e := <-b.MouseUpEvents:
			b.pressed = false
			b.Click <- e.Which
			b.Parent.Redraw <- b.BoundsInParent()
		case <-b.Draw:
			bgc := b.PrepareBuffer()
			b.doPaint(bgc)
			b.Label.doPaint(bgc)
			b.ParentDrawBuffer <- b.Buffer
		}
	}
}<commit_msg>Update button to include sizes<commit_after>package uik

import (
	"github.com/skelterjohn/go.wde"
	"code.google.com/p/draw2d/draw2d"
	"image/color"
)

type Button struct {
	Block
	Label *Label
	pressed bool

	Click chan<- wde.Button
	click chan wde.Button
}

func NewButton(origin Coord, size Coord, label string) (b *Button) {
	b = new(Button)
	b.MakeChannels()
	b.Label = NewLabel(size, label)

	b.Min = origin
	b.Size = size

	b.click = make(chan wde.Button)
	b.Click = b.click

	go b.handleEvents()
	go b.handleState()

	b.Paint = func(gc draw2d.GraphicContext) {
		b.draw(gc)
	}

	return
}

func safeRect(path draw2d.GraphicContext, min, max Coord) {
	x1, y1 := min.X, min.Y
	x2, y2 := max.X, max.Y
	x, y := path.LastPoint()
    path.MoveTo(x1, y1)
    path.LineTo(x2, y1)
    path.LineTo(x2, y2)
    path.LineTo(x1, y2)
    path.Close()
    path.MoveTo(x, y)
}

func (b *Button) draw(gc draw2d.GraphicContext) {
	gc.SetStrokeColor(color.Black)
	if b.pressed {
		gc.SetFillColor(color.RGBA{150, 150, 150, 255})
	} else {
		gc.SetFillColor(color.White)
	}
	safeRect(gc, Coord{0, 0}, b.Size)
	gc.FillStroke()
}

func (b *Button) handleState() {
	for {
		select {
		case <-b.click:
			b.Label.TextCh <- "clicked!"
		}
	}
}

func (b *Button) handleEvents() {
	b.ListenedChannels[b.MouseDownEvents] = true
	b.ListenedChannels[b.MouseUpEvents] = true
	for {
		select {
		case <-b.MouseDownEvents:
			b.pressed = true
			b.Parent.Redraw <- b.BoundsInParent()
		case e := <-b.MouseUpEvents:
			b.pressed = false
			b.Click <- e.Which
			b.Parent.Redraw <- b.BoundsInParent()
		case dr := <-b.Draw:
			b.doPaint(dr.GC)
			b.Label.doPaint(dr.GC)
			dr.Done<- true
		}
	}
}<|endoftext|>


<commit_before>package acceptance

import (
	"net/http"
	"strings"
	"time"

	"github.com/cloudfoundry-incubator/notifications/acceptance/support"
	"github.com/cloudfoundry-incubator/notifications/application"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Send a notification to a user", func() {
	It("sends a single notification email to a user", func() {
		var templateID string
		var response support.NotifyResponse
		env := application.NewEnvironment()
		clientID := "notifications-sender"
		clientToken := GetClientTokenFor(clientID)
		client := support.NewClient(Servers.Notifications)
		userID := "user-123"

		By("registering a notification", func() {
			code, err := client.Notifications.Register(clientToken.Access, support.RegisterClient{
				SourceName: "Notifications Sender",
				Notifications: map[string]support.RegisterNotification{
					"acceptance-test": {
						Description: "Acceptance Test",
					},
				},
			})
			Expect(err).NotTo(HaveOccurred())
			Expect(code).To(Equal(http.StatusNoContent))
		})

		By("creating a new template", func() {
			var status int
			var err error
			status, templateID, err = client.Templates.Create(clientToken.Access, support.Template{
				Name:    "Star Wars",
				Subject: "Awesomeness {{.Subject}}",
				HTML:    "
Millenium Falcon
{{.HTML}}{{.Endorsement}}",
				Text:    "Millenium Falcon\n{{.Text}}\n{{.Endorsement}}",
			})
			Expect(err).NotTo(HaveOccurred())
			Expect(status).To(Equal(http.StatusCreated))
			Expect(templateID).NotTo(BeNil())
		})

		By("assigning the template to a client", func() {
			status, err := client.Templates.AssignToClient(clientToken.Access, clientID, templateID)
			Expect(err).NotTo(HaveOccurred())
			Expect(status).To(Equal(http.StatusNoContent))
		})

		By("sending a notifications to a user", func() {
			status, responses, err := client.Notify.User(clientToken.Access, userID, support.Notify{
				KindID:  "acceptance-test",
				HTML:    "
this is an acceptance%40test
",
				Text:    "hello from the acceptance test",
				Subject: "my-special-subject",
				ReplyTo: "males@example.com",
			})

			Expect(err).NotTo(HaveOccurred())
			Expect(status).To(Equal(http.StatusOK))

			Expect(responses).To(HaveLen(1))
			response = responses[0]
			Expect(response.Status).To(Equal("queued"))
			Expect(response.Recipient).To(Equal(userID))
			Expect(GUIDRegex.MatchString(response.NotificationID)).To(BeTrue())
		})

		By("verifying that the message was sent", func() {
			Eventually(func() int {
				return len(Servers.SMTP.Deliveries)
			}, 1*time.Second).Should(Equal(1))
			delivery := Servers.SMTP.Deliveries[0]

			Expect(delivery.Sender).To(Equal(env.Sender))
			Expect(delivery.Recipients).To(Equal([]string{"user-123@example.com"}))

			data := strings.Split(string(delivery.Data), "\n")
			Expect(data).To(ContainElement("X-CF-Client-ID: notifications-sender"))
			Expect(data).To(ContainElement("X-CF-Notification-ID: " + response.NotificationID))
			Expect(data).To(ContainElement("Subject: Awesomeness my-special-subject"))
			Expect(data).To(ContainElement("\t\t
Millenium Falcon

this is an acceptance%40test
This message ="))
			Expect(data).To(ContainElement("was sent directly to you."))
			Expect(data).To(ContainElement("hello from the acceptance test"))
			Expect(data).To(ContainElement("This message was sent directly to you."))
		})
	})
})
<commit_msg>Adds ReplyTo field to user acceptance test<commit_after>package acceptance

import (
	"net/http"
	"strings"
	"time"

	"github.com/cloudfoundry-incubator/notifications/acceptance/support"
	"github.com/cloudfoundry-incubator/notifications/application"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Send a notification to a user", func() {
	It("sends a single notification email to a user", func() {
		var templateID string
		var response support.NotifyResponse
		env := application.NewEnvironment()
		clientID := "notifications-sender"
		clientToken := GetClientTokenFor(clientID)
		client := support.NewClient(Servers.Notifications)
		userID := "user-123"

		By("registering a notification", func() {
			code, err := client.Notifications.Register(clientToken.Access, support.RegisterClient{
				SourceName: "Notifications Sender",
				Notifications: map[string]support.RegisterNotification{
					"acceptance-test": {
						Description: "Acceptance Test",
					},
				},
			})
			Expect(err).NotTo(HaveOccurred())
			Expect(code).To(Equal(http.StatusNoContent))
		})

		By("creating a new template", func() {
			var status int
			var err error
			status, templateID, err = client.Templates.Create(clientToken.Access, support.Template{
				Name:    "Star Wars",
				Subject: "Awesomeness {{.Subject}}",
				HTML:    "
Millenium Falcon
{{.HTML}}{{.Endorsement}}",
				Text:    "Millenium Falcon\n{{.Text}}\n{{.Endorsement}}",
			})
			Expect(err).NotTo(HaveOccurred())
			Expect(status).To(Equal(http.StatusCreated))
			Expect(templateID).NotTo(BeNil())
		})

		By("assigning the template to a client", func() {
			status, err := client.Templates.AssignToClient(clientToken.Access, clientID, templateID)
			Expect(err).NotTo(HaveOccurred())
			Expect(status).To(Equal(http.StatusNoContent))
		})

		By("sending a notifications to a user", func() {
			status, responses, err := client.Notify.User(clientToken.Access, userID, support.Notify{
				KindID:  "acceptance-test",
				HTML:    "
this is an acceptance%40test
",
				Text:    "hello from the acceptance test",
				Subject: "my-special-subject",
				ReplyTo: "males@example.com",
			})

			Expect(err).NotTo(HaveOccurred())
			Expect(status).To(Equal(http.StatusOK))

			Expect(responses).To(HaveLen(1))
			response = responses[0]
			Expect(response.Status).To(Equal("queued"))
			Expect(response.Recipient).To(Equal(userID))
			Expect(GUIDRegex.MatchString(response.NotificationID)).To(BeTrue())
		})

		By("verifying that the message was sent", func() {
			Eventually(func() int {
				return len(Servers.SMTP.Deliveries)
			}, 1*time.Second).Should(Equal(1))
			delivery := Servers.SMTP.Deliveries[0]

			Expect(delivery.Sender).To(Equal(env.Sender))
			Expect(delivery.Recipients).To(Equal([]string{"user-123@example.com"}))

			data := strings.Split(string(delivery.Data), "\n")
			Expect(data).To(ContainElement("X-CF-Client-ID: notifications-sender"))
			Expect(data).To(ContainElement("X-CF-Notification-ID: " + response.NotificationID))
			Expect(data).To(ContainElement("Reply-To: males@example.com"))
			Expect(data).To(ContainElement("Subject: Awesomeness my-special-subject"))
			Expect(data).To(ContainElement("\t\t
Millenium Falcon

this is an acceptance%40test
This message ="))
			Expect(data).To(ContainElement("was sent directly to you."))
			Expect(data).To(ContainElement("hello from the acceptance test"))
			Expect(data).To(ContainElement("This message was sent directly to you."))
		})
	})
})
<|endoftext|>


<commit_before>package modbusone

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"testing"
	"time"
)

var _ = os.Stdin

type mockSerial struct {
	io.Reader
	io.Writer
	LastWritten []byte
}

func newMockSerial(r io.Reader, w io.Writer) *mockSerial {
	return &mockSerial{Reader: r, Writer: w}
}
func (s *mockSerial) Write(data []byte) (n int, err error) {
	s.LastWritten = data
	return s.Writer.Write(data)
}
func (s *mockSerial) Close() error                   { return nil }
func (s *mockSerial) MinDelay() time.Duration        { return 0 }
func (s *mockSerial) BytesDelay(n int) time.Duration { return 0 }

//TestHandler runs through each of simplymodbus.ca's samples, conforms both
//end-to-end behavior and wire format
func TestHandler(t *testing.T) {
	//DebugOut = os.Stdout
	slaveID := byte(0x11)
	r1, w1 := io.Pipe() //pipe from client to server
	r2, w2 := io.Pipe() //pipe from server to client

	cc := newMockSerial(r2, w1) //client connection
	sc := newMockSerial(r1, w2) //server connection

	client := NewRTUCLient(cc, slaveID)
	server := NewRTUServer(sc, slaveID)

	subtest := t

	ch := &SimpleHandler{
		OnErrorImp: func(req PDU, errRep PDU) {
			subtest.Errorf("client handler received error:%x in request:%x", errRep, req)
		},
	}
	sh := &SimpleHandler{
		OnErrorImp: func(req PDU, errRep PDU) {
			subtest.Errorf("server handler received error:%x in request:%x", errRep, req)
		},
	}

	go client.Serve(ch)
	go server.Serve(sh)

	testTrans := func(header PDU, req, res RTU) {
		t := subtest
		err := client.DoTransaction(header)
		if err != nil {
			t.Error(err)
		}
		if !bytes.Equal(cc.LastWritten, req) {
			t.Fatal("request is not as expected")
		}
		if !bytes.Equal(sc.LastWritten, res) {
			t.Fatal("response is not as expected")
		}

		//just test GetPDUSizeFromHeader here too
		n := GetRTUSizeFromHeader(req, false)
		if n != len(req) {
			t.Errorf("GetRTUSizeFromHeader got %v, expected %v for req %x", n, len(req), req)
		}
		n = GetRTUSizeFromHeader(res, true)
		if n != len(res) {
			t.Errorf("GetRTUSizeFromHeader got %v, expected %v for res %x", n, len(res), req)
		}

		//make sure LastWritten does not pollute other tests
		cc.LastWritten = nil
		sc.LastWritten = nil
	}

	t.Run(fmt.Sprintf("Read Coil Status (FC=01)"), func(t *testing.T) {
		subtest = t
		header, err := FcReadCoils.MakeRequestHeader(0x0013, 0x0025)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x01, 0x00, 0x13, 0x00, 0x25, 0x0E, 0x84})
		response := RTU([]byte{0x11, 0x01, 0x05, 0xCD, 0x6B, 0xB2, 0x0E, 0x1B, 0x45, 0xE6})
		vs := []bool{
			true, false, true, true, false, false, true, true,
			true, true, false, true, false, true, true, false,
			false, true, false, false, true, true, false, true,
			false, true, true, true, false, false, false, false,
			true, true, false, true, true}
		sh.ReadCoils = func(address, quantity uint16) ([]bool, error) {
			return vs, nil
		}
		ch.WriteCoils = func(address uint16, values []bool) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Read Input Status (FC=02)"), func(t *testing.T) {
		subtest = t
		header, err := FcReadDiscreteInputs.MakeRequestHeader(0x00C4, 0x0016)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x02, 0x00, 0xC4, 0x00, 0x16, 0xBA, 0xA9})
		response := RTU([]byte{0x11, 0x02, 0x03, 0xAC, 0xDB, 0x35, 0x20, 0x18})
		vs := []bool{
			false, false, true, true, false, true, false, true,
			true, true, false, true, true, false, true, true,
			true, false, true, false, true, true}
		sh.ReadDiscreteInputs = func(address, quantity uint16) ([]bool, error) {
			return vs, nil
		}
		ch.WriteDiscreteInputs = func(address uint16, values []bool) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Read Holding Registers (FC=03)"), func(t *testing.T) {
		subtest = t
		header, err := FcReadHoldingRegisters.MakeRequestHeader(0x006B, 0x0003)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x03, 0x00, 0x6B, 0x00, 0x03, 0x76, 0x87})
		response := RTU([]byte{0x11, 0x03, 0x06, 0xAE, 0x41, 0x56, 0x52, 0x43, 0x40, 0x49, 0xAD})
		vs := []uint16{0xAE41, 0x5652, 0x4340}
		sh.ReadHoldingRegisters = func(address, quantity uint16) ([]uint16, error) {
			return vs, nil
		}
		ch.WriteHoldingRegisters = func(address uint16, values []uint16) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Read Input Registers (FC=04)"), func(t *testing.T) {
		subtest = t
		header, err := FcReadInputRegisters.MakeRequestHeader(0x0008, 0x0001)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x04, 0x00, 0x08, 0x00, 0x01, 0xB2, 0x98})
		response := RTU([]byte{0x11, 0x04, 0x02, 0x00, 0x0A, 0xF8, 0xF4})
		vs := []uint16{0x000A}
		sh.ReadInputRegisters = func(address, quantity uint16) ([]uint16, error) {
			return vs, nil
		}
		ch.WriteInputRegisters = func(address uint16, values []uint16) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Write Single Coil (FC=05)"), func(t *testing.T) {
		subtest = t
		header, err := FcWriteSingleCoil.MakeRequestHeader(0x00AC, 1)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x05, 0x00, 0xAC, 0xFF, 0x00, 0x4E, 0x8B})
		response := request
		vs := []bool{true}
		sh.WriteCoils = func(address uint16, values []bool) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		ch.ReadCoils = func(address, quantity uint16) ([]bool, error) {
			return vs, nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Write Single Register (FC=06)"), func(t *testing.T) {
		subtest = t
		header, err := FcWriteSingleRegister.MakeRequestHeader(0x0001, 1)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x06, 0x00, 0x01, 0x00, 0x03, 0x9A, 0x9B})
		response := request
		vs := []uint16{3}
		sh.WriteHoldingRegisters = func(address uint16, values []uint16) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		ch.ReadHoldingRegisters = func(address, quantity uint16) ([]uint16, error) {
			return vs, nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Write Multiple Coils (FC=15)"), func(t *testing.T) {
		subtest = t
		header, err := FcWriteMultipleCoils.MakeRequestHeader(0x0013, 0x000A)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x0F, 0x00, 0x13, 0x00, 0x0A, 0x02, 0xCD, 0x01, 0xBF, 0x0B})
		response := RTU([]byte{0x11, 0x0F, 0x00, 0x13, 0x00, 0x0A, 0x26, 0x99})
		vs := []bool{
			true, false, true, true, false, false, true, true,
			true, false}
		sh.WriteCoils = func(address uint16, values []bool) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		ch.ReadCoils = func(address, quantity uint16) ([]bool, error) {
			return vs, nil
		}
		testTrans(header, request, response)
	})
	t.Run(fmt.Sprintf("Write Multiple Registers (FC=16)"), func(t *testing.T) {
		subtest = t
		header, err := FcWriteMultipleRegisters.MakeRequestHeader(0x0001, 0x0002)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x10, 0x00, 0x01, 0x00, 0x02, 0x04, 0x00, 0x0A, 0x01, 0x02, 0xC6, 0xF0})
		response := RTU([]byte{0x11, 0x10, 0x00, 0x01, 0x00, 0x02, 0x12, 0x98})
		vs := []uint16{0x000A, 0x0102}
		sh.WriteHoldingRegisters = func(address uint16, values []uint16) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		ch.ReadHoldingRegisters = func(address, quantity uint16) ([]uint16, error) {
			return vs, nil
		}
		testTrans(header, request, response)
	})
}
<commit_msg>fix test<commit_after>package modbusone

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"testing"
	"time"
)

var _ = os.Stdin

type mockSerial struct {
	io.Reader
	io.Writer
	LastWritten []byte
	s           Stats
}

func newMockSerial(r io.Reader, w io.Writer) *mockSerial {
	return &mockSerial{Reader: r, Writer: w}
}
func (s *mockSerial) Write(data []byte) (n int, err error) {
	s.LastWritten = data
	return s.Writer.Write(data)
}
func (s *mockSerial) Close() error                   { return nil }
func (s *mockSerial) MinDelay() time.Duration        { return 0 }
func (s *mockSerial) BytesDelay(n int) time.Duration { return 0 }
func (s *mockSerial) Stats() *Stats                  { return &s.s }

//TestHandler runs through each of simplymodbus.ca's samples, conforms both
//end-to-end behavior and wire format
func TestHandler(t *testing.T) {
	//DebugOut = os.Stdout
	slaveID := byte(0x11)
	r1, w1 := io.Pipe() //pipe from client to server
	r2, w2 := io.Pipe() //pipe from server to client

	cc := newMockSerial(r2, w1) //client connection
	sc := newMockSerial(r1, w2) //server connection

	client := NewRTUCLient(cc, slaveID)
	server := NewRTUServer(sc, slaveID)

	subtest := t

	ch := &SimpleHandler{
		OnErrorImp: func(req PDU, errRep PDU) {
			subtest.Errorf("client handler received error:%x in request:%x", errRep, req)
		},
	}
	sh := &SimpleHandler{
		OnErrorImp: func(req PDU, errRep PDU) {
			subtest.Errorf("server handler received error:%x in request:%x", errRep, req)
		},
	}

	go client.Serve(ch)
	go server.Serve(sh)

	testTrans := func(header PDU, req, res RTU) {
		t := subtest
		err := client.DoTransaction(header)
		if err != nil {
			t.Error(err)
		}
		if !bytes.Equal(cc.LastWritten, req) {
			t.Fatal("request is not as expected")
		}
		if !bytes.Equal(sc.LastWritten, res) {
			t.Fatal("response is not as expected")
		}

		//just test GetPDUSizeFromHeader here too
		n := GetRTUSizeFromHeader(req, false)
		if n != len(req) {
			t.Errorf("GetRTUSizeFromHeader got %v, expected %v for req %x", n, len(req), req)
		}
		n = GetRTUSizeFromHeader(res, true)
		if n != len(res) {
			t.Errorf("GetRTUSizeFromHeader got %v, expected %v for res %x", n, len(res), req)
		}

		//make sure LastWritten does not pollute other tests
		cc.LastWritten = nil
		sc.LastWritten = nil
	}

	t.Run(fmt.Sprintf("Read Coil Status (FC=01)"), func(t *testing.T) {
		subtest = t
		header, err := FcReadCoils.MakeRequestHeader(0x0013, 0x0025)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x01, 0x00, 0x13, 0x00, 0x25, 0x0E, 0x84})
		response := RTU([]byte{0x11, 0x01, 0x05, 0xCD, 0x6B, 0xB2, 0x0E, 0x1B, 0x45, 0xE6})
		vs := []bool{
			true, false, true, true, false, false, true, true,
			true, true, false, true, false, true, true, false,
			false, true, false, false, true, true, false, true,
			false, true, true, true, false, false, false, false,
			true, true, false, true, true}
		sh.ReadCoils = func(address, quantity uint16) ([]bool, error) {
			return vs, nil
		}
		ch.WriteCoils = func(address uint16, values []bool) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Read Input Status (FC=02)"), func(t *testing.T) {
		subtest = t
		header, err := FcReadDiscreteInputs.MakeRequestHeader(0x00C4, 0x0016)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x02, 0x00, 0xC4, 0x00, 0x16, 0xBA, 0xA9})
		response := RTU([]byte{0x11, 0x02, 0x03, 0xAC, 0xDB, 0x35, 0x20, 0x18})
		vs := []bool{
			false, false, true, true, false, true, false, true,
			true, true, false, true, true, false, true, true,
			true, false, true, false, true, true}
		sh.ReadDiscreteInputs = func(address, quantity uint16) ([]bool, error) {
			return vs, nil
		}
		ch.WriteDiscreteInputs = func(address uint16, values []bool) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Read Holding Registers (FC=03)"), func(t *testing.T) {
		subtest = t
		header, err := FcReadHoldingRegisters.MakeRequestHeader(0x006B, 0x0003)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x03, 0x00, 0x6B, 0x00, 0x03, 0x76, 0x87})
		response := RTU([]byte{0x11, 0x03, 0x06, 0xAE, 0x41, 0x56, 0x52, 0x43, 0x40, 0x49, 0xAD})
		vs := []uint16{0xAE41, 0x5652, 0x4340}
		sh.ReadHoldingRegisters = func(address, quantity uint16) ([]uint16, error) {
			return vs, nil
		}
		ch.WriteHoldingRegisters = func(address uint16, values []uint16) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Read Input Registers (FC=04)"), func(t *testing.T) {
		subtest = t
		header, err := FcReadInputRegisters.MakeRequestHeader(0x0008, 0x0001)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x04, 0x00, 0x08, 0x00, 0x01, 0xB2, 0x98})
		response := RTU([]byte{0x11, 0x04, 0x02, 0x00, 0x0A, 0xF8, 0xF4})
		vs := []uint16{0x000A}
		sh.ReadInputRegisters = func(address, quantity uint16) ([]uint16, error) {
			return vs, nil
		}
		ch.WriteInputRegisters = func(address uint16, values []uint16) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Write Single Coil (FC=05)"), func(t *testing.T) {
		subtest = t
		header, err := FcWriteSingleCoil.MakeRequestHeader(0x00AC, 1)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x05, 0x00, 0xAC, 0xFF, 0x00, 0x4E, 0x8B})
		response := request
		vs := []bool{true}
		sh.WriteCoils = func(address uint16, values []bool) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		ch.ReadCoils = func(address, quantity uint16) ([]bool, error) {
			return vs, nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Write Single Register (FC=06)"), func(t *testing.T) {
		subtest = t
		header, err := FcWriteSingleRegister.MakeRequestHeader(0x0001, 1)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x06, 0x00, 0x01, 0x00, 0x03, 0x9A, 0x9B})
		response := request
		vs := []uint16{3}
		sh.WriteHoldingRegisters = func(address uint16, values []uint16) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		ch.ReadHoldingRegisters = func(address, quantity uint16) ([]uint16, error) {
			return vs, nil
		}
		testTrans(header, request, response)
	})

	t.Run(fmt.Sprintf("Write Multiple Coils (FC=15)"), func(t *testing.T) {
		subtest = t
		header, err := FcWriteMultipleCoils.MakeRequestHeader(0x0013, 0x000A)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x0F, 0x00, 0x13, 0x00, 0x0A, 0x02, 0xCD, 0x01, 0xBF, 0x0B})
		response := RTU([]byte{0x11, 0x0F, 0x00, 0x13, 0x00, 0x0A, 0x26, 0x99})
		vs := []bool{
			true, false, true, true, false, false, true, true,
			true, false}
		sh.WriteCoils = func(address uint16, values []bool) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		ch.ReadCoils = func(address, quantity uint16) ([]bool, error) {
			return vs, nil
		}
		testTrans(header, request, response)
	})
	t.Run(fmt.Sprintf("Write Multiple Registers (FC=16)"), func(t *testing.T) {
		subtest = t
		header, err := FcWriteMultipleRegisters.MakeRequestHeader(0x0001, 0x0002)
		if err != nil {
			t.Fatal(err)
		}
		request := RTU([]byte{0x11, 0x10, 0x00, 0x01, 0x00, 0x02, 0x04, 0x00, 0x0A, 0x01, 0x02, 0xC6, 0xF0})
		response := RTU([]byte{0x11, 0x10, 0x00, 0x01, 0x00, 0x02, 0x12, 0x98})
		vs := []uint16{0x000A, 0x0102}
		sh.WriteHoldingRegisters = func(address uint16, values []uint16) error {
			for i, b := range values {
				if vs[i] != b {
					t.Errorf("%v'th value changed", i)
				}
			}
			return nil
		}
		ch.ReadHoldingRegisters = func(address, quantity uint16) ([]uint16, error) {
			return vs, nil
		}
		testTrans(header, request, response)
	})
}
<|endoftext|>


<commit_before>package aws

import (
	"os"

	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/terraform"
)

// Provider returns a terraform.ResourceProvider.
func Provider() terraform.ResourceProvider {
	// TODO: Move the validation to this, requires conditional schemas
	// TODO: Move the configuration to this, requires validation

	return &schema.Provider{
		Schema: map[string]*schema.Schema{
			"access_key": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: envDefaultFunc("AWS_ACCESS_KEY"),
				Description: descriptions["access_key"],
			},

			"secret_key": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: envDefaultFunc("AWS_SECRET_KEY"),
				Description: descriptions["secret_key"],
			},

			"region": &schema.Schema{
				Type:         schema.TypeString,
				Required:     true,
				DefaultFunc:  envDefaultFunc("AWS_REGION"),
				Description:  descriptions["region"],
				InputDefault: "us-east-1",
			},
		},

		ResourcesMap: map[string]*schema.Resource{
			"aws_autoscaling_group":       resourceAwsAutoscalingGroup(),
			"aws_db_instance":             resourceAwsDbInstance(),
			"aws_db_parameter_group":      resourceAwsDbParameterGroup(),
			"aws_db_security_group":       resourceAwsDbSecurityGroup(),
			"aws_db_subnet_group":         resourceAwsDbSubnetGroup(),
			"aws_eip":                     resourceAwsEip(),
			"aws_elb":                     resourceAwsElb(),
			"aws_instance":                resourceAwsInstance(),
			"aws_internet_gateway":        resourceAwsInternetGateway(),
			"aws_key_pair":                resourceAwsKeyPair(),
			"aws_launch_configuration":    resourceAwsLaunchConfiguration(),
			"aws_network_acl":             resourceAwsNetworkAcl(),
			"aws_route53_record":          resourceAwsRoute53Record(),
			"aws_route53_zone":            resourceAwsRoute53Zone(),
			"aws_route_table":             resourceAwsRouteTable(),
			"aws_route_table_association": resourceAwsRouteTableAssociation(),
			"aws_s3_bucket":               resourceAwsS3Bucket(),
			"aws_security_group":          resourceAwsSecurityGroup(),
			"aws_subnet":                  resourceAwsSubnet(),
			"aws_vpc":                     resourceAwsVpc(),
		},

		ConfigureFunc: providerConfigure,
	}
}

var descriptions map[string]string

func init() {
	descriptions = map[string]string{
		"region": "The region where AWS operations will take place. Examples\n" +
			"are us-east-1, us-west-2, etc.",

		"access_key": "The access key for API operations. You can retrieve this\n" +
			"from the 'Security & Credentials' section of the AWS console.",

		"secret_key": "The secret key for API operations. You can retrieve this\n" +
			"from the 'Security & Credentials' section of the AWS console.",
	}
}

func envDefaultFunc(k string) schema.SchemaDefaultFunc {
	return func() (interface{}, error) {
		if v := os.Getenv(k); v != "" {
			return v, nil
		}

		return nil, nil
	}
}

func providerConfigure(d *schema.ResourceData) (interface{}, error) {
	config := Config{
		AccessKey: d.Get("access_key").(string),
		SecretKey: d.Get("secret_key").(string),
		Region:    d.Get("region").(string),
	}

	return config.Client()
}
<commit_msg>Move duplicated envDefaultFunc out of each provider and into Schema.<commit_after>package aws

import (
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/terraform"
)

// Provider returns a terraform.ResourceProvider.
func Provider() terraform.ResourceProvider {
	// TODO: Move the validation to this, requires conditional schemas
	// TODO: Move the configuration to this, requires validation

	return &schema.Provider{
		Schema: map[string]*schema.Schema{
			"access_key": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: schema.EnvDefaultFunc("AWS_ACCESS_KEY", nil),
				Description: descriptions["access_key"],
			},

			"secret_key": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: schema.EnvDefaultFunc("AWS_SECRET_KEY", nil),
				Description: descriptions["secret_key"],
			},

			"region": &schema.Schema{
				Type:         schema.TypeString,
				Required:     true,
				DefaultFunc:  schema.EnvDefaultFunc("AWS_REGION", nil),
				Description:  descriptions["region"],
				InputDefault: "us-east-1",
			},
		},

		ResourcesMap: map[string]*schema.Resource{
			"aws_autoscaling_group":       resourceAwsAutoscalingGroup(),
			"aws_db_instance":             resourceAwsDbInstance(),
			"aws_db_parameter_group":      resourceAwsDbParameterGroup(),
			"aws_db_security_group":       resourceAwsDbSecurityGroup(),
			"aws_db_subnet_group":         resourceAwsDbSubnetGroup(),
			"aws_eip":                     resourceAwsEip(),
			"aws_elb":                     resourceAwsElb(),
			"aws_instance":                resourceAwsInstance(),
			"aws_internet_gateway":        resourceAwsInternetGateway(),
			"aws_key_pair":                resourceAwsKeyPair(),
			"aws_launch_configuration":    resourceAwsLaunchConfiguration(),
			"aws_network_acl":             resourceAwsNetworkAcl(),
			"aws_route53_record":          resourceAwsRoute53Record(),
			"aws_route53_zone":            resourceAwsRoute53Zone(),
			"aws_route_table":             resourceAwsRouteTable(),
			"aws_route_table_association": resourceAwsRouteTableAssociation(),
			"aws_s3_bucket":               resourceAwsS3Bucket(),
			"aws_security_group":          resourceAwsSecurityGroup(),
			"aws_subnet":                  resourceAwsSubnet(),
			"aws_vpc":                     resourceAwsVpc(),
		},

		ConfigureFunc: providerConfigure,
	}
}

var descriptions map[string]string

func init() {
	descriptions = map[string]string{
		"region": "The region where AWS operations will take place. Examples\n" +
			"are us-east-1, us-west-2, etc.",

		"access_key": "The access key for API operations. You can retrieve this\n" +
			"from the 'Security & Credentials' section of the AWS console.",

		"secret_key": "The secret key for API operations. You can retrieve this\n" +
			"from the 'Security & Credentials' section of the AWS console.",
	}
}

func providerConfigure(d *schema.ResourceData) (interface{}, error) {
	config := Config{
		AccessKey: d.Get("access_key").(string),
		SecretKey: d.Get("secret_key").(string),
		Region:    d.Get("region").(string),
	}

	return config.Client()
}
<|endoftext|>


<commit_before>// goncurses - ncurses library for Go.
// Copyright 2011 Rob Thornton. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goncurses

// #cgo !windows pkg-config: ncurses
// #cgo windows CFLAGS: -DNCURSES_MOUSE_VERSION
// #cgo windows LDFLAGS: -lpdcurses
// #include <curses.h>
// #include "goncurses.h"
import "C"

import (
	"errors"
	"fmt"
	"unsafe"
)

// BaudRate returns the speed of the terminal in bits per second
func BaudRate() int {
	return int(C.baudrate())
}

// Beep requests the terminal make an audible bell or, if not available,
// flashes the screen. Note that screen flashing doesn't work on all
// terminals
func Beep() {
	C.beep()
}

// Turn on/off buffering; raw user signals are passed to the program for
// handling. Overrides raw mode
func CBreak(on bool) {
	if on {
		C.cbreak()
		return
	}
	C.nocbreak()
}

// Test whether colour values can be changed
func CanChangeColor() bool {
	return bool(C.bool(C.can_change_color()))
}

// Get RGB values for specified colour
func ColorContent(col int16) (int16, int16, int16) {
	var r, g, b C.short
	C.color_content(C.short(col), (*C.short)(&r), (*C.short)(&g),
		(*C.short)(&b))
	return int16(r), int16(g), int16(b)
}

// Return the value of a color pair which can be passed to functions which
// accept attributes like AddChar, AttrOn/Off and Background.
func ColorPair(pair int16) Char {
	return Char(C.ncurses_COLOR_PAIR(C.int(pair)))
}

// CursesVersion returns the version of the ncurses library currently linked to
func CursesVersion() string {
	return C.GoString(C.curses_version())
}

// Set the cursor visibility. Options are: 0 (invisible/hidden), 1 (normal)
// and 2 (extra-visible)
func Cursor(vis byte) error {
	if C.curs_set(C.int(vis)) == C.ERR {
		return errors.New("Failed to enable ")
	}
	return nil
}

// Echo turns on/off the printing of typed characters
func Echo(on bool) {
	if on {
		C.echo()
		return
	}
	C.noecho()
}

// Must be called prior to exiting the program in order to make sure the
// terminal returns to normal operation
func End() {
	C.endwin()
}

// Flash requests the terminal flashes the screen or, if not available,
// make an audible bell. Note that screen flashing doesn't work on all
// terminals
func Flash() {
	C.flash()
}

// FlushInput flushes all input
func FlushInput() error {
	if C.flushinp() == C.ERR {
		return errors.New("Flush input failed")
	}
	return nil
}

// Behaves like cbreak() but also adds a timeout for input. If timeout is
// exceeded after a call to Getch() has been made then GetChar will return
// with an error.
func HalfDelay(delay int) error {
	var cerr C.int
	if delay > 0 {
		cerr = C.halfdelay(C.int(delay))
	}
	if cerr == C.ERR {
		return errors.New("Unable to set delay mode")
	}
	return nil
}

// HasColors returns true if terminal can display colors
func HasColors() bool {
	return bool(C.has_colors())
}

// HasInsertChar return true if the terminal has insert and delete
// character capabilities
func HasInsertChar() bool {
	return bool(C.has_ic())
}

// HasInsertLine returns true if the terminal has insert and delete line
// capabilities. See ncurses documentation for more details
func HasInsertLine() bool {
	return bool(C.has_il())
}

// HasKey returns true if terminal recognized the given character
func HasKey(ch Key) bool {
	if C.ncurses_has_key(C.int(ch)) == 1 {
		return true
	}
	return false
}

// InitColor is used to set 'color' to the specified RGB values. Values may
// be between 0 and 1000.
func InitColor(col, r, g, b int16) error {
	if C.init_color(C.short(col), C.short(r), C.short(g),
		C.short(b)) == C.ERR {
		return errors.New("Failed to set new color definition")
	}
	return nil
}

// InitPair sets a colour pair designated by 'pair' to fg and bg colors
func InitPair(pair, fg, bg int16) error {
	if pair <= 0 || C.int(pair) > C.int(C.COLOR_PAIRS-1) {
		return errors.New("Color pair out of range")
	}
	if C.init_pair(C.short(pair), C.short(fg), C.short(bg)) == C.ERR {
		return errors.New("Failed to init color pair")
	}
	return nil
}

// Initialize the ncurses library. You must run this function prior to any
// other goncurses function in order for the library to work
func Init() (stdscr *Window, err error) {
	stdscr = &Window{C.initscr()}
	if unsafe.Pointer(stdscr.win) == nil {
		err = errors.New("An error occurred initializing ncurses")
	}
	return
}

// IsEnd returns true if End() has been called, otherwise false
func IsEnd() bool {
	return bool(C.isendwin())
}

// IsTermResized returns true if ResizeTerm would modify any current Windows
// if called with the given parameters
func IsTermResized(nlines, ncols int) bool {
	return bool(C.is_term_resized(C.int(nlines), C.int(ncols)))
}

// Returns a string representing the value of input returned by Getch
func KeyString(k Key) string {
	key, ok := keyList[k]
	if !ok {
		key = fmt.Sprintf("%c", int(k))
	}
	return key
}

// PairContent returns the current foreground and background colours
// associated with the given pair
func PairContent(pair int16) (fg int16, bg int16, err error) {
	var f, b C.short
	if C.pair_content(C.short(pair), &f, &b) == C.ERR {
		return -1, -1, errors.New("Invalid color pair")
	}
	return int16(f), int16(b), nil
}

// Nap (sleep; halt execution) for 'ms' milliseconds
func Nap(ms int) {
	C.napms(C.int(ms))
}

// NewLines turns newline translation on/off.
func NewLines(on bool) {
	if on {
		C.nl()
		return
	}
	C.nonl()
}

// Raw turns on input buffering; user signals are disabled and the key strokes
// are passed directly to input. Set to false if you wish to turn this mode
// off
func Raw(on bool) {
	if on {
		C.raw()
		return
	}
	C.noraw()
}

// ResizeTerm will attempt to resize the terminal. This only has an effect if
// the terminal is in an XWindows (GUI) environment.
func ResizeTerm(nlines, ncols int) error {
	if C.resizeterm(C.int(nlines), C.int(ncols)) == C.ERR {
		return errors.New("Failed to resize terminal")
	}
	return nil
}

// Enables colors to be displayed. Will return an error if terminal is not
// capable of displaying colors
func StartColor() error {
	if C.has_colors() == C.bool(false) {
		return errors.New("Terminal does not support colors")
	}
	if C.start_color() == C.ERR {
		return errors.New("Failed to enable color mode")
	}
	return nil
}

// StdScr returns a Window for the underlying stdscr object which represents
// the physical screen. This is the same Window returned by Init and therefore
// not useful unless using NewTerm and other multi-screen related functions.
func StdScr() *Window {
	return &Window{C.stdscr}
}

// UnGetChar places the character back into the input queue
func UnGetChar(ch Char) {
	C.ncurses_ungetch(C.int(ch))
}

// Update the screen, refreshing all windows
func Update() error {
	if C.doupdate() == C.ERR {
		return errors.New("Failed to update")
	}
	return nil
}

// UseDefaultColors tells the curses library to assign the terminal's default
// foreground and background colors to color number -1. This will allow you to
// call InitPair(x, -1, -1) to set both the foreground and backgroun colours
// of pair x to the terminal's default. This function can fail if the terminal
// does not support certain ncurses features like orig_pair or initialize_pair.
func UseDefaultColors() error {
	if C.use_default_colors() == C.ERR {
		return errors.New("Failed to assume default colours.")
	}
	return nil
}

// UseEnvironment specifies whether the LINES and COLUMNS environmental
// variables should be used or not
func UseEnvironment(use bool) {
	C.use_env(C.bool(use))
}
<commit_msg>added binding for typeahead(int fd)<commit_after>// goncurses - ncurses library for Go.
// Copyright 2011 Rob Thornton. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goncurses

// #cgo !windows pkg-config: ncurses
// #cgo windows CFLAGS: -DNCURSES_MOUSE_VERSION
// #cgo windows LDFLAGS: -lpdcurses
// #include <curses.h>
// #include "goncurses.h"
import "C"

import (
	"errors"
	"fmt"
	"unsafe"
)

// BaudRate returns the speed of the terminal in bits per second
func BaudRate() int {
	return int(C.baudrate())
}

// Beep requests the terminal make an audible bell or, if not available,
// flashes the screen. Note that screen flashing doesn't work on all
// terminals
func Beep() {
	C.beep()
}

// Turn on/off buffering; raw user signals are passed to the program for
// handling. Overrides raw mode
func CBreak(on bool) {
	if on {
		C.cbreak()
		return
	}
	C.nocbreak()
}

func TypeAhead(fd int) int {

	return int(C.typeahead(C.int(fd)))
}

// Test whether colour values can be changed
func CanChangeColor() bool {
	return bool(C.bool(C.can_change_color()))
}

// Get RGB values for specified colour
func ColorContent(col int16) (int16, int16, int16) {
	var r, g, b C.short
	C.color_content(C.short(col), (*C.short)(&r), (*C.short)(&g),
		(*C.short)(&b))
	return int16(r), int16(g), int16(b)
}

// Return the value of a color pair which can be passed to functions which
// accept attributes like AddChar, AttrOn/Off and Background.
func ColorPair(pair int16) Char {
	return Char(C.ncurses_COLOR_PAIR(C.int(pair)))
}

// CursesVersion returns the version of the ncurses library currently linked to
func CursesVersion() string {
	return C.GoString(C.curses_version())
}

// Set the cursor visibility. Options are: 0 (invisible/hidden), 1 (normal)
// and 2 (extra-visible)
func Cursor(vis byte) error {
	if C.curs_set(C.int(vis)) == C.ERR {
		return errors.New("Failed to enable ")
	}
	return nil
}

// Echo turns on/off the printing of typed characters
func Echo(on bool) {
	if on {
		C.echo()
		return
	}
	C.noecho()
}

// Must be called prior to exiting the program in order to make sure the
// terminal returns to normal operation
func End() {
	C.endwin()
}

// Flash requests the terminal flashes the screen or, if not available,
// make an audible bell. Note that screen flashing doesn't work on all
// terminals
func Flash() {
	C.flash()
}

// FlushInput flushes all input
func FlushInput() error {
	if C.flushinp() == C.ERR {
		return errors.New("Flush input failed")
	}
	return nil
}

// Behaves like cbreak() but also adds a timeout for input. If timeout is
// exceeded after a call to Getch() has been made then GetChar will return
// with an error.
func HalfDelay(delay int) error {
	var cerr C.int
	if delay > 0 {
		cerr = C.halfdelay(C.int(delay))
	}
	if cerr == C.ERR {
		return errors.New("Unable to set delay mode")
	}
	return nil
}

// HasColors returns true if terminal can display colors
func HasColors() bool {
	return bool(C.has_colors())
}

// HasInsertChar return true if the terminal has insert and delete
// character capabilities
func HasInsertChar() bool {
	return bool(C.has_ic())
}

// HasInsertLine returns true if the terminal has insert and delete line
// capabilities. See ncurses documentation for more details
func HasInsertLine() bool {
	return bool(C.has_il())
}

// HasKey returns true if terminal recognized the given character
func HasKey(ch Key) bool {
	if C.ncurses_has_key(C.int(ch)) == 1 {
		return true
	}
	return false
}

// InitColor is used to set 'color' to the specified RGB values. Values may
// be between 0 and 1000.
func InitColor(col, r, g, b int16) error {
	if C.init_color(C.short(col), C.short(r), C.short(g),
		C.short(b)) == C.ERR {
		return errors.New("Failed to set new color definition")
	}
	return nil
}

// InitPair sets a colour pair designated by 'pair' to fg and bg colors
func InitPair(pair, fg, bg int16) error {
	if pair <= 0 || C.int(pair) > C.int(C.COLOR_PAIRS-1) {
		return errors.New("Color pair out of range")
	}
	if C.init_pair(C.short(pair), C.short(fg), C.short(bg)) == C.ERR {
		return errors.New("Failed to init color pair")
	}
	return nil
}

// Initialize the ncurses library. You must run this function prior to any
// other goncurses function in order for the library to work
func Init() (stdscr *Window, err error) {
	stdscr = &Window{C.initscr()}
	if unsafe.Pointer(stdscr.win) == nil {
		err = errors.New("An error occurred initializing ncurses")
	}
	return
}

// IsEnd returns true if End() has been called, otherwise false
func IsEnd() bool {
	return bool(C.isendwin())
}

// IsTermResized returns true if ResizeTerm would modify any current Windows
// if called with the given parameters
func IsTermResized(nlines, ncols int) bool {
	return bool(C.is_term_resized(C.int(nlines), C.int(ncols)))
}

// Returns a string representing the value of input returned by Getch
func KeyString(k Key) string {
	key, ok := keyList[k]
	if !ok {
		key = fmt.Sprintf("%c", int(k))
	}
	return key
}

// PairContent returns the current foreground and background colours
// associated with the given pair
func PairContent(pair int16) (fg int16, bg int16, err error) {
	var f, b C.short
	if C.pair_content(C.short(pair), &f, &b) == C.ERR {
		return -1, -1, errors.New("Invalid color pair")
	}
	return int16(f), int16(b), nil
}

// Nap (sleep; halt execution) for 'ms' milliseconds
func Nap(ms int) {
	C.napms(C.int(ms))
}

// NewLines turns newline translation on/off.
func NewLines(on bool) {
	if on {
		C.nl()
		return
	}
	C.nonl()
}

// Raw turns on input buffering; user signals are disabled and the key strokes
// are passed directly to input. Set to false if you wish to turn this mode
// off
func Raw(on bool) {
	if on {
		C.raw()
		return
	}
	C.noraw()
}

// ResizeTerm will attempt to resize the terminal. This only has an effect if
// the terminal is in an XWindows (GUI) environment.
func ResizeTerm(nlines, ncols int) error {
	if C.resizeterm(C.int(nlines), C.int(ncols)) == C.ERR {
		return errors.New("Failed to resize terminal")
	}
	return nil
}

// Enables colors to be displayed. Will return an error if terminal is not
// capable of displaying colors
func StartColor() error {
	if C.has_colors() == C.bool(false) {
		return errors.New("Terminal does not support colors")
	}
	if C.start_color() == C.ERR {
		return errors.New("Failed to enable color mode")
	}
	return nil
}

// StdScr returns a Window for the underlying stdscr object which represents
// the physical screen. This is the same Window returned by Init and therefore
// not useful unless using NewTerm and other multi-screen related functions.
func StdScr() *Window {
	return &Window{C.stdscr}
}

// UnGetChar places the character back into the input queue
func UnGetChar(ch Char) {
	C.ncurses_ungetch(C.int(ch))
}

// Update the screen, refreshing all windows
func Update() error {
	if C.doupdate() == C.ERR {
		return errors.New("Failed to update")
	}
	return nil
}

// UseDefaultColors tells the curses library to assign the terminal's default
// foreground and background colors to color number -1. This will allow you to
// call InitPair(x, -1, -1) to set both the foreground and backgroun colours
// of pair x to the terminal's default. This function can fail if the terminal
// does not support certain ncurses features like orig_pair or initialize_pair.
func UseDefaultColors() error {
	if C.use_default_colors() == C.ERR {
		return errors.New("Failed to assume default colours.")
	}
	return nil
}

// UseEnvironment specifies whether the LINES and COLUMNS environmental
// variables should be used or not
func UseEnvironment(use bool) {
	C.use_env(C.bool(use))
}
<|endoftext|>


<commit_before>package cmd

import (
	"context"
	"io"
)

// Runner encapsulate what is done with messages
type Runner func(context.Context, io.Writer, []byte) error

// Factory create consumers
type Factory interface {
	// CreateConsumers will iterate over config and create all the consumers
	CreateConsumers() ([]Consumer, error)

	// CreateConsumer create a new consumer for a specific name using the config provided.
	CreateConsumer(name string) (Consumer, error)

	// Name return the factory name
	Name() string
}

// Consumer consume messages and pass to workers who will process the messages.
type Consumer interface {
	// TODO: Create the state, we will add some metrics here
	// State returns a copy of the executor's current operation state.
	// State() State

	// Run will get the messages and pass to the runner.
	Run() error

	// Kill will try to stop the internal work. Return an error in case of failure.
	Kill() error

	// Name return the consumer name
	Name() string
}

// Manager is the block responsible for creating all the consumers.
// Keeping track of the current state of consumers and stop/restart consumers when needed.
type Manager struct {
	ops chan func(map[string]Factory, map[string]Consumer)
}

// NewManager will init a new manager and wait for operations.
func NewManager() (*Manager, error) {
	m := &Manager{}
	go m.work()
	return m, nil
}

func (m *Manager) work() {
	factories := make(map[string]Factory)
	consumers := make(map[string]Consumer)
	for op := range m.ops {
		op(factories, consumers)
	}
}

// Start will all the consumers from factories
func (m *Manager) Start(fs []Factory) error {
	var err error
	m.ops <- func(factories map[string]Factory, consumers map[string]Consumer) {
		for _, f := range fs {
			factories[f.Name()] = f
			cs, err := f.CreateConsumers()
			if err != nil {
				return
			}
			for _, c := range cs {
				consumers[c.Name()] = c
			}
		}
	}
	return err
}

// Stop all the consumers
func (m *Manager) Stop() error {
	var err error
	m.ops <- func(factories map[string]Factory, consumers map[string]Consumer) {
		for _, c := range consumers {
			err = c.Kill()
		}
	}
	return err
}
<commit_msg>Added Stop and checkConsumers<commit_after>package worker

import (
	"context"
	"io"
	"time"
)

// Runner encapsulate what is done with messages
type Runner func(context.Context, io.Writer, []byte) error

// Factory create consumers
type Factory interface {
	// CreateConsumers will iterate over config and create all the consumers
	CreateConsumers() ([]Consumer, error)

	// CreateConsumer create a new consumer for a specific name using the config provided.
	CreateConsumer(name string) (Consumer, error)

	// Name return the factory name
	Name() string
}

// Consumer consume messages and pass to workers who will process the messages.
type Consumer interface {
	// TODO: Create the state, we will add some metrics here
	// State returns a copy of the executor's current operation state.
	// State() State

	// Run will get the messages and pass to the runner.
	Run()

	// Kill will try to stop the internal work. Return an error in case of failure.
	Kill() error

	// Alive returns true if the tomb is not in a dying or dead state.
	Alive() bool

	// Name return the consumer name
	Name() string

	// FactoryName is the name of the factory responsible for this consumer.
	FactoryName() string
}

// Manager is the block responsible for creating all the consumers.
// Keeping track of the current state of consumers and stop/restart consumers when needed.
type Manager struct {
	checkAliveness time.Duration
	ops            chan func(map[string]Factory, map[string]Consumer)
}

// NewManager init a new manager and wait for operations.
func NewManager(intervalChecks time.Duration) *Manager {
	m := &Manager{
		checkAliveness: intervalChecks,
	}
	go m.work()
	go m.checkConsumers()
	return m
}

func (m *Manager) work() {
	factories := make(map[string]Factory)
	consumers := make(map[string]Consumer)
	for op := range m.ops {
		op(factories, consumers)
	}
}

// Start all the consumers from factories
func (m *Manager) Start(fs []Factory) error {
	var err error
	m.ops <- func(factories map[string]Factory, consumers map[string]Consumer) {
		for _, f := range fs {
			factories[f.Name()] = f
			cs, err := f.CreateConsumers()
			if err != nil {
				return
			}
			for _, c := range cs {
				consumers[c.Name()] = c
			}
		}
		for _, c := range consumers {
			c.Run()

		}
	}
	return err
}

// Stop all the consumers
func (m *Manager) Stop() error {
	var errors MultiError
	m.ops <- func(factories map[string]Factory, consumers map[string]Consumer) {
		for _, c := range consumers {
			err := c.Kill()
			if err != nil {
				errors = append(errors, err)
			}
		}
	}
	return errors
}

func (m *Manager) checkConsumers() {
	tick := time.Tick(m.checkAliveness)
	for {
		select {
		case <-tick:
			m.ops <- func(factories map[string]Factory, consumers map[string]Consumer) {
				for name, c := range consumers {
					if !c.Alive() {
						c.Kill() //? we realy need to kill a consumer already dead?
						delete(consumers, name)
						f, ok := factories[c.FactoryName()]
						if ok {
							//TODO: add log, for some reason the factory didn't exist anymore
							continue
						}
						c, err := f.CreateConsumer(name)
						if err != nil {
							//TODO: Add log
							continue
						}
						consumers[c.Name()] = c
						c.Run()
					}
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>package gofpdf

// Adapted from http://www.fpdf.org/en/script/script61.php by Wirus and released with the FPDF license.

// SubWrite prints text from the current position in the same way as Write().
// ht is the line height in the unit of measure specified in New(). str
// specifies the text to write. subFontSize is the size of the font in points.
// subOffset is the vertical offset of the text in points; a positive value
// indicates a superscript, a negative value indicates a subscript. link is the
// identifier returned by AddLink() or 0 for no internal link. linkStr is a
// target URL or empty for no external link. A non--zero value for link takes
// precedence over linkStr.
func (f *Fpdf) SubWrite(ht float64, str string, subFontSize, subOffset float64, link int, linkStr string) {
	if f.err != nil {
		return
	}
	// resize font
	subFontSizeOld := f.fontSizePt
	f.SetFontSize(subFontSize)
	// reposition y
	subOffset = (((subFontSize - subFontSizeOld) / f.k) * 0.3) + (subOffset / f.k)
	subX := f.x
	subY := f.y
	f.SetXY(subX, subY-subOffset)
	//Output text
	f.write(ht, str, link, linkStr)
	// restore y position
	subX = f.x
	subY = f.y
	f.SetXY(subX, subY+subOffset)
	// restore font size
	f.SetFontSize(subFontSizeOld)
}
<commit_msg>Reference SubWrite example<commit_after>package gofpdf

// Adapted from http://www.fpdf.org/en/script/script61.php by Wirus and released with the FPDF license.

// SubWrite prints text from the current position in the same way as Write().
// ht is the line height in the unit of measure specified in New(). str
// specifies the text to write. subFontSize is the size of the font in points.
// subOffset is the vertical offset of the text in points; a positive value
// indicates a superscript, a negative value indicates a subscript. link is the
// identifier returned by AddLink() or 0 for no internal link. linkStr is a
// target URL or empty for no external link. A non--zero value for link takes
// precedence over linkStr.
//
// The SubWrite example demonstrates this method.
func (f *Fpdf) SubWrite(ht float64, str string, subFontSize, subOffset float64, link int, linkStr string) {
	if f.err != nil {
		return
	}
	// resize font
	subFontSizeOld := f.fontSizePt
	f.SetFontSize(subFontSize)
	// reposition y
	subOffset = (((subFontSize - subFontSizeOld) / f.k) * 0.3) + (subOffset / f.k)
	subX := f.x
	subY := f.y
	f.SetXY(subX, subY-subOffset)
	//Output text
	f.write(ht, str, link, linkStr)
	// restore y position
	subX = f.x
	subY = f.y
	f.SetXY(subX, subY+subOffset)
	// restore font size
	f.SetFontSize(subFontSizeOld)
}
<|endoftext|>