Skip to content

Instantly share code, notes, and snippets.

@dimroc
Created December 20, 2018 15:13
Show Gist options
  • Save dimroc/7d82e5cc4cfb951efe505a7a5501f488 to your computer and use it in GitHub Desktop.
Save dimroc/7d82e5cc4cfb951efe505a7a5501f488 to your computer and use it in GitHub Desktop.
diff --git a/services/application.go b/services/application.go
index 39573a5b..3d5c0cad 100644
--- a/services/application.go
+++ b/services/application.go
@@ -43,7 +43,7 @@ type ChainlinkApplication struct {
BulkRunDeleter SleeperTask
pendingConnectionResumer *pendingConnectionResumer
bridgeTypeMutex sync.Mutex
- jobSubscriberID, txManagerID, connectionResumerID string
+ jobSubscriberID, txManagerID, connectionResumerID int
}
// NewApplication initializes a new store if one is not already
diff --git a/services/head_tracker.go b/services/head_tracker.go
index 3a07d1ae..527fe213 100644
--- a/services/head_tracker.go
+++ b/services/head_tracker.go
@@ -7,7 +7,6 @@ import (
"time"
"github.com/asdine/storm"
- uuid "github.com/satori/go.uuid"
"github.com/smartcontractkit/chainlink/logger"
"github.com/smartcontractkit/chainlink/store"
strpkg "github.com/smartcontractkit/chainlink/store"
@@ -21,8 +20,8 @@ import (
// in a thread safe manner. Reconstitutes the last block number from the data
// store on reboot.
type HeadTracker struct {
- trackers map[string]store.HeadTrackable
- sortedTrackerIDs []string // map order is non-deterministic, so keep order.
+ trackables []trackable
+ trackableNonce int
headers chan models.BlockHeader
headSubscription models.EthSubscription
store *strpkg.Store
@@ -49,11 +48,9 @@ func NewHeadTracker(store *strpkg.Store, sleepers ...utils.Sleeper) *HeadTracker
sleeper = utils.NewBackoffSleeper()
}
return &HeadTracker{
- store: store,
- trackers: map[string]strpkg.HeadTrackable{},
- sortedTrackerIDs: []string{},
- sleeper: sleeper,
- connected: abool.New(),
+ store: store,
+ sleeper: sleeper,
+ connected: abool.New(),
}
}
@@ -127,43 +124,35 @@ func (ht *HeadTracker) Head() *models.IndexableBlockNumber {
// Attach registers an object that will have HeadTrackable events fired on occurence,
// such as Connect.
-func (ht *HeadTracker) Attach(t store.HeadTrackable) string {
+func (ht *HeadTracker) Attach(t store.HeadTrackable) int {
ht.trackersMutex.Lock()
defer ht.trackersMutex.Unlock()
- id := uuid.Must(uuid.NewV4()).String()
- ht.trackers[id] = t
- ht.sortedTrackerIDs = append(ht.sortedTrackerIDs, id)
+ ht.trackables = append(ht.trackables, newTrackable(t, ht.trackableNonce))
+ ht.trackableNonce++
if ht.connected.IsSet() {
logger.WarnIf(t.Connect(ht.Head()))
}
- return id
+ return ht.trackableNonce - 1
}
// Detach deregisters an object from having HeadTrackable events fired.
-func (ht *HeadTracker) Detach(id string) {
+func (ht *HeadTracker) Detach(nonce int) {
ht.trackersMutex.Lock()
defer ht.trackersMutex.Unlock()
- t, present := ht.trackers[id]
- if ht.connected.IsSet() && present {
- t.Disconnect()
- }
- if present {
- ht.sortedTrackerIDs = removeTrackerID(id, ht.sortedTrackerIDs, t)
+ idx := indexOf(nonce, ht.trackables)
+ if idx == -1 {
+ return
}
- delete(ht.trackers, id)
-}
-func removeTrackerID(id string, old []string, t store.HeadTrackable) []string {
- idx := indexOf(id, old)
- if idx == -1 {
- logger.Panicf("invariant violated: id %s for %T exists in trackerIDs but not in sortedTrackerIDs in HeadTracker", id, t)
+ if ht.connected.IsSet() {
+ ht.trackables[idx].headTrackable.Disconnect()
}
- return append(old[:idx], old[idx+1:]...)
+ ht.trackables = append(ht.trackables[:idx], ht.trackables[idx+1:]...)
}
-func indexOf(value string, arr []string) int {
- for i, v := range arr {
- if v == value {
+func indexOf(nonce int, arr []trackable) int {
+ for i, t := range arr {
+ if t.nonce == nonce {
return i
}
}
@@ -176,24 +165,24 @@ func (ht *HeadTracker) Connected() bool { return ht.connected.IsSet() }
func (ht *HeadTracker) connect(bn *models.IndexableBlockNumber) {
ht.trackersMutex.RLock()
defer ht.trackersMutex.RUnlock()
- for _, id := range ht.sortedTrackerIDs {
- logger.WarnIf(ht.trackers[id].Connect(bn))
+ for _, t := range ht.trackables {
+ logger.WarnIf(t.headTrackable.Connect(bn))
}
}
func (ht *HeadTracker) disconnect() {
ht.trackersMutex.RLock()
defer ht.trackersMutex.RUnlock()
- for _, id := range ht.sortedTrackerIDs {
- ht.trackers[id].Disconnect()
+ for _, t := range ht.trackables {
+ t.headTrackable.Disconnect()
}
}
func (ht *HeadTracker) onNewHead(head *models.BlockHeader) {
ht.trackersMutex.RLock()
defer ht.trackersMutex.RUnlock()
- for _, id := range ht.sortedTrackerIDs {
- ht.trackers[id].OnNewHead(head)
+ for _, t := range ht.trackables {
+ t.headTrackable.OnNewHead(head)
}
}
@@ -313,3 +302,12 @@ func (ht *HeadTracker) updateHeadFromDb() error {
}
return nil
}
+
+type trackable struct {
+ nonce int
+ headTrackable store.HeadTrackable
+}
+
+func newTrackable(ht store.HeadTrackable, nonce int) trackable {
+ return trackable{headTrackable: ht, nonce: nonce}
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment