Skip to content

Commit 5b6de51

Browse files
author
Guy Baron
authored
removed non transactional bus mode (#120)
1 parent de202b1 commit 5b6de51

File tree

7 files changed

+79
-300
lines changed

7 files changed

+79
-300
lines changed

gbus/builder/builder.go

+19-29
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
"github.com/wework/grabbit/gbus"
1111
"github.com/wework/grabbit/gbus/saga"
12-
"github.com/wework/grabbit/gbus/saga/stores"
1312
"github.com/wework/grabbit/gbus/serialization"
1413
"github.com/wework/grabbit/gbus/tx/mysql"
1514
)
@@ -37,17 +36,14 @@ func (builder *defaultBuilder) Build(svcName string) gbus.Bus {
3736
gb := &gbus.DefaultBus{
3837
AmqpConnStr: builder.connStr,
3938
PrefetchCount: builder.PrefetchCount,
40-
Outgoing: &gbus.AMQPOutbox{
41-
SvcName: svcName,
42-
},
39+
4340
SvcName: svcName,
4441
PurgeOnStartup: builder.purgeOnStartup,
4542
DelayedSubscriptions: [][]string{},
4643
HandlersLock: &sync.Mutex{},
4744
RPCLock: &sync.Mutex{},
4845
SenderLock: &sync.Mutex{},
4946
ConsumerLock: &sync.Mutex{},
50-
IsTxnl: builder.txnl,
5147
Registrations: make([]*gbus.Registration, 0),
5248
RPCHandlers: make(map[string]gbus.MessageHandler),
5349
Serializer: builder.serializer,
@@ -72,36 +68,30 @@ func (builder *defaultBuilder) Build(svcName string) gbus.Bus {
7268
sagaStore saga.Store
7369
timeoutManager gbus.TimeoutManager
7470
)
75-
if builder.txnl {
76-
gb.IsTxnl = true
77-
switch builder.txnlProvider {
7871

79-
case "mysql":
80-
mysqltx, err := mysql.NewTxProvider(builder.txConnStr)
72+
switch builder.txnlProvider {
73+
74+
case "mysql":
75+
mysqltx, err := mysql.NewTxProvider(builder.txConnStr)
76+
if err != nil {
77+
panic(err)
78+
}
79+
gb.TxProvider = mysqltx
80+
//TODO move purge logic into the NewSagaStore factory method
81+
sagaStore = mysql.NewSagaStore(gb.SvcName, mysqltx)
82+
if builder.purgeOnStartup {
83+
err := sagaStore.Purge()
8184
if err != nil {
8285
panic(err)
8386
}
84-
gb.TxProvider = mysqltx
85-
//TODO move purge logic into the NewSagaStore factory method
86-
sagaStore = mysql.NewSagaStore(gb.SvcName, mysqltx)
87-
if builder.purgeOnStartup {
88-
err := sagaStore.Purge()
89-
if err != nil {
90-
panic(err)
91-
}
92-
}
93-
gb.Outbox = mysql.NewOutbox(gb.SvcName, mysqltx, builder.purgeOnStartup)
94-
timeoutManager = mysql.NewTimeoutManager(gb, gb.TxProvider, gb.Log, svcName, builder.purgeOnStartup)
95-
96-
default:
97-
err := fmt.Errorf("no provider found for passed in value %v", builder.txnlProvider)
98-
panic(err)
9987
}
100-
} else {
101-
sagaStore = stores.NewInMemoryStore()
102-
timeoutManager = &saga.InMemoryTimeoutManager{}
103-
}
88+
gb.Outbox = mysql.NewOutbox(gb.SvcName, mysqltx, builder.purgeOnStartup)
89+
timeoutManager = mysql.NewTimeoutManager(gb, gb.TxProvider, gb.Log, svcName, builder.purgeOnStartup)
10490

91+
default:
92+
err := fmt.Errorf("no provider found for passed in value %v", builder.txnlProvider)
93+
panic(err)
94+
}
10595
if builder.usingPingTimeout {
10696
gb.DbPingTimeout = builder.dbPingTimeout
10797
}

gbus/bus.go

+53-78
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ var _ Bus = &DefaultBus{}
2626
type DefaultBus struct {
2727
*Safety
2828
*Glogged
29-
Outgoing *AMQPOutbox
3029
Outbox TxOutbox
3130
PrefetchCount uint
3231
AmqpConnStr string
@@ -41,6 +40,7 @@ type DefaultBus struct {
4140
amqpErrors chan *amqp.Error
4241
amqpBlocks chan amqp.Blocking
4342
Registrations []*Registration
43+
amqpOutbox *AMQPOutbox
4444

4545
RPCHandlers map[string]MessageHandler
4646
deadletterHandler func(tx *sql.Tx, poision amqp.Delivery) error
@@ -54,16 +54,16 @@ type DefaultBus struct {
5454
started bool
5555
Glue SagaGlue
5656
TxProvider TxProvider
57-
IsTxnl bool
58-
WorkerNum uint
59-
Serializer Serializer
60-
DLX string
61-
DefaultPolicies []MessagePolicy
62-
Confirm bool
63-
healthChan chan error
64-
backpressure bool
65-
DbPingTimeout time.Duration
66-
amqpConnected bool
57+
58+
WorkerNum uint
59+
Serializer Serializer
60+
DLX string
61+
DefaultPolicies []MessagePolicy
62+
Confirm bool
63+
healthChan chan error
64+
backpressure bool
65+
DbPingTimeout time.Duration
66+
amqpConnected bool
6767
}
6868

6969
var (
@@ -203,37 +203,28 @@ func (b *DefaultBus) Start() error {
203203
b.egressConn.NotifyClose(b.amqpErrors)
204204
b.egressConn.NotifyBlocked(b.amqpBlocks)
205205
b.egressChannel.NotifyClose(b.amqpErrors)
206-
//TODO:Figure out what should be done
207206

208-
//init the outbox that sends the messages to the amqp transport and handles publisher confirms
209-
if e := b.Outgoing.init(b.egressChannel, b.Confirm, true); e != nil {
210-
return e
211-
}
212207
/*
213208
start the transactional outbox, make sure calling b.TxOutgoing.Start() is done only after b.Outgoing.init is called
214209
TODO://the design is crap and needs to be refactored
215210
*/
216-
if b.IsTxnl {
217-
218-
var amqpChan *amqp.Channel
219-
if amqpChan, e = b.createAMQPChannel(b.egressConn); e != nil {
220-
b.Log().WithError(e).Error("failed to create amqp channel for transactional outbox")
221-
return e
222-
}
223-
amqpChan.NotifyClose(b.amqpErrors)
224-
amqpOutbox := &AMQPOutbox{
225-
SvcName: b.SvcName,
226-
}
227-
err := amqpOutbox.init(amqpChan, b.Confirm, false)
228-
if err != nil {
229-
b.Log().WithError(err).Error("failed initializing amqpOutbox")
230-
return err
231-
}
232-
if startErr := b.Outbox.Start(amqpOutbox); startErr != nil {
233-
b.Log().WithError(startErr).Error("failed to start transactional outbox")
234-
return startErr
235-
}
236-
211+
var amqpChan *amqp.Channel
212+
if amqpChan, e = b.createAMQPChannel(b.egressConn); e != nil {
213+
b.Log().WithError(e).Error("failed to create amqp channel for transactional outbox")
214+
return e
215+
}
216+
amqpChan.NotifyClose(b.amqpErrors)
217+
b.amqpOutbox = &AMQPOutbox{
218+
SvcName: b.SvcName,
219+
}
220+
err := b.amqpOutbox.init(amqpChan, b.Confirm, false)
221+
if err != nil {
222+
b.Log().WithError(err).Error("failed initializing amqpOutbox")
223+
return err
224+
}
225+
if startErr := b.Outbox.Start(b.amqpOutbox); startErr != nil {
226+
b.Log().WithError(startErr).Error("failed to start transactional outbox")
227+
return startErr
237228
}
238229

239230
//declare queue
@@ -244,10 +235,10 @@ func (b *DefaultBus) Start() error {
244235
b.serviceQueue = q
245236

246237
//bind queue
247-
err := b.bindServiceQueue()
248-
if err != nil {
238+
bindErr := b.bindServiceQueue()
239+
if bindErr != nil {
249240
b.Log().WithError(err).Error("could not bind service to queue")
250-
return err
241+
return bindErr
251242
}
252243

253244
//declare rpc queue
@@ -299,7 +290,6 @@ func (b *DefaultBus) createBusWorkers(workerNum uint) ([]*worker, error) {
299290
q: b.serviceQueue,
300291
rpcq: b.rpcQueue,
301292
svcName: b.SvcName,
302-
isTxnl: b.IsTxnl,
303293
txProvider: b.TxProvider,
304294
rpcLock: b.RPCLock,
305295
rpcHandlers: b.RPCHandlers,
@@ -339,23 +329,19 @@ func (b *DefaultBus) Shutdown() (shutdwonErr error) {
339329
return err
340330
}
341331
}
342-
b.Outgoing.shutdown()
343332

344333
if err := b.Glue.Stop(); err != nil {
345334
return err
346335
}
347336
b.started = false
348-
if b.IsTxnl {
349-
350-
err := b.Outbox.Stop()
351-
352-
if err != nil {
353-
b.Log().WithError(err).Error("could not shutdown outbox")
354-
return err
355-
}
356-
b.TxProvider.Dispose()
337+
err := b.Outbox.Stop()
357338

339+
if err != nil {
340+
b.Log().WithError(err).Error("could not shutdown outbox")
341+
return err
358342
}
343+
b.amqpOutbox.Shutdown()
344+
b.TxProvider.Dispose()
359345

360346
return nil
361347
}
@@ -370,11 +356,8 @@ func (b *DefaultBus) NotifyHealth(health chan error) {
370356

371357
//GetHealth implements Health.GetHealth
372358
func (b *DefaultBus) GetHealth() HealthCard {
373-
var dbConnected bool
374359

375-
if b.IsTxnl {
376-
dbConnected = b.TxProvider.Ping(b.DbPingTimeout)
377-
}
360+
dbConnected := b.TxProvider.Ping(b.DbPingTimeout)
378361

379362
return HealthCard{
380363
DbConnected: dbConnected,
@@ -387,11 +370,11 @@ func (b *DefaultBus) withTx(action func(tx *sql.Tx) error, ambientTx *sql.Tx) er
387370
var shouldCommitTx bool
388371
var activeTx *sql.Tx
389372
//create a new transaction only if there is no active one already passed in
390-
if b.IsTxnl && ambientTx == nil {
373+
if ambientTx == nil {
391374

392375
/*
393376
if the passed in ambient transaction is not nil it means that some caller has created the transaction
394-
and knows when should this transaction bee committed or rolledback.
377+
and knows when should this transaction be committed or rolledback.
395378
In these cases we only invoke the passed in action with the passed in transaction
396379
and do not commit/rollback the transaction.action
397380
If no ambient transaction is passed in then we create a new transaction and commit or rollback after
@@ -414,11 +397,7 @@ func (b *DefaultBus) withTx(action func(tx *sql.Tx) error, ambientTx *sql.Tx) er
414397
}
415398
actionErr := b.SafeWithRetries(retryAction, MaxRetryCount)
416399

417-
/*
418-
if the bus is transactional and there is no ambient transaction then create a new one else use the ambient tranaction.
419-
if the bus is not transactional a nil transaction reference will be passed
420-
*/
421-
if b.IsTxnl && shouldCommitTx {
400+
if shouldCommitTx {
422401
if actionErr != nil {
423402
err := activeTx.Rollback()
424403
if err != nil {
@@ -464,7 +443,12 @@ func (b *DefaultBus) RPC(ctx context.Context, service string, request, reply *Bu
464443
rpcID: rpcID}
465444

466445
b.Serializer.Register(reply.Payload)
467-
err := b.sendImpl(ctx, nil, service, b.rpcQueue.Name, "", "", request, rpc)
446+
447+
sendRPC := func(tx *sql.Tx) error {
448+
return b.sendImpl(ctx, tx, service, b.rpcQueue.Name, "", "", request, rpc)
449+
}
450+
451+
err := b.withTx(sendRPC, nil)
468452
if err != nil {
469453
b.Log().WithError(err).Error("could not send message")
470454
return nil, err
@@ -624,22 +608,13 @@ func (b *DefaultBus) monitorAMQPErrors() {
624608

625609
func (b *DefaultBus) publish(tx *sql.Tx, exchange, routingKey string, msg *amqp.Publishing) error {
626610
publish := func() error {
627-
//send to the transactional outbox if the bus is transactional
628-
//otherwise send directly to amqp
629-
if b.IsTxnl && tx != nil {
630-
b.Log().WithField("message_id", msg.MessageId).Debug("sending message to outbox")
631-
saveErr := b.Outbox.Save(tx, exchange, routingKey, *msg)
632-
if saveErr != nil {
633-
b.Log().WithError(saveErr).Error("failed to save to transactional outbox")
634-
}
635-
return saveErr
636-
}
637-
//do not attempt to contact the borker if backpressure is being applied
638-
if b.backpressure {
639-
return errors.New("can't send message due to backpressure from amqp broker")
611+
612+
b.Log().WithField("message_id", msg.MessageId).Debug("sending message to outbox")
613+
saveErr := b.Outbox.Save(tx, exchange, routingKey, *msg)
614+
if saveErr != nil {
615+
b.Log().WithError(saveErr).Error("failed to save to transactional outbox")
640616
}
641-
_, outgoingErr := b.Outgoing.Post(exchange, routingKey, *msg)
642-
return outgoingErr
617+
return saveErr
643618
}
644619
//currently only one thread can publish at a time
645620
//TODO:add a publishing workers

gbus/outbox.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ func (out *AMQPOutbox) init(amqp *amqp.Channel, confirm, resendOnNack bool) erro
5050
return nil
5151
}
5252

53-
func (out *AMQPOutbox) shutdown() {
54-
out.stop <- true
53+
func (out *AMQPOutbox) Shutdown() {
54+
close(out.stop)
5555

5656
}
5757

gbus/saga/inmemory_timeout.go

-72
This file was deleted.

0 commit comments

Comments
 (0)