110 lines
2.1 KiB
Go
110 lines
2.1 KiB
Go
package txn
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"sort"
|
|
"sync/atomic"
|
|
|
|
"gopkg.in/mgo.v2/bson"
|
|
)
|
|
|
|
var (
|
|
debugEnabled bool
|
|
logger log_Logger
|
|
)
|
|
|
|
type log_Logger interface {
|
|
Output(calldepth int, s string) error
|
|
}
|
|
|
|
// Specify the *log.Logger where logged messages should be sent to.
|
|
func SetLogger(l log_Logger) {
|
|
logger = l
|
|
}
|
|
|
|
// SetDebug enables or disables debugging.
|
|
func SetDebug(debug bool) {
|
|
debugEnabled = debug
|
|
}
|
|
|
|
var ErrChaos = fmt.Errorf("interrupted by chaos")
|
|
|
|
var debugId uint32
|
|
|
|
func debugPrefix() string {
|
|
d := atomic.AddUint32(&debugId, 1) - 1
|
|
s := make([]byte, 0, 10)
|
|
for i := uint(0); i < 8; i++ {
|
|
s = append(s, "abcdefghijklmnop"[(d>>(4*i))&0xf])
|
|
if d>>(4*(i+1)) == 0 {
|
|
break
|
|
}
|
|
}
|
|
s = append(s, ')', ' ')
|
|
return string(s)
|
|
}
|
|
|
|
func logf(format string, args ...interface{}) {
|
|
if logger != nil {
|
|
logger.Output(2, fmt.Sprintf(format, argsForLog(args)...))
|
|
}
|
|
}
|
|
|
|
func debugf(format string, args ...interface{}) {
|
|
if debugEnabled && logger != nil {
|
|
logger.Output(2, fmt.Sprintf(format, argsForLog(args)...))
|
|
}
|
|
}
|
|
|
|
func argsForLog(args []interface{}) []interface{} {
|
|
for i, arg := range args {
|
|
switch v := arg.(type) {
|
|
case bson.ObjectId:
|
|
args[i] = v.Hex()
|
|
case []bson.ObjectId:
|
|
lst := make([]string, len(v))
|
|
for j, id := range v {
|
|
lst[j] = id.Hex()
|
|
}
|
|
args[i] = lst
|
|
case map[docKey][]bson.ObjectId:
|
|
buf := &bytes.Buffer{}
|
|
var dkeys docKeys
|
|
for dkey := range v {
|
|
dkeys = append(dkeys, dkey)
|
|
}
|
|
sort.Sort(dkeys)
|
|
for i, dkey := range dkeys {
|
|
if i > 0 {
|
|
buf.WriteByte(' ')
|
|
}
|
|
buf.WriteString(fmt.Sprintf("%v: {", dkey))
|
|
for j, id := range v[dkey] {
|
|
if j > 0 {
|
|
buf.WriteByte(' ')
|
|
}
|
|
buf.WriteString(id.Hex())
|
|
}
|
|
buf.WriteByte('}')
|
|
}
|
|
args[i] = buf.String()
|
|
case map[docKey][]int64:
|
|
buf := &bytes.Buffer{}
|
|
var dkeys docKeys
|
|
for dkey := range v {
|
|
dkeys = append(dkeys, dkey)
|
|
}
|
|
sort.Sort(dkeys)
|
|
for i, dkey := range dkeys {
|
|
if i > 0 {
|
|
buf.WriteByte(' ')
|
|
}
|
|
buf.WriteString(fmt.Sprintf("%v: %v", dkey, v[dkey]))
|
|
}
|
|
args[i] = buf.String()
|
|
}
|
|
}
|
|
return args
|
|
}
|