Integrate NATS with event subsystem

Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
Kenfe-Mickael Laventure 2016-12-12 14:26:51 -08:00
parent 934940a96c
commit aa5ff88bbc
10 changed files with 165 additions and 68 deletions

31
events/nats.go Normal file
View file

@ -0,0 +1,31 @@
package events
import (
"context"
"strings"
"github.com/docker/containerd/log"
nats "github.com/nats-io/go-nats"
)
type natsPoster struct {
nec *nats.EncodedConn
}
func GetNATSPoster(nec *nats.EncodedConn) Poster {
return &natsPoster{nec}
}
func (p *natsPoster) Post(ctx context.Context, e Event) {
subject := strings.Replace(log.GetModulePath(ctx), "/", ".", -1)
topic := getTopic(ctx)
if topic != "" {
subject = strings.Join([]string{subject, topic}, ".")
}
if subject == "" {
log.GetLogger(ctx).WithField("event", e).Warn("unable to post event, subject is empty")
}
p.nec.Publish(subject, e)
}

View file

@ -3,8 +3,8 @@ package events
import (
"context"
"github.com/Sirupsen/logrus"
"github.com/docker/containerd/log"
"github.com/sirupsen/logrus"
)
var (
@ -13,13 +13,17 @@ var (
// Poster posts the event.
type Poster interface {
Post(event Event)
Post(ctx context.Context, event Event)
}
type posterKey struct{}
func WithPoster(ctx context.Context, poster Poster) context.Context {
return context.WithValue(ctx, posterKey{}, poster)
}
func GetPoster(ctx context.Context) Poster {
poster := ctx.Value(ctx)
poster := ctx.Value(posterKey{})
if poster == nil {
logger := log.G(ctx)
tx, _ := getTx(ctx)
@ -27,7 +31,7 @@ func GetPoster(ctx context.Context) Poster {
// likely means we don't have a configured event system. Just return
// the default poster, which merely logs events.
return posterFunc(func(event Event) {
return posterFunc(func(ctx context.Context, event Event) {
fields := logrus.Fields{"event": event}
if topic != "" {
@ -48,8 +52,8 @@ func GetPoster(ctx context.Context) Poster {
return poster.(Poster)
}
type posterFunc func(event Event)
type posterFunc func(ctx context.Context, event Event)
func (fn posterFunc) Post(event Event) {
fn(event)
func (fn posterFunc) Post(ctx context.Context, event Event) {
fn(ctx, event)
}

View file

@ -18,6 +18,7 @@ func nexttxID() int64 {
}
type transaction struct {
ctx context.Context
id int64
parent *transaction // if nil, no parent transaction
finish sync.Once
@ -25,17 +26,18 @@ type transaction struct {
}
// begin creates a sub-transaction.
func (tx *transaction) begin(poster Poster) *transaction {
func (tx *transaction) begin(ctx context.Context, poster Poster) *transaction {
id := nexttxID()
child := &transaction{
ctx: ctx,
id: id,
parent: tx,
start: time.Now(),
}
// post the transaction started event
poster.Post(child.makeTransactionEvent("begin")) // tranactions are really just events
poster.Post(ctx, child.makeTransactionEvent("begin")) // tranactions are really just events
return child
}
@ -44,7 +46,7 @@ func (tx *transaction) begin(poster Poster) *transaction {
func (tx *transaction) commit(poster Poster) {
tx.finish.Do(func() {
tx.end = time.Now()
poster.Post(tx.makeTransactionEvent("commit"))
poster.Post(tx.ctx, tx.makeTransactionEvent("commit"))
})
}
@ -53,7 +55,7 @@ func (tx *transaction) rollback(poster Poster, cause error) {
tx.end = time.Now()
event := tx.makeTransactionEvent("rollback")
event = fmt.Sprintf("%s error=%q", event, cause.Error())
poster.Post(event)
poster.Post(tx.ctx, event)
})
}
@ -84,7 +86,7 @@ func getTx(ctx context.Context) (*transaction, bool) {
func WithTx(pctx context.Context) (ctx context.Context, commit func(), rollback func(err error)) {
poster := G(pctx)
parent, _ := getTx(pctx)
tx := parent.begin(poster)
tx := parent.begin(pctx, poster)
return context.WithValue(pctx, txKey{}, tx), func() {
tx.commit(poster)