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

package trace

import (
	"context"
)

// DefaultTracer is the tracer used when package-level exported functions are invoked.
var DefaultTracer Tracer = &tracer{}

// Tracer can start spans and access context functions.
type Tracer interface {

	// StartSpan starts a new child span of the current span in the context. If
	// there is no span in the context, creates a new trace and span.
	//
	// Returned context contains the newly created span. You can use it to
	// propagate the returned span in process.
	StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span)

	// StartSpanWithRemoteParent starts a new child span of the span from the given parent.
	//
	// If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is
	// preferred for cases where the parent is propagated via an incoming request.
	//
	// Returned context contains the newly created span. You can use it to
	// propagate the returned span in process.
	StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span)

	// FromContext returns the Span stored in a context, or nil if there isn't one.
	FromContext(ctx context.Context) *Span

	// NewContext returns a new context with the given Span attached.
	NewContext(parent context.Context, s *Span) context.Context
}

// StartSpan starts a new child span of the current span in the context. If
// there is no span in the context, creates a new trace and span.
//
// Returned context contains the newly created span. You can use it to
// propagate the returned span in process.
func StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) {
	return DefaultTracer.StartSpan(ctx, name, o...)
}

// StartSpanWithRemoteParent starts a new child span of the span from the given parent.
//
// If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is
// preferred for cases where the parent is propagated via an incoming request.
//
// Returned context contains the newly created span. You can use it to
// propagate the returned span in process.
func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) {
	return DefaultTracer.StartSpanWithRemoteParent(ctx, name, parent, o...)
}

// FromContext returns the Span stored in a context, or a Span that is not
// recording events if there isn't one.
func FromContext(ctx context.Context) *Span {
	return DefaultTracer.FromContext(ctx)
}

// NewContext returns a new context with the given Span attached.
func NewContext(parent context.Context, s *Span) context.Context {
	return DefaultTracer.NewContext(parent, s)
}

// SpanInterface represents a span of a trace.  It has an associated SpanContext, and
// stores data accumulated while the span is active.
//
// Ideally users should interact with Spans by calling the functions in this
// package that take a Context parameter.
type SpanInterface interface {

	// IsRecordingEvents returns true if events are being recorded for this span.
	// Use this check to avoid computing expensive annotations when they will never
	// be used.
	IsRecordingEvents() bool

	// End ends the span.
	End()

	// SpanContext returns the SpanContext of the span.
	SpanContext() SpanContext

	// SetName sets the name of the span, if it is recording events.
	SetName(name string)

	// SetStatus sets the status of the span, if it is recording events.
	SetStatus(status Status)

	// AddAttributes sets attributes in the span.
	//
	// Existing attributes whose keys appear in the attributes parameter are overwritten.
	AddAttributes(attributes ...Attribute)

	// Annotate adds an annotation with attributes.
	// Attributes can be nil.
	Annotate(attributes []Attribute, str string)

	// Annotatef adds an annotation with attributes.
	Annotatef(attributes []Attribute, format string, a ...interface{})

	// AddMessageSendEvent adds a message send event to the span.
	//
	// messageID is an identifier for the message, which is recommended to be
	// unique in this span and the same between the send event and the receive
	// event (this allows to identify a message between the sender and receiver).
	// For example, this could be a sequence id.
	AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64)

	// AddMessageReceiveEvent adds a message receive event to the span.
	//
	// messageID is an identifier for the message, which is recommended to be
	// unique in this span and the same between the send event and the receive
	// event (this allows to identify a message between the sender and receiver).
	// For example, this could be a sequence id.
	AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64)

	// AddLink adds a link to the span.
	AddLink(l Link)

	// String prints a string representation of a span.
	String() string
}

// NewSpan is a convenience function for creating a *Span out of a *span
func NewSpan(s SpanInterface) *Span {
	return &Span{internal: s}
}

// Span is a struct wrapper around the SpanInt interface, which allows correctly handling
// nil spans, while also allowing the SpanInterface implementation to be swapped out.
type Span struct {
	internal SpanInterface
}

// IsRecordingEvents returns true if events are being recorded for this span.
// Use this check to avoid computing expensive annotations when they will never
// be used.
func (s *Span) IsRecordingEvents() bool {
	if s == nil {
		return false
	}
	return s.internal.IsRecordingEvents()
}

// End ends the span.
func (s *Span) End() {
	if s == nil {
		return
	}
	s.internal.End()
}

// SpanContext returns the SpanContext of the span.
func (s *Span) SpanContext() SpanContext {
	if s == nil {
		return SpanContext{}
	}
	return s.internal.SpanContext()
}

// SetName sets the name of the span, if it is recording events.
func (s *Span) SetName(name string) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.SetName(name)
}

// SetStatus sets the status of the span, if it is recording events.
func (s *Span) SetStatus(status Status) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.SetStatus(status)
}

// AddAttributes sets attributes in the span.
//
// Existing attributes whose keys appear in the attributes parameter are overwritten.
func (s *Span) AddAttributes(attributes ...Attribute) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.AddAttributes(attributes...)
}

// Annotate adds an annotation with attributes.
// Attributes can be nil.
func (s *Span) Annotate(attributes []Attribute, str string) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.Annotate(attributes, str)
}

// Annotatef adds an annotation with attributes.
func (s *Span) Annotatef(attributes []Attribute, format string, a ...interface{}) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.Annotatef(attributes, format, a...)
}

// AddMessageSendEvent adds a message send event to the span.
//
// messageID is an identifier for the message, which is recommended to be
// unique in this span and the same between the send event and the receive
// event (this allows to identify a message between the sender and receiver).
// For example, this could be a sequence id.
func (s *Span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize)
}

// AddMessageReceiveEvent adds a message receive event to the span.
//
// messageID is an identifier for the message, which is recommended to be
// unique in this span and the same between the send event and the receive
// event (this allows to identify a message between the sender and receiver).
// For example, this could be a sequence id.
func (s *Span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize)
}

// AddLink adds a link to the span.
func (s *Span) AddLink(l Link) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.AddLink(l)
}

// String prints a string representation of a span.
func (s *Span) String() string {
	if s == nil {
		return "<nil>"
	}
	return s.internal.String()
}
<commit_msg>provide accessor to the span implementation (#1240)<commit_after>// Copyright 2020, OpenCensus Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package trace

import (
	"context"
)

// DefaultTracer is the tracer used when package-level exported functions are invoked.
var DefaultTracer Tracer = &tracer{}

// Tracer can start spans and access context functions.
type Tracer interface {

	// StartSpan starts a new child span of the current span in the context. If
	// there is no span in the context, creates a new trace and span.
	//
	// Returned context contains the newly created span. You can use it to
	// propagate the returned span in process.
	StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span)

	// StartSpanWithRemoteParent starts a new child span of the span from the given parent.
	//
	// If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is
	// preferred for cases where the parent is propagated via an incoming request.
	//
	// Returned context contains the newly created span. You can use it to
	// propagate the returned span in process.
	StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span)

	// FromContext returns the Span stored in a context, or nil if there isn't one.
	FromContext(ctx context.Context) *Span

	// NewContext returns a new context with the given Span attached.
	NewContext(parent context.Context, s *Span) context.Context
}

// StartSpan starts a new child span of the current span in the context. If
// there is no span in the context, creates a new trace and span.
//
// Returned context contains the newly created span. You can use it to
// propagate the returned span in process.
func StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) {
	return DefaultTracer.StartSpan(ctx, name, o...)
}

// StartSpanWithRemoteParent starts a new child span of the span from the given parent.
//
// If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is
// preferred for cases where the parent is propagated via an incoming request.
//
// Returned context contains the newly created span. You can use it to
// propagate the returned span in process.
func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) {
	return DefaultTracer.StartSpanWithRemoteParent(ctx, name, parent, o...)
}

// FromContext returns the Span stored in a context, or a Span that is not
// recording events if there isn't one.
func FromContext(ctx context.Context) *Span {
	return DefaultTracer.FromContext(ctx)
}

// NewContext returns a new context with the given Span attached.
func NewContext(parent context.Context, s *Span) context.Context {
	return DefaultTracer.NewContext(parent, s)
}

// SpanInterface represents a span of a trace.  It has an associated SpanContext, and
// stores data accumulated while the span is active.
//
// Ideally users should interact with Spans by calling the functions in this
// package that take a Context parameter.
type SpanInterface interface {

	// IsRecordingEvents returns true if events are being recorded for this span.
	// Use this check to avoid computing expensive annotations when they will never
	// be used.
	IsRecordingEvents() bool

	// End ends the span.
	End()

	// SpanContext returns the SpanContext of the span.
	SpanContext() SpanContext

	// SetName sets the name of the span, if it is recording events.
	SetName(name string)

	// SetStatus sets the status of the span, if it is recording events.
	SetStatus(status Status)

	// AddAttributes sets attributes in the span.
	//
	// Existing attributes whose keys appear in the attributes parameter are overwritten.
	AddAttributes(attributes ...Attribute)

	// Annotate adds an annotation with attributes.
	// Attributes can be nil.
	Annotate(attributes []Attribute, str string)

	// Annotatef adds an annotation with attributes.
	Annotatef(attributes []Attribute, format string, a ...interface{})

	// AddMessageSendEvent adds a message send event to the span.
	//
	// messageID is an identifier for the message, which is recommended to be
	// unique in this span and the same between the send event and the receive
	// event (this allows to identify a message between the sender and receiver).
	// For example, this could be a sequence id.
	AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64)

	// AddMessageReceiveEvent adds a message receive event to the span.
	//
	// messageID is an identifier for the message, which is recommended to be
	// unique in this span and the same between the send event and the receive
	// event (this allows to identify a message between the sender and receiver).
	// For example, this could be a sequence id.
	AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64)

	// AddLink adds a link to the span.
	AddLink(l Link)

	// String prints a string representation of a span.
	String() string
}

