Пример #1
0
// threadedSendUpdates sends updates to a specific subscriber as updates become
// available. If the subscriber deadlocks, this thread will deadlock, however
// that will not affect any of the other threads in the transaction pool.
func (tp *TransactionPool) threadedSendUpdates(update chan struct{}, subscriber modules.TransactionPoolSubscriber) {
	// Updates must be sent in order. This is achieved by having all of the
	// updates stored in the transaction pool in a specific order, and then
	// making blocking calls to 'ReceiveTransactionPoolUpates' until all of the
	// updates have been sent.
	i := 0
	for {
		// Determine how many total updates there are to send.
		id := tp.mu.RLock()
		updateCount := len(tp.consensusChanges)
		tp.mu.RUnlock(id)

		// Send each of the updates in order, starting from the first update
		// that has not yet been sent to the subscriber.
		for i < updateCount {
			id := tp.mu.RLock()
			cc := tp.consensusChanges[i]
			unconfirmedTransactions := tp.unconfirmedTransactions[i]
			unconfirmedDiffs := tp.unconfirmedSiacoinDiffs[i]
			tp.mu.RUnlock(id)
			subscriber.ReceiveTransactionPoolUpdate(cc, unconfirmedTransactions, unconfirmedDiffs)
			i++
		}

		// Wait until there has been another update.
		<-update
	}
}
Пример #2
0
// TransactionPoolSubscribe adds a subscriber to the transaction pool.
// Subscribers will receive all consensus set changes as well as transaction
// pool changes, and should not subscribe to both.
func (tp *TransactionPool) TransactionPoolSubscribe(subscriber modules.TransactionPoolSubscriber) {
	lockID := tp.mu.Lock()
	tp.subscribers = append(tp.subscribers, subscriber)
	for i := 0; i <= tp.consensusChangeIndex; i++ {
		cc, err := tp.consensusSet.ConsensusChange(i)
		if err != nil && build.DEBUG {
			panic(err)
		}
		subscriber.ProcessConsensusChange(cc)

		// Release the lock between iterations to smooth out performance a bit
		// - tpool does not need to hold the lock for 15,000 consensus change
		// objects.
		tp.mu.Unlock(lockID)
		runtime.Gosched()
		lockID = tp.mu.Lock()
	}

	// Send the new subscriber the transaction pool set.
	var txns []types.Transaction
	var cc modules.ConsensusChange
	for _, tSet := range tp.transactionSets {
		txns = append(txns, tSet...)
	}
	for _, tSetDiff := range tp.transactionSetDiffs {
		cc = cc.Append(tSetDiff)
	}
	subscriber.ReceiveUpdatedUnconfirmedTransactions(txns, cc)
	tp.mu.Unlock(lockID)
}
Пример #3
0
// TransactionPoolSubscribe adds a subscriber to the transaction pool.
// Subscribers will receive the full transaction set every time there is a
// signficant change to the transaction pool.
func (tp *TransactionPool) TransactionPoolSubscribe(subscriber modules.TransactionPoolSubscriber) {
	tp.mu.Lock()
	defer tp.mu.Unlock()

	// Add the subscriber to the subscriber list.
	tp.subscribers = append(tp.subscribers, subscriber)

	// Send the new subscriber the transaction pool set.
	var txns []types.Transaction
	for _, tSet := range tp.transactionSets {
		txns = append(txns, tSet...)
	}
	var cc modules.ConsensusChange
	for _, tSetDiff := range tp.transactionSetDiffs {
		cc = cc.Append(tSetDiff)
	}
	subscriber.ReceiveUpdatedUnconfirmedTransactions(txns, cc)
}
Пример #4
0
// TransactionPoolSubscribe adds a subscriber to the transaction pool.
// Subscribers will receive all consensus set changes as well as transaction
// pool changes, and should not subscribe to both.
func (tp *TransactionPool) TransactionPoolSubscribe(subscriber modules.TransactionPoolSubscriber) {
	id := tp.mu.Lock()
	tp.subscribers = append(tp.subscribers, subscriber)
	for i := 0; i <= tp.consensusChangeIndex; i++ {
		cc, err := tp.consensusSet.ConsensusChange(i)
		if err != nil && build.DEBUG {
			panic(err)
		}
		subscriber.ProcessConsensusChange(cc)
	}

	// Send the new subscriber the transaction pool set.
	var txns []types.Transaction
	var cc modules.ConsensusChange
	for _, tSet := range tp.transactionSets {
		txns = append(txns, tSet...)
	}
	for _, tSetDiff := range tp.transactionSetDiffs {
		cc = cc.Append(tSetDiff)
	}
	subscriber.ReceiveUpdatedUnconfirmedTransactions(txns, cc)
	tp.mu.Unlock(id)
}