-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #51 from smartcontractkit/ethclient-refactor
Refactor the main timelock loop
- Loading branch information
Showing
15 changed files
with
1,088 additions
and
833 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
golang 1.20 | ||
golangci-lint 1.52.2 | ||
golang 1.22 | ||
golangci-lint 1.57.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package isclosed | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
) | ||
|
||
// All returns a channel that is closed either when each of the channels is read from or the passed | ||
// context is canceled. All is useful for implementing graceful shutdown of a number of Sends or | ||
// other running goroutines that indicate their state via a returned read only channel. The graceful | ||
// shutdown can be circumvented via the context passed to All to ensure shutdowns will not deadlock. | ||
func All(ctx context.Context, done ...<-chan struct{}) <-chan struct{} { | ||
var ( | ||
shutdown = make(chan struct{}) | ||
wg sync.WaitGroup | ||
) | ||
|
||
wg.Add(len(done)) | ||
for _, ch := range done { | ||
go func() { | ||
defer wg.Done() | ||
|
||
select { | ||
case <-ctx.Done(): | ||
case <-ch: | ||
} | ||
}() | ||
} | ||
|
||
go func() { | ||
defer close(shutdown) | ||
|
||
wg.Wait() | ||
}() | ||
|
||
return shutdown | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package isclosed | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
) | ||
|
||
var maxTestTimeout = 3 * time.Second | ||
|
||
func TestAll_DoneAfterAllClose(t *testing.T) { | ||
var ( | ||
ctx = context.Background() | ||
a, b, c = make(chan struct{}), make(chan struct{}), make(chan struct{}) | ||
done = All(ctx, a, b, c) | ||
) | ||
|
||
close(a) | ||
close(b) | ||
close(c) // close all channels | ||
eventually(t, done, maxTestTimeout) | ||
} | ||
|
||
func TestAll_DoneAfterCtxCancel(t *testing.T) { | ||
var ( | ||
ctx, cancel = context.WithCancel(context.Background()) | ||
a, b, c = make(chan struct{}), make(chan struct{}), make(chan struct{}) | ||
done = All(ctx, a, b, c) | ||
) | ||
|
||
close(a) | ||
close(b) | ||
cancel() // c is never closed, but context is canceled | ||
eventually(t, done, maxTestTimeout) | ||
} | ||
|
||
func TestAll_DoneAfterCtxCancelWithNilChannels(t *testing.T) { | ||
var ( | ||
ctx, cancel = context.WithCancel(context.Background()) | ||
done = All(ctx, nil, nil, nil) | ||
) | ||
|
||
cancel() | ||
eventually(t, done, maxTestTimeout) | ||
} | ||
|
||
// TestAll_DoneNonBlocking verifies that if all the input channels close, the All function's returned | ||
// channel should also close regardless of the order of the input channel arguments. | ||
func TestAll_DoneNonBlocking(t *testing.T) { | ||
var ( | ||
ctx = context.Background() | ||
a, b, c = make(chan struct{}), make(chan struct{}), make(chan struct{}) | ||
start = make(chan struct{}) | ||
|
||
// done is only closed once all three input channels are closed as the context is never | ||
// cancelled. | ||
done = All(ctx, c, b, a) | ||
) | ||
|
||
// By default channel a closes with no dependencies. | ||
go func() { | ||
<-start | ||
close(a) | ||
}() | ||
|
||
// Only close channel b after channel a is closed. | ||
go func() { | ||
<-a | ||
close(b) | ||
}() | ||
|
||
// Only close the c channel after both channel b and channel a are closed. | ||
go func() { | ||
<-a | ||
<-b | ||
close(c) | ||
}() | ||
|
||
// Start the closing of the channels once all waiting routines are running. | ||
close(start) | ||
|
||
// Require that the done channel is eventually closed without context cancellation even with | ||
// dependencies on closing between various channels as long as there is no deadlock state. | ||
eventually(t, done, maxTestTimeout) | ||
} | ||
|
||
// eventually blocks until done is closed or d time duration passes. | ||
func eventually(t *testing.T, done <-chan struct{}, d time.Duration) { | ||
t.Helper() | ||
|
||
select { | ||
case <-done: | ||
case <-time.After(d): | ||
t.Fatal("timed out waiting for done to close") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.