// NewSpan is a convenience function for creating a *Span out of a *span
func NewSpan(s SpanInterface) *Span {
	return &Span{internal: s}
}

// Span is a struct wrapper around the SpanInt interface, which allows correctly handling
// nil spans, while also allowing the SpanInterface implementation to be swapped out.
type Span struct {
	internal SpanInterface
}

// Internal returns the underlying implementation of the Span
func (s *Span) Internal() SpanInterface {
	return s.internal
}

// IsRecordingEvents returns true if events are being recorded for this span.
// Use this check to avoid computing expensive annotations when they will never
// be used.
func (s *Span) IsRecordingEvents() bool {
	if s == nil {
		return false
	}
	return s.internal.IsRecordingEvents()
}

// End ends the span.
func (s *Span) End() {
	if s == nil {
		return
	}
	s.internal.End()
}

// SpanContext returns the SpanContext of the span.
func (s *Span) SpanContext() SpanContext {
	if s == nil {
		return SpanContext{}
	}
	return s.internal.SpanContext()
}

// SetName sets the name of the span, if it is recording events.
func (s *Span) SetName(name string) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.SetName(name)
}

// SetStatus sets the status of the span, if it is recording events.
func (s *Span) SetStatus(status Status) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.SetStatus(status)
}

// AddAttributes sets attributes in the span.
//
// Existing attributes whose keys appear in the attributes parameter are overwritten.
func (s *Span) AddAttributes(attributes ...Attribute) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.AddAttributes(attributes...)
}

// Annotate adds an annotation with attributes.
// Attributes can be nil.
func (s *Span) Annotate(attributes []Attribute, str string) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.Annotate(attributes, str)
}

// Annotatef adds an annotation with attributes.
func (s *Span) Annotatef(attributes []Attribute, format string, a ...interface{}) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.Annotatef(attributes, format, a...)
}

// AddMessageSendEvent adds a message send event to the span.
//
// messageID is an identifier for the message, which is recommended to be
// unique in this span and the same between the send event and the receive
// event (this allows to identify a message between the sender and receiver).
// For example, this could be a sequence id.
func (s *Span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize)
}

// AddMessageReceiveEvent adds a message receive event to the span.
//
// messageID is an identifier for the message, which is recommended to be
// unique in this span and the same between the send event and the receive
// event (this allows to identify a message between the sender and receiver).
// For example, this could be a sequence id.
func (s *Span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize)
}

// AddLink adds a link to the span.
func (s *Span) AddLink(l Link) {
	if !s.IsRecordingEvents() {
		return
	}
	s.internal.AddLink(l)
}

// String prints a string representation of a span.
func (s *Span) String() string {
	if s == nil {
		return "<nil>"
	}
	return s.internal.String()
}
<|endoftext|>


<commit_before>package tracetcp

import (
	"fmt"
	"syscall"
	"time"
)

type SocketState int

const (
	SocketConnected SocketState = iota
	SocketTimedOut
	SocketPortClosed
	SocketError
)

func (s SocketState) String() string {
	switch s {
	case SocketConnected:
		return "SocketConnected"
	case SocketTimedOut:
		return "SocketTimedOut"
	case SocketPortClosed:
		return "SocketPortClosed"
	case SocketError:
		return "SocketError"
	}
	return "SocketInvlaidState"
}

func waitWithTimeout(socket int, timeout time.Duration) (state SocketState, err error) {
	wfdset := &syscall.FdSet{}

	FD_ZERO(wfdset)
	FD_SET(wfdset, socket)

	timeval := syscall.NsecToTimeval(int64(timeout))

	n, err := syscall.Select(socket+1, nil, wfdset, nil, &timeval)
	if err != nil {
		state = SocketError
		return
	}
	errcode, err := syscall.GetsockoptInt(socket, syscall.SOL_SOCKET, syscall.SO_ERROR)
	if err != nil {
		state = SocketError
		return
	}

	if errcode == int(syscall.ECONNREFUSED) {
		state = SocketPortClosed
		return
	}

	if errcode != 0 {
		state = SocketError
		err = fmt.Errorf("Connect Error: %v", errcode)
		return
	}

	if n == 0 {
		state = SocketTimedOut
	} else {
		state = SocketConnected
	}
	return
}
<commit_msg>ignore EHOSTUNREACH errors<commit_after>package tracetcp

import (
	"fmt"
	"syscall"
	"time"
)

type SocketState int

const (
	SocketConnected SocketState = iota
	SocketTimedOut
	SocketPortClosed
	SocketError
)

func (s SocketState) String() string {
	switch s {
	case SocketConnected:
		return "SocketConnected"
	case SocketTimedOut:
		return "SocketTimedOut"
	case SocketPortClosed:
		return "SocketPortClosed"
	case SocketError:
		return "SocketError"
	}
	return "SocketInvlaidState"
}

func waitWithTimeout(socket int, timeout time.Duration) (state SocketState, err error) {
	wfdset := &syscall.FdSet{}

	FD_ZERO(wfdset)
	FD_SET(wfdset, socket)

	timeval := syscall.NsecToTimeval(int64(timeout))

	n, err := syscall.Select(socket+1, nil, wfdset, nil, &timeval)
	if err != nil {
		state = SocketError
		return
	}
	errcode, err := syscall.GetsockoptInt(socket, syscall.SOL_SOCKET, syscall.SO_ERROR)
	if err != nil {
		state = SocketError
		return
	}

	if errcode == int(syscall.ECONNREFUSED) {
		state = SocketPortClosed
		return
	}

	// ignore host unreachable as thats what we get when ttl expires
	if errcode != 0 && errcode != int(syscall.EHOSTUNREACH) {
		state = SocketError
		err = fmt.Errorf("Connect Error: %v", errcode)
		return
	}

	if n == 0 {
		state = SocketTimedOut
	} else {
		state = SocketConnected
	}
	return
}
<|endoftext|>


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

package tracker

import (
	"database/sql"
	"github.com/hashicorp/go-memdb"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"sync/atomic"
)

const (
	DB_DRIVER       = "sqlite3"
	DB_TABLE_NAME   = "events"
	DB_COLUMN_ID    = "id"
	DB_COLUMN_EVENT = "event"
)

type Storage interface {
	AddEventRow(payload Payload) bool
	DeleteAllEventRows() int64
	DeleteEventRows(ids []int) int64
	GetAllEventRows() []EventRow
	GetEventRowsWithinRange(eventRange int) []EventRow
}

type RawEventRow struct {
	id    int
	event []byte
}

type RawEventRowUint struct {
	id    uint
	event []byte
}

type EventRow struct {
	id    int
	event Payload
}

// --- Memory Storage Implementation

type StorageMemory struct {
	Db    *memdb.MemDB
	Index *uint32
}

func InitStorageMemory() *StorageMemory {
	schema := &memdb.DBSchema{
		Tables: map[string]*memdb.TableSchema{
			DB_TABLE_NAME: {
				Name: DB_TABLE_NAME,
				Indexes: map[string]*memdb.IndexSchema{
					DB_COLUMN_ID: {
						Name:    DB_COLUMN_ID,
						Unique:  true,
						Indexer: &memdb.UintFieldIndex{Field: DB_COLUMN_ID},
					},
					DB_COLUMN_EVENT: {
						Name:    DB_COLUMN_EVENT,
						Indexer: &memdb.StringFieldIndex{Field: DB_COLUMN_EVENT},
					},
				},
			},
		},
	}

	db, err := memdb.NewMemDB(schema)
	checkErr(err)

	return &StorageMemory{Db: db, Index: new(uint32)}
}

// AddEventRow adds a new event to the database
//
// NOTE: As entries are not auto-incremeneting the id is incremented manually which
//       limits inserts to 4,294,967,295 in single session
func (s StorageMemory) AddEventRow(payload Payload) bool {
	txn := s.Db.Txn(true)
	byteBuffer := SerializeMap(payload.Get())
	rer := &RawEventRowUint{event: byteBuffer, id: uint(atomic.AddUint32(s.Index, 1))}
	err := txn.Insert(DB_TABLE_NAME, rer)
	checkErr(err)
	txn.Commit()

	return true
}

// DeleteAllEventRows removes all rows within the memory store
func (s StorageMemory) DeleteAllEventRows() int64 {
	txn := s.Db.Txn(true)
	result, err := txn.DeleteAll(DB_TABLE_NAME, DB_COLUMN_ID)
	checkErr(err)
	txn.Commit()

	return int64(result)
}

// DeleteEventRows removes all rows with matching identifiers
func (s StorageMemory) DeleteEventRows(ids []int) int64 {
	txn := s.Db.Txn(true)
	deleteCount := 0

	for _, id := range ids {
		result, err := txn.DeleteAll(DB_TABLE_NAME, DB_COLUMN_ID, uint(id))
		checkErr(err)
		deleteCount += result
	}

	txn.Commit()

	return int64(deleteCount)
}

// GetAllEventRows returns all rows within the memory store
func (s StorageMemory) GetAllEventRows() []EventRow {
	eventItems := []EventRow{}
	txn := s.Db.Txn(false)
	defer txn.Abort()

	result, err := txn.Get(DB_TABLE_NAME, DB_COLUMN_ID)
	checkErr(err)
	for row := result.Next(); row != nil; row = result.Next() {
		item := row.(*RawEventRowUint)
		eventMap, _ := DeserializeMap(item.event)
		eventItems = append(eventItems, EventRow{int(item.id), Payload{eventMap}})
	}

	return eventItems
}

// GetEventRowsWithinRange returns all available events or a maximal slice
func (s StorageMemory) GetEventRowsWithinRange(eventRange int) []EventRow {
	eventItems := s.GetAllEventRows()
	if len(eventItems) <= eventRange {
		return eventItems
	} else {
		return eventItems[:eventRange]
	}
}

// --- SQLite3 Storage Implementation

type StorageSQLite3 struct {
	DbName string
}

func InitStorageSQLite3(dbName string) *StorageSQLite3 {
	db, err := getDbConn(dbName)
	checkErr(err)
	defer db.Close()

	db.SetMaxOpenConns(1)

	// Enable Write-Ahead-Logging for concurrent read and write
	_, err1 := db.Exec("PRAGMA journal_mode=WAL;")
	checkErr(err1)

	// Create the Events Table
	query :=
		"CREATE TABLE IF NOT EXISTS " + DB_TABLE_NAME + "(" +
			DB_COLUMN_ID + " INTEGER PRIMARY KEY, " +
			DB_COLUMN_EVENT + " BLOB" +
			");"
	_, err2 := db.Exec(query)
	checkErr(err2)

	return &StorageSQLite3{DbName: dbName}
}

func getDbConn(dbName string) (*sql.DB, error) {
	return sql.Open(DB_DRIVER, dbName)
}

// --- ADD

// Add stores an event payload in the database.
func (s StorageSQLite3) AddEventRow(payload Payload) bool {
	db, err := getDbConn(s.DbName)
	checkErr(err)
	defer db.Close()

	// Prepare Add Statement
	query :=
		"INSERT INTO " + DB_TABLE_NAME + "(" +
			DB_COLUMN_EVENT +
			") values(?);"
	addStmt, err1 := db.Prepare(query)
	checkErr(err1)

	byteBuffer := SerializeMap(payload.Get())
	return execAddStatement(addStmt, byteBuffer)
}

// execAddStatement executes the add statement passed to it.
func execAddStatement(stmt *sql.Stmt, byteBuffer []byte) bool {
	defer func() {
		if err := recover(); err != nil {
			log.Println(err)
		}
	}()

	res, err := stmt.Exec(byteBuffer)
	checkErr(err)
	affected, err2 := res.RowsAffected()
	checkErr(err2)

	return affected == 1
}

// --- DELETE

// DeleteAllEventRows removes all events from the database.
func (s StorageSQLite3) DeleteAllEventRows() int64 {
	db, err := getDbConn(s.DbName)
	checkErr(err)
	defer db.Close()

	query := "DELETE FROM " + DB_TABLE_NAME + ";"
	return execDeleteQuery(db, query)
}

// DeleteEventRows removes a range of ids from the database.
func (s StorageSQLite3) DeleteEventRows(ids []int) int64 {
	db, err := getDbConn(s.DbName)
	checkErr(err)
	defer db.Close()

	if len(ids) > 0 {
		query :=
			"DELETE FROM " + DB_TABLE_NAME + " " +
				"WHERE " + DB_COLUMN_ID + " in(" + IntArrayToString(ids, ",") + ");"
		return execDeleteQuery(db, query)
	} else {
		return 0
	}
}

// execDeleteQuery is used to run queries which removed event rows from the database.
func execDeleteQuery(db *sql.DB, query string) int64 {
	defer func() {
		if err := recover(); err != nil {
			log.Println(err)
		}
	}()

	stmt, err := db.Prepare(query)
	checkErr(err)
	defer stmt.Close()
	res, err2 := stmt.Exec()
	checkErr(err2)
	affected, err3 := res.RowsAffected()
	checkErr(err3)

	return affected
}

// --- GET

// GetAllEventRows returns all events in the database.
func (s StorageSQLite3) GetAllEventRows() []EventRow {
	db, err := getDbConn(s.DbName)
	checkErr(err)
	defer db.Close()

	query := "SELECT " + DB_COLUMN_ID + ", " + DB_COLUMN_EVENT + " FROM " + DB_TABLE_NAME + ";"
	return execGetQuery(db, query)
}

// GetEventRowsWithinRange returns a specified range of events from the database.
func (s StorageSQLite3) GetEventRowsWithinRange(eventRange int) []EventRow {
	db, err := getDbConn(s.DbName)
	checkErr(err)
	defer db.Close()

	query :=
		"SELECT " + DB_COLUMN_ID + ", " + DB_COLUMN_EVENT + " FROM " + DB_TABLE_NAME + " " +
			"ORDER BY " + DB_COLUMN_ID + " DESC LIMIT " + IntToString(eventRange) + ";"
	return execGetQuery(db, query)
}

// execGetQuery is used to run queries to fetch event rows from the database.
func execGetQuery(db *sql.DB, query string) []EventRow {
	defer func() {
		if err := recover(); err != nil {
			log.Println(err)
		}
	}()

	eventItems := []EventRow{}
	rows, err := db.Query(query)
	checkErr(err)
	defer rows.Close()

	for rows.Next() {
		item := RawEventRow{}
		rows.Scan(&item.id, &item.event)
		eventMap, _ := DeserializeMap(item.event)
		eventItems = append(eventItems, EventRow{item.id, Payload{eventMap}})
	}

	return eventItems
}

// --- Helpers

// checkErr throws a panic for all non-nil errors passed to it.
func checkErr(err error) {
	if err != nil {
		panic(err.Error())
	}
}
<commit_msg>Simplify SQLite3 getDbConn function (closes #25)<commit_after>//
// Copyright (c) 2016-2018 Snowplow Analytics Ltd. All rights reserved.
//
// This program is licensed to you under the Apache License Version 2.0,
// and you may not use this file except in compliance with the Apache License Version 2.0.
// You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the Apache License Version 2.0 is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
//

package tracker

import (
	"database/sql"
	"github.com/hashicorp/go-memdb"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"sync/atomic"
)

const (
	DB_DRIVER       = "sqlite3"
	DB_TABLE_NAME   = "events"
	DB_COLUMN_ID    = "id"
	DB_COLUMN_EVENT = "event"
)

type Storage interface {
	AddEventRow(payload Payload) bool
	DeleteAllEventRows() int64
	DeleteEventRows(ids []int) int64
	GetAllEventRows() []EventRow
	GetEventRowsWithinRange(eventRange int) []EventRow
}

type RawEventRow struct {
	id    int
	event []byte
}

type RawEventRowUint struct {
	id    uint
	event []byte
}

type EventRow struct {
	id    int
	event Payload
}

// --- Memory Storage Implementation

type StorageMemory struct {
	Db    *memdb.MemDB
	Index *uint32
}

func InitStorageMemory() *StorageMemory {
	schema := &memdb.DBSchema{
		Tables: map[string]*memdb.TableSchema{
			DB_TABLE_NAME: {
				Name: DB_TABLE_NAME,
				Indexes: map[string]*memdb.IndexSchema{
					DB_COLUMN_ID: {
						Name:    DB_COLUMN_ID,
						Unique:  true,
						Indexer: &memdb.UintFieldIndex{Field: DB_COLUMN_ID},
					},
					DB_COLUMN_EVENT: {
						Name:    DB_COLUMN_EVENT,
						Indexer: &memdb.StringFieldIndex{Field: DB_COLUMN_EVENT},
					},
				},
			},
		},
	}

	db, err := memdb.NewMemDB(schema)
	checkErr(err)

	return &StorageMemory{Db: db, Index: new(uint32)}
}

// AddEventRow adds a new event to the database
//
// NOTE: As entries are not auto-incremeneting the id is incremented manually which
//       limits inserts to 4,294,967,295 in single session
func (s StorageMemory) AddEventRow(payload Payload) bool {
	txn := s.Db.Txn(true)
	byteBuffer := SerializeMap(payload.Get())
	rer := &RawEventRowUint{event: byteBuffer, id: uint(atomic.AddUint32(s.Index, 1))}
	err := txn.Insert(DB_TABLE_NAME, rer)
	checkErr(err)
	txn.Commit()

	return true
}

// DeleteAllEventRows removes all rows within the memory store
func (s StorageMemory) DeleteAllEventRows() int64 {
	txn := s.Db.Txn(true)
	result, err := txn.DeleteAll(DB_TABLE_NAME, DB_COLUMN_ID)
	checkErr(err)
	txn.Commit()

	return int64(result)
}

// DeleteEventRows removes all rows with matching identifiers
func (s StorageMemory) DeleteEventRows(ids []int) int64 {
	txn := s.Db.Txn(true)
	deleteCount := 0

	for _, id := range ids {
		result, err := txn.DeleteAll(DB_TABLE_NAME, DB_COLUMN_ID, uint(id))
		checkErr(err)
		deleteCount += result
	}

	txn.Commit()

	return int64(deleteCount)
}

// GetAllEventRows returns all rows within the memory store
func (s StorageMemory) GetAllEventRows() []EventRow {
	eventItems := []EventRow{}
	txn := s.Db.Txn(false)
	defer txn.Abort()

	result, err := txn.Get(DB_TABLE_NAME, DB_COLUMN_ID)
	checkErr(err)
	for row := result.Next(); row != nil; row = result.Next() {
		item := row.(*RawEventRowUint)
		eventMap, _ := DeserializeMap(item.event)
		eventItems = append(eventItems, EventRow{int(item.id), Payload{eventMap}})
	}

	return eventItems
}

// GetEventRowsWithinRange returns all available events or a maximal slice
func (s StorageMemory) GetEventRowsWithinRange(eventRange int) []EventRow {
	eventItems := s.GetAllEventRows()
	if len(eventItems) <= eventRange {
		return eventItems
	} else {
		return eventItems[:eventRange]
	}
}

// --- SQLite3 Storage Implementation

type StorageSQLite3 struct {
	DbName string
}

func InitStorageSQLite3(dbName string) *StorageSQLite3 {
	db := getDbConn(dbName)
	defer db.Close()

	db.SetMaxOpenConns(1)

	// Enable Write-Ahead-Logging for concurrent read and write
	_, err1 := db.Exec("PRAGMA journal_mode=WAL;")
	checkErr(err1)

	// Create the Events Table
	query :=
		"CREATE TABLE IF NOT EXISTS " + DB_TABLE_NAME + "(" +
			DB_COLUMN_ID + " INTEGER PRIMARY KEY, " +
			DB_COLUMN_EVENT + " BLOB" +
			");"
	_, err2 := db.Exec(query)
	checkErr(err2)

	return &StorageSQLite3{DbName: dbName}
}

func getDbConn(dbName string) *sql.DB {
	db, err := sql.Open(DB_DRIVER, dbName)
	checkErr(err)
	return db
}

// --- ADD

// Add stores an event payload in the database.
func (s StorageSQLite3) AddEventRow(payload Payload) bool {
	db := getDbConn(s.DbName)
	defer db.Close()

	// Prepare Add Statement
	query :=
		"INSERT INTO " + DB_TABLE_NAME + "(" +
			DB_COLUMN_EVENT +
			") values(?);"
	addStmt, err1 := db.Prepare(query)
	checkErr(err1)

	byteBuffer := SerializeMap(payload.Get())
	return execAddStatement(addStmt, byteBuffer)
}

// execAddStatement executes the add statement passed to it.
func execAddStatement(stmt *sql.Stmt, byteBuffer []byte) bool {
	defer func() {
		if err := recover(); err != nil {
			log.Println(err)
		}
	}()

	res, err := stmt.Exec(byteBuffer)
	checkErr(err)
	affected, err2 := res.RowsAffected()
	checkErr(err2)

	return affected == 1
}

// --- DELETE

// DeleteAllEventRows removes all events from the database.
func (s StorageSQLite3) DeleteAllEventRows() int64 {
	db := getDbConn(s.DbName)
	defer db.Close()

	query := "DELETE FROM " + DB_TABLE_NAME + ";"
	return execDeleteQuery(db, query)
}

// DeleteEventRows removes a range of ids from the database.
func (s StorageSQLite3) DeleteEventRows(ids []int) int64 {
	db := getDbConn(s.DbName)
	defer db.Close()

	if len(ids) > 0 {
		query :=
			"DELETE FROM " + DB_TABLE_NAME + " " +
				"WHERE " + DB_COLUMN_ID + " in(" + IntArrayToString(ids, ",") + ");"
		return execDeleteQuery(db, query)
	} else {
		return 0
	}
}

// execDeleteQuery is used to run queries which removed event rows from the database.
func execDeleteQuery(db *sql.DB, query string) int64 {
	defer func() {
		if err := recover(); err != nil {
			log.Println(err)
		}
	}()

	stmt, err := db.Prepare(query)
	checkErr(err)
	defer stmt.Close()
	res, err2 := stmt.Exec()
	checkErr(err2)
	affected, err3 := res.RowsAffected()
	checkErr(err3)

	return affected
}

// --- GET

// GetAllEventRows returns all events in the database.
func (s StorageSQLite3) GetAllEventRows() []EventRow {
	db := getDbConn(s.DbName)
	defer db.Close()

	query := "SELECT " + DB_COLUMN_ID + ", " + DB_COLUMN_EVENT + " FROM " + DB_TABLE_NAME + ";"
	return execGetQuery(db, query)
}

// GetEventRowsWithinRange returns a specified range of events from the database.
func (s StorageSQLite3) GetEventRowsWithinRange(eventRange int) []EventRow {
	db := getDbConn(s.DbName)
	defer db.Close()

	query :=
		"SELECT " + DB_COLUMN_ID + ", " + DB_COLUMN_EVENT + " FROM " + DB_TABLE_NAME + " " +
			"ORDER BY " + DB_COLUMN_ID + " DESC LIMIT " + IntToString(eventRange) + ";"
	return execGetQuery(db, query)
}

// execGetQuery is used to run queries to fetch event rows from the database.
func execGetQuery(db *sql.DB, query string) []EventRow {
	defer func() {
		if err := recover(); err != nil {
			log.Println(err)
		}
	}()

	eventItems := []EventRow{}
	rows, err := db.Query(query)
	checkErr(err)
	defer rows.Close()

	for rows.Next() {
		item := RawEventRow{}
		rows.Scan(&item.id, &item.event)
		eventMap, _ := DeserializeMap(item.event)
		eventItems = append(eventItems, EventRow{item.id, Payload{eventMap}})
	}

	return eventItems
}

// --- Helpers

// checkErr throws a panic for all non-nil errors passed to it.
func checkErr(err error) {
	if err != nil {
		panic(err.Error())
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package testing

import (
	"github.com/globocom/tsuru/db"
	"launchpad.net/gocheck"
	"time"
)

type Action struct {
	User   string
	Action string
	Extra  []interface{}
}

type action struct {
	Action
	Date time.Time
}

type isRecordedChecker struct{}

func (isRecordedChecker) Info() *gocheck.CheckerInfo {
	return &gocheck.CheckerInfo{Name: "IsRecorded", Params: []string{"action"}}
}

func (isRecordedChecker) Check(params []interface{}, names []string) (bool, string) {
	var a Action
	switch params[0].(type) {
	case Action:
		a = params[0].(Action)
	case *Action:
		a = *params[0].(*Action)
	default:
		return false, "First parameter must be of type Action or *Action"
	}
	conn, err := db.Conn()
	if err != nil {
		panic("Could not connect to the database: " + err.Error())
	}
	defer conn.Close()
	query := map[string]interface{}{
		"user":   a.User,
		"action": a.Action,
	}
	if len(a.Extra) > 0 {
		query["extra"] = a.Extra
	}
	var got action
	err = conn.UserActions().Find(query).One(&got)
	if err != nil {
		return false, "Action not in the database"
	}
	var empty time.Time
	if got.Date.Sub(empty.In(time.UTC)) == 0 {
		return false, "Action was not recorded using rec.Log"
	}
	return true, ""
}

var IsRecorded gocheck.Checker = isRecordedChecker{}
<commit_msg>testing: improve IsRecorded checker<commit_after>// Copyright 2013 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package testing

import (
	"github.com/globocom/tsuru/db"
	"launchpad.net/gocheck"
	"runtime"
	"time"
)

type Action struct {
	User   string
	Action string
	Extra  []interface{}
}

type action struct {
	Action
	Date time.Time
}

type isRecordedChecker struct{}

func (isRecordedChecker) Info() *gocheck.CheckerInfo {
	return &gocheck.CheckerInfo{Name: "IsRecorded", Params: []string{"action"}}
}

func (isRecordedChecker) Check(params []interface{}, names []string) (bool, string) {
	var a Action
	switch params[0].(type) {
	case Action:
		a = params[0].(Action)
	case *Action:
		a = *params[0].(*Action)
	default:
		return false, "First parameter must be of type Action or *Action"
	}
	conn, err := db.Conn()
	if err != nil {
		panic("Could not connect to the database: " + err.Error())
	}
	defer conn.Close()
	query := map[string]interface{}{
		"user":   a.User,
		"action": a.Action,
	}
	if len(a.Extra) > 0 {
		query["extra"] = a.Extra
	}
	done := make(chan action, 1)
	quit := make(chan int8)
	defer close(quit)
	go func() {
		for {
			select {
			case <-quit:
				runtime.Goexit()
			default:
				var a action
				if err := conn.UserActions().Find(query).One(&a); err == nil {
					done <- a
					return
				}
				runtime.Gosched()
			}
		}
	}()
	var got action
	select {
	case got = <-done:
	case <-time.After(2e9):
		return false, "Action not in the database"
	}
	var empty time.Time
	if got.Date.Sub(empty.In(time.UTC)) == 0 {
		return false, "Action was not recorded using rec.Log"
	}
	return true, ""
}

var IsRecorded gocheck.Checker = isRecordedChecker{}
<|endoftext|>


<commit_before>package clang

// #include <stdlib.h>
// #include "clang-c/Index.h"
import "C"

/**
 * \brief Flags that control the creation of translation units.
 *
 * The enumerators in this enumeration type are meant to be bitwise
 * ORed together to specify which options should be used when
 * constructing the translation unit.
 */
type TranslationUnitFlags uint32

const (
	/**
	 * \brief Used to indicate that no special translation-unit options are
	 * needed.
	 */
	TU_None = C.CXTranslationUnit_None

	/**
	 * \brief Used to indicate that the parser should construct a "detailed"
	 * preprocessing record, including all macro definitions and instantiations.
	 *
	 * Constructing a detailed preprocessing record requires more memory
	 * and time to parse, since the information contained in the record
	 * is usually not retained. However, it can be useful for
	 * applications that require more detailed information about the
	 * behavior of the preprocessor.
	 */
	TU_DetailedPreprocessingRecord = C.CXTranslationUnit_DetailedPreprocessingRecord

	/**
	 * \brief Used to indicate that the translation unit is incomplete.
	 *
	 * When a translation unit is considered "incomplete", semantic
	 * analysis that is typically performed at the end of the
	 * translation unit will be suppressed. For example, this suppresses
	 * the completion of tentative declarations in C and of
	 * instantiation of implicitly-instantiation function templates in
	 * C++. This option is typically used when parsing a header with the
	 * intent of producing a precompiled header.
	 */
	TU_Incomplete = C.CXTranslationUnit_Incomplete

	/**
	 * \brief Used to indicate that the translation unit should be built with an
	 * implicit precompiled header for the preamble.
	 *
	 * An implicit precompiled header is used as an optimization when a
	 * particular translation unit is likely to be reparsed many times
	 * when the sources aren't changing that often. In this case, an
	 * implicit precompiled header will be built containing all of the
	 * initial includes at the top of the main file (what we refer to as
	 * the "preamble" of the file). In subsequent parses, if the
	 * preamble or the files in it have not changed, \c
	 * clang_reparseTranslationUnit() will re-use the implicit
	 * precompiled header to improve parsing performance.
	 */
	TU_PrecompiledPreamble = C.CXTranslationUnit_PrecompiledPreamble

	/**
	 * \brief Used to indicate that the translation unit should cache some
	 * code-completion results with each reparse of the source file.
	 *
	 * Caching of code-completion results is a performance optimization that
	 * introduces some overhead to reparsing but improves the performance of
	 * code-completion operations.
	 */
	TU_CacheCompletionResults = C.CXTranslationUnit_CacheCompletionResults

	/**
	 * \brief DEPRECATED: Enabled chained precompiled preambles in C++.
	 *
	 * Note: this is a *temporary* option that is available only while
	 * we are testing C++ precompiled preamble support. It is deprecated.
	 */
	TU_CXXChainedPCH = C.CXTranslationUnit_CXXChainedPCH
)
<commit_msg>sourcelocation: add CXTranslationUnit_ForSerialization, CXTranslationUnit_SkipFunctionBodies and CXTranslationUnit_IncludeBriefCommentsInCodeCompletion<commit_after>package clang

// #include <stdlib.h>
// #include "clang-c/Index.h"
import "C"

/**
 * \brief Flags that control the creation of translation units.
 *
 * The enumerators in this enumeration type are meant to be bitwise
 * ORed together to specify which options should be used when
 * constructing the translation unit.
 */
type TranslationUnitFlags uint32

const (
	/**
	 * \brief Used to indicate that no special translation-unit options are
	 * needed.
	 */
	TU_None = C.CXTranslationUnit_None

	/**
	 * \brief Used to indicate that the parser should construct a "detailed"
	 * preprocessing record, including all macro definitions and instantiations.
	 *
	 * Constructing a detailed preprocessing record requires more memory
	 * and time to parse, since the information contained in the record
	 * is usually not retained. However, it can be useful for
	 * applications that require more detailed information about the
	 * behavior of the preprocessor.
	 */
	TU_DetailedPreprocessingRecord = C.CXTranslationUnit_DetailedPreprocessingRecord

	/**
	 * \brief Used to indicate that the translation unit is incomplete.
	 *
	 * When a translation unit is considered "incomplete", semantic
	 * analysis that is typically performed at the end of the
	 * translation unit will be suppressed. For example, this suppresses
	 * the completion of tentative declarations in C and of
	 * instantiation of implicitly-instantiation function templates in
	 * C++. This option is typically used when parsing a header with the
	 * intent of producing a precompiled header.
	 */
	TU_Incomplete = C.CXTranslationUnit_Incomplete

	/**
	 * \brief Used to indicate that the translation unit should be built with an
	 * implicit precompiled header for the preamble.
	 *
	 * An implicit precompiled header is used as an optimization when a
	 * particular translation unit is likely to be reparsed many times
	 * when the sources aren't changing that often. In this case, an
	 * implicit precompiled header will be built containing all of the
	 * initial includes at the top of the main file (what we refer to as
	 * the "preamble" of the file). In subsequent parses, if the
	 * preamble or the files in it have not changed, \c
	 * clang_reparseTranslationUnit() will re-use the implicit
	 * precompiled header to improve parsing performance.
	 */
	TU_PrecompiledPreamble = C.CXTranslationUnit_PrecompiledPreamble

	/**
	 * \brief Used to indicate that the translation unit should cache some
	 * code-completion results with each reparse of the source file.
	 *
	 * Caching of code-completion results is a performance optimization that
	 * introduces some overhead to reparsing but improves the performance of
	 * code-completion operations.
	 */
	TU_CacheCompletionResults = C.CXTranslationUnit_CacheCompletionResults

	/**
	 * \brief Used to indicate that the translation unit will be serialized with
	 * \c clang_saveTranslationUnit.
	 *
	 * This option is typically used when parsing a header with the intent of
	 * producing a precompiled header.
	 */
	TU_ForSerialization = C.CXTranslationUnit_ForSerialization

	/**
	 * \brief DEPRECATED: Enabled chained precompiled preambles in C++.
	 *
	 * Note: this is a *temporary* option that is available only while
	 * we are testing C++ precompiled preamble support. It is deprecated.
	 */
	TU_CXXChainedPCH = C.CXTranslationUnit_CXXChainedPCH

	/**
	 * \brief Used to indicate that function/method bodies should be skipped while
	 * parsing.
	 *
	 * This option can be used to search for declarations/definitions while
	 * ignoring the usages.
	 */
	TU_SkipFunctionBodies = C.CXTranslationUnit_SkipFunctionBodies

	/**
	 * \brief Used to indicate that brief documentation comments should be
	 * included into the set of code completions returned from this translation
	 * unit.
	 */
	TU_IncludeBriefCommentsInCodeCompletion = C.CXTranslationUnit_IncludeBriefCommentsInCodeCompletion
)
<|endoftext|>


<commit_before>package ray

import (
	"errors"
	"io"

	"time"

	"v2ray.com/core/common/buf"
)

const (
	bufferSize = 512
)

var ErrReadTimeout = errors.New("Ray: timeout.")

// NewRay creates a new Ray for direct traffic transport.
func NewRay() Ray {
	return &directRay{
		Input:  NewStream(),
		Output: NewStream(),
	}
}

type directRay struct {
	Input  *Stream
	Output *Stream
}

func (v *directRay) OutboundInput() InputStream {
	return v.Input
}

func (v *directRay) OutboundOutput() OutputStream {
	return v.Output
}

func (v *directRay) InboundInput() OutputStream {
	return v.Input
}

func (v *directRay) InboundOutput() InputStream {
	return v.Output
}

func (v *directRay) AddInspector(inspector Inspector) {
	if inspector == nil {
		return
	}
	v.Input.inspector.AddInspector(inspector)
	v.Output.inspector.AddInspector(inspector)
}

type Stream struct {
	buffer    chan *buf.Buffer
	close     chan bool
	err       chan bool
	inspector *InspectorChain
}

func NewStream() *Stream {
	return &Stream{
		buffer:    make(chan *buf.Buffer, bufferSize),
		close:     make(chan bool),
		err:       make(chan bool),
		inspector: &InspectorChain{},
	}
}

func (v *Stream) Read() (*buf.Buffer, error) {
	select {
	case <-v.err:
		return nil, io.ErrClosedPipe
	case b := <-v.buffer:
		return b, nil
	default:
		select {
		case b := <-v.buffer:
			return b, nil
		case <-v.close:
			return nil, io.EOF
		case <-v.err:
			return nil, io.ErrClosedPipe
		}
	}
}

func (v *Stream) ReadTimeout(timeout time.Duration) (*buf.Buffer, error) {
	select {
	case <-v.err:
		return nil, io.ErrClosedPipe
	case b := <-v.buffer:
		return b, nil
	default:
		select {
		case b := <-v.buffer:
			return b, nil
		case <-v.close:
			return nil, io.EOF
		case <-v.err:
			return nil, io.ErrClosedPipe
		case <-time.After(timeout):
			return nil, ErrReadTimeout
		}
	}
}

func (v *Stream) Write(data *buf.Buffer) (err error) {
	if data.IsEmpty() {
		return
	}

	select {
	case <-v.err:
		return io.ErrClosedPipe
	case <-v.close:
		return io.ErrClosedPipe
	default:
		select {
		case <-v.err:
			return io.ErrClosedPipe
		case <-v.close:
			return io.ErrClosedPipe
		case v.buffer <- data:
			v.inspector.Input(data)
			return nil
		}
	}
}

func (v *Stream) Close() {
	defer swallowPanic()

	close(v.close)
}

func (v *Stream) CloseError() {
	defer swallowPanic()

	close(v.err)
	v.Close()

	n := len(v.buffer)
	for i := 0; i < n; i++ {
		select {
		case b := <-v.buffer:
			b.Release()
		default:
			return
		}
	}
}

func (v *Stream) Release() {}

func swallowPanic() {
	recover()
}
<commit_msg>don't do normal close in error case<commit_after>package ray

import (
	"errors"
	"io"

	"time"

	"v2ray.com/core/common/buf"
)

const (
	bufferSize = 512
)

var ErrReadTimeout = errors.New("Ray: timeout.")

// NewRay creates a new Ray for direct traffic transport.
func NewRay() Ray {
	return &directRay{
		Input:  NewStream(),
		Output: NewStream(),
	}
}

type directRay struct {
	Input  *Stream
	Output *Stream
}

func (v *directRay) OutboundInput() InputStream {
	return v.Input
}

func (v *directRay) OutboundOutput() OutputStream {
	return v.Output
}

func (v *directRay) InboundInput() OutputStream {
	return v.Input
}

func (v *directRay) InboundOutput() InputStream {
	return v.Output
}

func (v *directRay) AddInspector(inspector Inspector) {
	if inspector == nil {
		return
	}
	v.Input.inspector.AddInspector(inspector)
	v.Output.inspector.AddInspector(inspector)
}

type Stream struct {
	buffer    chan *buf.Buffer
	close     chan bool
	err       chan bool
	inspector *InspectorChain
}

func NewStream() *Stream {
	return &Stream{
		buffer:    make(chan *buf.Buffer, bufferSize),
		close:     make(chan bool),
		err:       make(chan bool),
		inspector: &InspectorChain{},
	}
}

func (v *Stream) Read() (*buf.Buffer, error) {
	select {
	case <-v.err:
		return nil, io.ErrClosedPipe
	case b := <-v.buffer:
		return b, nil
	default:
		select {
		case b := <-v.buffer:
			return b, nil
		case <-v.close:
			return nil, io.EOF
		case <-v.err:
			return nil, io.ErrClosedPipe
		}
	}
}

func (v *Stream) ReadTimeout(timeout time.Duration) (*buf.Buffer, error) {
	select {
	case <-v.err:
		return nil, io.ErrClosedPipe
	case b := <-v.buffer:
		return b, nil
	default:
		select {
		case b := <-v.buffer:
			return b, nil
		case <-v.close:
			return nil, io.EOF
		case <-v.err:
			return nil, io.ErrClosedPipe
		case <-time.After(timeout):
			return nil, ErrReadTimeout
		}
	}
}

func (v *Stream) Write(data *buf.Buffer) (err error) {
	if data.IsEmpty() {
		return
	}

	select {
	case <-v.err:
		return io.ErrClosedPipe
	case <-v.close:
		return io.ErrClosedPipe
	default:
		select {
		case <-v.err:
			return io.ErrClosedPipe
		case <-v.close:
			return io.ErrClosedPipe
		case v.buffer <- data:
			v.inspector.Input(data)
			return nil
		}
	}
}

func (v *Stream) Close() {
	defer swallowPanic()

	close(v.close)
}

func (v *Stream) CloseError() {
	defer swallowPanic()

	close(v.err)

	n := len(v.buffer)
	for i := 0; i < n; i++ {
		select {
		case b := <-v.buffer:
			b.Release()
		default:
			return
		}
	}
}

func (v *Stream) Release() {}

func swallowPanic() {
	recover()
}
<|endoftext|>


<commit_before>/**
 * @file scoreboard.go
 * @author Mikhail Klementyev jollheef<AT>riseup.net
 * @license GNU GPLv3
 * @date September, 2015
 * @brief web security advisory
 *
 * Contain web ui and several helpers for show advisory results
 */

package scoreboard

import (
	"database/sql"
	"fmt"
	"golang.org/x/net/websocket"
	"time"
)

import "tinfoilhat/steward"

func AdvisoryToHtml(adv steward.Advisory) (html string) {

	html = fmt.Sprintf("
ISA-%d-%04d
",
		adv.Timestamp.Year(), adv.Id)

	html += "

Summary:
"

	html += `<pre style="background-color: #000084; color: #ffffff">` +
		adv.Text + "
"

	html += fmt.Sprintf("
Published: %02d.%02d.%d %02d:%02d
",
		adv.Timestamp.Day(),
		adv.Timestamp.Month(),
		adv.Timestamp.Year(),
		adv.Timestamp.Hour(),
		adv.Timestamp.Minute())

	html += fmt.Sprintf("
Score: %d

", adv.Score)

	return
}

var advisories string

func AdvisoryUpdater(db *sql.DB, update_timeout time.Duration) {

	for {
		var tmp_advisories string

		advs, err := steward.GetAdvisories(db)
		if err != nil {
			time.Sleep(update_timeout)
			continue
		}

		for i := range advs {
			adv := advs[len(advs)-i-1]
			if adv.Reviewed {
				tmp_advisories += AdvisoryToHtml(adv)
			}
		}

		if len(tmp_advisories) == 0 {
			advisories = "Current no advisories"
		} else {
			advisories = tmp_advisories
		}

		time.Sleep(update_timeout)
	}
}

func AdvisoryHandler(ws *websocket.Conn) {
	defer ws.Close()
	fmt.Fprint(ws, advisories)
}
<commit_msg>Fix xss in advisory<commit_after>/**
 * @file scoreboard.go
 * @author Mikhail Klementyev jollheef<AT>riseup.net
 * @license GNU GPLv3
 * @date September, 2015
 * @brief web security advisory
 *
 * Contain web ui and several helpers for show advisory results
 */

package scoreboard

import (
	"database/sql"
	"fmt"
	"golang.org/x/net/websocket"
	"html/template"
	"time"
)

import "tinfoilhat/steward"

func AdvisoryToHtml(adv steward.Advisory) (html string) {

	html = fmt.Sprintf("
ISA-%d-%04d
",
		adv.Timestamp.Year(), adv.Id)

	html += "

Summary:
"

	html += `<pre style="background-color: #000084; color: #ffffff">` +
		template.HTMLEscapeString(adv.Text) + "
"

	html += fmt.Sprintf("
Published: %02d.%02d.%d %02d:%02d
",
		adv.Timestamp.Day(),
		adv.Timestamp.Month(),
		adv.Timestamp.Year(),
		adv.Timestamp.Hour(),
		adv.Timestamp.Minute())

	html += fmt.Sprintf("
Score: %d

", adv.Score)

	return
}

var advisories string

func AdvisoryUpdater(db *sql.DB, update_timeout time.Duration) {

	for {
		var tmp_advisories string

		advs, err := steward.GetAdvisories(db)
		if err != nil {
			time.Sleep(update_timeout)
			continue
		}

		for i := range advs {
			adv := advs[len(advs)-i-1]
			if adv.Reviewed {
				tmp_advisories += AdvisoryToHtml(adv)
			}
		}

		if len(tmp_advisories) == 0 {
			advisories = "Current no advisories"
		} else {
			advisories = tmp_advisories
		}

		time.Sleep(update_timeout)
	}
}

func AdvisoryHandler(ws *websocket.Conn) {
	defer ws.Close()
	fmt.Fprint(ws, advisories)
}
<|endoftext|>


<commit_before>package main

import (
	"archive/zip"
	"errors"
	"os"
	"path"
	"strings"

	"github.com/MJKWoolnough/byteio"
)

func (t Transfer) server(r *byteio.StickyReader, w *byteio.StickyWriter, f *os.File) error {
	stat, err := f.Stat()
	if err != nil {
		return err
	}
	zr, err := zip.NewReader(f, stat.Size())
	if err != nil {
		return err
	}
	name := readString(r)
	jars := make([]*zip.File, 0, 16)
	for _, file := range zr.File {
		if strings.HasSuffix(file.Name, ".jar") {
			jars = append(jars, file)
		}
	}
	s := t.c.NewServer()
	if s == nil {
		return errors.New("error creating server")
	}
	s.Lock()
	s.Name = name
	d := s.Path
	s.Unlock()
	if len(jars) == 0 {
		err = moveFile(f.Name(), path.Join(d, "server.jar"))
	} else {
		if len(jars) > 1 {
			w.WriteUint8(1)
			w.WriteInt16(int16(len(jars)))
			for _, jar := range jars {
				writeString(w, jar.Name)
			}
			p := r.ReadInt16()
			if int(p) >= len(jars) || p < 0 {
				err = errors.New("error selecting server jar")
			} else {
				jars[0] = jars[p]
			}
		}
		if err == nil {
			err = unzip(zr, d)
			if err == nil {
				err = os.Rename(path.Join(d, jars[0].Name), path.Join(d, "server.jar"))
			}
		}
	}
	if err != nil {
		t.c.RemoveServer(s.ID)
		return err
	}
	serverProperties := DefaultServerSettings()
	ps, err := os.OpenFile(path.Join(d, "properties.server"), os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
	if err != nil {
		t.c.RemoveServer(s.ID)
		return err
	}
	defer ps.Close()
	err = serverProperties.WriteTo(ps)
	if err != nil {
		t.c.RemoveServer(s.ID)
		return err
	}
	go t.c.Save()
	return nil
}
<commit_msg>simplified server removal upon error<commit_after>package main

import (
	"archive/zip"
	"errors"
	"os"
	"path"
	"strings"

	"github.com/MJKWoolnough/byteio"
)

func (t Transfer) server(r *byteio.StickyReader, w *byteio.StickyWriter, f *os.File) error {
	stat, err := f.Stat()
	if err != nil {
		return err
	}
	zr, err := zip.NewReader(f, stat.Size())
	if err != nil {
		return err
	}
	name := readString(r)
	jars := make([]*zip.File, 0, 16)
	for _, file := range zr.File {
		if strings.HasSuffix(file.Name, ".jar") {
			jars = append(jars, file)
		}
	}
	s := t.c.NewServer()
	done := false
	defer func() {
		if !done {
			t.c.RemoveServer(s.ID)
		}
	}()
	if s == nil {
		return errors.New("error creating server")
	}
	s.Lock()
	s.Name = name
	d := s.Path
	s.Unlock()
	if len(jars) == 0 {
		err = moveFile(f.Name(), path.Join(d, "server.jar"))
	} else {
		if len(jars) > 1 {
			w.WriteUint8(1)
			w.WriteInt16(int16(len(jars)))
			for _, jar := range jars {
				writeString(w, jar.Name)
			}
			if w.Err != nil {
				return w.Err
			}
			p := r.ReadInt16()
			if r.Err != nil {
				return r.Err
			}
			if int(p) >= len(jars) || p < 0 {
				return errors.New("error selecting server jar")
			} else {
				jars[0] = jars[p]
			}
		}
		if err == nil {
			err = unzip(zr, d)
			if err == nil {
				err = os.Rename(path.Join(d, jars[0].Name), path.Join(d, "server.jar"))
			}
		}
	}
	if err != nil {
		return err
	}
	serverProperties := DefaultServerSettings()
	ps, err := os.OpenFile(path.Join(d, "properties.server"), os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
	if err != nil {
		return err
	}
	defer ps.Close()
	err = serverProperties.WriteTo(ps)
	if err != nil {
		return err
	}
	go t.c.Save()
	done = true
	return nil
}
<|endoftext|>


<commit_before>package test

import (
	"testing"

	"github.com/golang/glog"
	"github.com/kubeflow/pipelines/backend/src/cmd/ml/cmd"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
)

const (
	defaultPageSize = int32(10)
)

func GetRealRootCommand() (*cmd.RootCommand, *cmd.ClientFactory) {
	clientFactory := cmd.NewClientFactory()
	rootCmd := cmd.NewRootCmd(clientFactory)
	rootCmd = cmd.CreateSubCommands(rootCmd, defaultPageSize)
	return rootCmd, clientFactory
}

type CLIIntegrationTest struct {
	suite.Suite
	namespace string
}

// Check the cluster namespace has Kubeflow pipelines installed and ready.
func (c *CLIIntegrationTest) SetupTest() {
	c.namespace = *namespace

	// Wait for the system to be ready.
	err := waitForReady(c.namespace, *initializeTimeout)
	if err != nil {
		glog.Exitf("Cluster namespace '%s' is still not ready after timeout. Error: %s", c.namespace,
			err.Error())
	}
}

func (c *CLIIntegrationTest) TearDownTest() {
	// Nothing to do.
}

func (c *CLIIntegrationTest) TestPipelineListSuccess() {
	t := c.T()
	rootCmd, _ := GetRealRootCommand()
	rootCmd.Command().SetArgs([]string{"pipeline", "list", "--debug"})
	_, err := rootCmd.Command().ExecuteC()
	assert.Nil(t, err)
}

func (c *CLIIntegrationTest) TestPipelineListFailureInvalidArgument() {
	t := c.T()
	rootCmd, _ := GetRealRootCommand()
	rootCmd.Command().SetArgs([]string{"pipeline", "list", "askjdfskldjf", "--debug"})
	_, err := rootCmd.Command().ExecuteC()
	assert.NotNil(t, err)
}

func TestPipelineAPI(t *testing.T) {
	suite.Run(t, new(CLIIntegrationTest))
}
<commit_msg>Changing the namespace to Kubeflow.<commit_after>package test

import (
	"testing"

	"github.com/golang/glog"
	"github.com/kubeflow/pipelines/backend/src/cmd/ml/cmd"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
)

const (
	defaultPageSize = int32(10)
)

func GetRealRootCommand() (*cmd.RootCommand, *cmd.ClientFactory) {
	clientFactory := cmd.NewClientFactory()
	rootCmd := cmd.NewRootCmd(clientFactory)
	rootCmd = cmd.CreateSubCommands(rootCmd, defaultPageSize)
	return rootCmd, clientFactory
}

type CLIIntegrationTest struct {
	suite.Suite
	namespace string
}

// Check the cluster namespace has Kubeflow pipelines installed and ready.
func (c *CLIIntegrationTest) SetupTest() {
	c.namespace = *namespace

	// Wait for the system to be ready.
	err := waitForReady(c.namespace, *initializeTimeout)
	if err != nil {
		glog.Exitf("Cluster namespace '%s' is still not ready after timeout. Error: %s", c.namespace,
			err.Error())
	}
}

func (c *CLIIntegrationTest) TearDownTest() {
	// Nothing to do.
}

func (c *CLIIntegrationTest) TestPipelineListSuccess() {
	t := c.T()
	rootCmd, _ := GetRealRootCommand()
	args := []string{"pipeline", "list"}
	args = addCommonArgs(args, c.namespace)
	rootCmd.Command().SetArgs(args)
	_, err := rootCmd.Command().ExecuteC()
	assert.Nil(t, err)
}

func (c *CLIIntegrationTest) TestPipelineListFailureInvalidArgument() {
	t := c.T()
	rootCmd, _ := GetRealRootCommand()
	args := []string{"pipeline", "list", "askjdfskldjf"}
	args = addCommonArgs(args, c.namespace)
	rootCmd.Command().SetArgs(args)
	_, err := rootCmd.Command().ExecuteC()
	assert.NotNil(t, err)
}

func TestPipelineAPI(t *testing.T) {
	suite.Run(t, new(CLIIntegrationTest))
}

func addCommonArgs(args []string, namespace string) []string {
	args = append(args, "--debug", "--namespace", namespace)
	return args
}
<|endoftext|>


<commit_before>package grim

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

// Copyright 2015 MediaMath <http://www.mediamath.com>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

type grimNotification interface {
	GithubRefStatus() refStatusState
	HipchatNotification(context *grimNotificationContext, config *effectiveConfig) (string, messageColor, error)
}

type standardGrimNotification struct {
	githubState  refStatusState
	hipchatColor messageColor
	getTemplate  func(*effectiveConfig) string
}

//GrimPending is the notification used for pending builds.
var GrimPending = &standardGrimNotification{RSPending, ColorYellow, func(c *effectiveConfig) string { return c.pendingTemplate }}

//GrimError is the notification used for builds that cannot be run correctly.
var GrimError = &standardGrimNotification{RSError, ColorGray, func(c *effectiveConfig) string { return c.errorTemplate }}

//GrimFailure is the notification used when builds fail.
var GrimFailure = &standardGrimNotification{RSFailure, ColorRed, func(c *effectiveConfig) string { return c.failureTemplate }}

//GrimSuccess is the notification used when builds succeed.
var GrimSuccess = &standardGrimNotification{RSSuccess, ColorGreen, func(c *effectiveConfig) string { return c.successTemplate }}

func (s *standardGrimNotification) GithubRefStatus() refStatusState {
	return s.githubState
}

func (s *standardGrimNotification) HipchatNotification(context *grimNotificationContext, config *effectiveConfig) (string, messageColor, error) {
	message, err := context.render(s.getTemplate(config))
	return message, s.hipchatColor, err
}

type grimNotificationContext struct {
	Owner     string
	Repo      string
	EventName string
	Target    string
	UserName  string
	Workspace string
	LogDir    string
}

func (c *grimNotificationContext) render(templateString string) (string, error) {
	template, tempErr := template.New("msg").Parse(templateString)
	if tempErr != nil {
		return "", fmt.Errorf("Error parsing notification template: %v", tempErr)
	}

	var doc bytes.Buffer
	if tempErr = template.Execute(&doc, c); tempErr != nil {
		return "", fmt.Errorf("Error applying template: %v", tempErr)
	}

	return doc.String(), nil
}

func buildContext(hook hookEvent, ws, logDir string) *grimNotificationContext {
	return &grimNotificationContext{hook.Owner, hook.Repo, hook.EventName, hook.Target, hook.UserName, ws, logDir}
}

func notify(config *effectiveConfig, hook hookEvent, ws string, notification grimNotification, logger *log.Logger) error {
	if hook.EventName != "push" && hook.EventName != "pull_request" {
		return nil
	}

	ghErr := setRefStatus(config.gitHubToken, hook.Owner, hook.Repo, hook.StatusRef, notification.GithubRefStatus(), "", "")

	logDir := config.resultRoot + "/" + hook.Owner + "/" + hook.Repo

	context := buildContext(hook, ws, logDir)
	message, color, err := notification.HipchatNotification(context, config)
	sendToLogger(logger, message)

	if config.hipChatToken != "" && config.hipChatRoom != "" {
		if err != nil {
			sendToLogger(logger, fmt.Sprintf("Hipchat: Error while rendering message: %v", err))
			return err
		}

		err = sendMessageToRoom(config.hipChatToken, config.hipChatRoom, config.grimServerID, message, color)
		if err != nil {
			sendToLogger(logger, fmt.Sprintf("Hipchat: Error while sending message to room: %v", message, err))
			return err
		}
	} else {
		sendToLogger(logger, "HipChat: config.hipChatToken and config.hitChatRoom not set")
	}

	return ghErr
}

func sendToLogger(logger *log.Logger, message string) {
	if logger != nil {
		logger.Print(message)
	}
}
<commit_msg>bug fix<commit_after>package grim

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

// Copyright 2015 MediaMath <http://www.mediamath.com>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

type grimNotification interface {
	GithubRefStatus() refStatusState
	HipchatNotification(context *grimNotificationContext, config *effectiveConfig) (string, messageColor, error)
}

type standardGrimNotification struct {
	githubState  refStatusState
	hipchatColor messageColor
	getTemplate  func(*effectiveConfig) string
}

//GrimPending is the notification used for pending builds.
var GrimPending = &standardGrimNotification{RSPending, ColorYellow, func(c *effectiveConfig) string { return c.pendingTemplate }}

//GrimError is the notification used for builds that cannot be run correctly.
var GrimError = &standardGrimNotification{RSError, ColorGray, func(c *effectiveConfig) string { return c.errorTemplate }}

//GrimFailure is the notification used when builds fail.
var GrimFailure = &standardGrimNotification{RSFailure, ColorRed, func(c *effectiveConfig) string { return c.failureTemplate }}

//GrimSuccess is the notification used when builds succeed.
var GrimSuccess = &standardGrimNotification{RSSuccess, ColorGreen, func(c *effectiveConfig) string { return c.successTemplate }}

func (s *standardGrimNotification) GithubRefStatus() refStatusState {
	return s.githubState
}

func (s *standardGrimNotification) HipchatNotification(context *grimNotificationContext, config *effectiveConfig) (string, messageColor, error) {
	message, err := context.render(s.getTemplate(config))
	return message, s.hipchatColor, err
}

type grimNotificationContext struct {
	Owner     string
	Repo      string
	EventName string
	Target    string
	UserName  string
	Workspace string
	LogDir    string
}

func (c *grimNotificationContext) render(templateString string) (string, error) {
	template, tempErr := template.New("msg").Parse(templateString)
	if tempErr != nil {
		return "", fmt.Errorf("Error parsing notification template: %v", tempErr)
	}

	var doc bytes.Buffer
	if tempErr = template.Execute(&doc, c); tempErr != nil {
		return "", fmt.Errorf("Error applying template: %v", tempErr)
	}

	return doc.String(), nil
}

func buildContext(hook hookEvent, ws, logDir string) *grimNotificationContext {
	return &grimNotificationContext{hook.Owner, hook.Repo, hook.EventName, hook.Target, hook.UserName, ws, logDir}
}

func notify(config *effectiveConfig, hook hookEvent, ws string, notification grimNotification, logger *log.Logger) error {
	if hook.EventName != "push" && hook.EventName != "pull_request" {
		return nil
	}

	ghErr := setRefStatus(config.gitHubToken, hook.Owner, hook.Repo, hook.StatusRef, notification.GithubRefStatus(), "", "")

	logDir := config.resultRoot + "/" + hook.Owner + "/" + hook.Repo

	context := buildContext(hook, ws, logDir)
	message, color, err := notification.HipchatNotification(context, config)
	sendToLogger(logger, message)

	if config.hipChatToken != "" && config.hipChatRoom != "" {
		if err != nil {
			sendToLogger(logger, fmt.Sprintf("Hipchat: Error while rendering message: %v", err))
			return err
		}

		err = sendMessageToRoom(config.hipChatToken, config.hipChatRoom, config.grimServerID, message, color)
		if err != nil {
			sendToLogger(logger, fmt.Sprintf("Hipchat: Error while sending message to room: %v", err))
			return err
		}
	} else {
		sendToLogger(logger, "HipChat: config.hipChatToken and config.hitChatRoom not set")
	}

	return ghErr
}

func sendToLogger(logger *log.Logger, message string) {
	if logger != nil {
		logger.Print(message)
	}
}
<|endoftext|>


<commit_before>package gobrake

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
)

var defaultContext map[string]interface{}

func getDefaultContext() map[string]interface{} {
	if defaultContext != nil {
		return defaultContext
	}

	defaultContext = map[string]interface{}{
		"notifier": map[string]interface{}{
			"name":    "gobrake",
			"version": "2.0.4",
			"url":     "https://github.com/airbrake/gobrake",
		},

		"language":     runtime.Version(),
		"os":           runtime.GOOS,
		"architecture": runtime.GOARCH,
	}
	if s, err := os.Hostname(); err == nil {
		defaultContext["hostname"] = s
	}
	if s := os.Getenv("GOPATH"); s != "" {
		list := filepath.SplitList(s)
		// TODO: multiple root dirs?
		defaultContext["rootDirectory"] = list[0]
	}
	return defaultContext
}

type Error struct {
	Type      string       `json:"type"`
	Message   string       `json:"message"`
	Backtrace []StackFrame `json:"backtrace"`
}

type Notice struct {
	Errors  []Error                `json:"errors"`
	Context map[string]interface{} `json:"context"`
	Env     map[string]interface{} `json:"environment"`
	Session map[string]interface{} `json:"session"`
	Params  map[string]interface{} `json:"params"`
}

func (n *Notice) String() string {
	if len(n.Errors) == 0 {
		return "Notice<no errors>"
	}
	e := n.Errors[0]
	return fmt.Sprintf("Notice<%s: %s>", e.Type, e.Message)
}

func NewNotice(e interface{}, req *http.Request, depth int) *Notice {
	notice := &Notice{
		Errors: []Error{{
			Type:      fmt.Sprintf("%T", e),
			Message:   fmt.Sprint(e),
			Backtrace: stack(depth),
		}},
		Context: map[string]interface{}{},
		Env:     map[string]interface{}{},
		Session: map[string]interface{}{},
		Params:  map[string]interface{}{},
	}

	for k, v := range getDefaultContext() {
		notice.Context[k] = v
	}

	if req != nil {
		notice.Context["url"] = req.URL.String()
		if ua := req.Header.Get("User-Agent"); ua != "" {
			notice.Context["userAgent"] = ua
		}

		for k, v := range req.Header {
			if len(v) == 1 {
				notice.Env[k] = v[0]
			} else {
				notice.Env[k] = v
			}
		}

		if err := req.ParseForm(); err == nil {
			for k, v := range req.Form {
				if len(v) == 1 {
					notice.Params[k] = v[0]
				} else {
					notice.Params[k] = v
				}
			}
		}
	}

	return notice
}
<commit_msg>Fix default context race<commit_after>package gobrake

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
	"sync"
)

var defaultContextOnce sync.Once
var defaultContext map[string]interface{}

func getDefaultContext() map[string]interface{} {
	defaultContextOnce.Do(func() {
		defaultContext = map[string]interface{}{
			"notifier": map[string]interface{}{
				"name":    "gobrake",
				"version": "2.0.4",
				"url":     "https://github.com/airbrake/gobrake",
			},

			"language":     runtime.Version(),
			"os":           runtime.GOOS,
			"architecture": runtime.GOARCH,
		}
		if s, err := os.Hostname(); err == nil {
			defaultContext["hostname"] = s
		}
		if s := os.Getenv("GOPATH"); s != "" {
			list := filepath.SplitList(s)
			// TODO: multiple root dirs?
			defaultContext["rootDirectory"] = list[0]
		}
	})
	return defaultContext
}

type Error struct {
	Type      string       `json:"type"`
	Message   string       `json:"message"`
	Backtrace []StackFrame `json:"backtrace"`
}

type Notice struct {
	Errors  []Error                `json:"errors"`
	Context map[string]interface{} `json:"context"`
	Env     map[string]interface{} `json:"environment"`
	Session map[string]interface{} `json:"session"`
	Params  map[string]interface{} `json:"params"`
}

func (n *Notice) String() string {
	if len(n.Errors) == 0 {
		return "Notice<no errors>"
	}
	e := n.Errors[0]
	return fmt.Sprintf("Notice<%s: %s>", e.Type, e.Message)
}

func NewNotice(e interface{}, req *http.Request, depth int) *Notice {
	notice := &Notice{
		Errors: []Error{{
			Type:      fmt.Sprintf("%T", e),
			Message:   fmt.Sprint(e),
			Backtrace: stack(depth),
		}},
		Context: make(map[string]interface{}),
		Env:     make(map[string]interface{}),
		Session: make(map[string]interface{}),
		Params:  make(map[string]interface{}),
	}

	for k, v := range getDefaultContext() {
		notice.Context[k] = v
	}

	if req != nil {
		notice.Context["url"] = req.URL.String()
		if ua := req.Header.Get("User-Agent"); ua != "" {
			notice.Context["userAgent"] = ua
		}

		for k, v := range req.Header {
			if len(v) == 1 {
				notice.Env[k] = v[0]
			} else {
				notice.Env[k] = v
			}
		}

		if err := req.ParseForm(); err == nil {
			for k, v := range req.Form {
				if len(v) == 1 {
					notice.Params[k] = v[0]
				} else {
					notice.Params[k] = v
				}
			}
		}
	}

	return notice
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/daviddengcn/go-colortext"
	"github.com/mattn/go-gntp"
)

// var server = flag.String("s", "127.0.0.1:23053", "GNTP server")
// var action = flag.String("a", "", "Click action")
//	var buf bytes.Buffer
//	cmd := exec.Command(flag.Args()[0], flag.Args()[1:]...)
//	cmd.Stdout = io.MultiWriter(os.Stdout, &buf)
//	cmd.Stderr = io.MultiWriter(os.Stderr, &buf)
//	err := cmd.Run()

func createNotification(server string) *gntp.Client {
	growl := gntp.NewClient()
	// defualt GNTP Server
	growl.Server = server
	growl.AppName = "gomon"
	growl.Register([]gntp.Notification{
		gntp.Notification{
			Event:   "success",
			Enabled: false,
		}, gntp.Notification{
			Event:   "failed",
			Enabled: true,
		},
	})
	return growl
}

func notifyFixed(server string, text, callback string) {
	growl := createNotification(server)
	growl.Notify(&gntp.Message{
		Event:    "success",
		Title:    "Fixed",
		Text:     text,
		Callback: callback,
		Icon:     icon("success"),
	})
}

func notifyFail(server string, text, callback string) {
	growl := createNotification(server)
	growl.Notify(&gntp.Message{
		Event:    "failed",
		Title:    "Failed",
		Text:     text,
		Callback: callback,
		Icon:     icon("failed"),
	})
}

func success(msg string) {
	ct.ChangeColor(ct.Black, true, ct.Green, true)
	fmt.Print(msg)
	ct.ResetColor()
	fmt.Println()
}

func failed(msg string) {
	ct.ChangeColor(ct.Black, true, ct.Red, true)
	fmt.Print(msg)
	ct.ResetColor()
	fmt.Println()
}
<commit_msg>Foreground is better to be dark<commit_after>package main

import (
	"fmt"
	"github.com/daviddengcn/go-colortext"
	"github.com/mattn/go-gntp"
)

// var server = flag.String("s", "127.0.0.1:23053", "GNTP server")
// var action = flag.String("a", "", "Click action")
//	var buf bytes.Buffer
//	cmd := exec.Command(flag.Args()[0], flag.Args()[1:]...)
//	cmd.Stdout = io.MultiWriter(os.Stdout, &buf)
//	cmd.Stderr = io.MultiWriter(os.Stderr, &buf)
//	err := cmd.Run()

func createNotification(server string) *gntp.Client {
	growl := gntp.NewClient()
	// defualt GNTP Server
	growl.Server = server
	growl.AppName = "gomon"
	growl.Register([]gntp.Notification{
		gntp.Notification{
			Event:   "success",
			Enabled: false,
		}, gntp.Notification{
			Event:   "failed",
			Enabled: true,
		},
	})
	return growl
}

func notifyFixed(server string, text, callback string) {
	growl := createNotification(server)
	growl.Notify(&gntp.Message{
		Event:    "success",
		Title:    "Fixed",
		Text:     text,
		Callback: callback,
		Icon:     icon("success"),
	})
}

func notifyFail(server string, text, callback string) {
	growl := createNotification(server)
	growl.Notify(&gntp.Message{
		Event:    "failed",
		Title:    "Failed",
		Text:     text,
		Callback: callback,
		Icon:     icon("failed"),
	})
}

func success(msg string) {
	ct.ChangeColor(ct.Black, false, ct.Green, true)
	fmt.Print(msg)
	ct.ResetColor()
	fmt.Println()
}

func failed(msg string) {
	ct.ChangeColor(ct.Black, false, ct.Red, true)
	fmt.Print(msg)
	ct.ResetColor()
	fmt.Println()
}
<|endoftext|>