-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ac6f3c1
commit b215782
Showing
15 changed files
with
243 additions
and
49 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 |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package thegraph | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/Layr-Labs/eigenda/common" | ||
"github.com/urfave/cli" | ||
) | ||
|
||
const ( | ||
EndpointFlagName = "thegraph.endpoint" | ||
BackoffFlagName = "thegraph.backoff" | ||
MaxRetriesFlagName = "thegraph.max_retries" | ||
) | ||
|
||
type Config struct { | ||
Endpoint string // The Graph endpoint | ||
PullInterval time.Duration // The interval to pull data from The Graph | ||
MaxRetries int // The maximum number of retries to pull data from The Graph | ||
} | ||
|
||
func CLIFlags(envPrefix string) []cli.Flag { | ||
return []cli.Flag{ | ||
cli.StringFlag{ | ||
Name: EndpointFlagName, | ||
Usage: "The Graph endpoint", | ||
Required: true, | ||
EnvVar: common.PrefixEnvVar(envPrefix, "GRAPH_URL"), | ||
}, | ||
cli.DurationFlag{ | ||
Name: BackoffFlagName, | ||
Usage: "Backoff for retries", | ||
Value: 100 * time.Millisecond, | ||
EnvVar: common.PrefixEnvVar(envPrefix, "GRAPH_BACKOFF"), | ||
}, | ||
cli.UintFlag{ | ||
Name: MaxRetriesFlagName, | ||
Usage: "The maximum number of retries", | ||
Value: 5, | ||
EnvVar: common.PrefixEnvVar(envPrefix, "GRAPH_MAX_RETRIES"), | ||
}, | ||
} | ||
} | ||
|
||
func ReadCLIConfig(ctx *cli.Context) Config { | ||
|
||
return Config{ | ||
Endpoint: ctx.String(EndpointFlagName), | ||
PullInterval: ctx.Duration(BackoffFlagName), | ||
MaxRetries: ctx.Int(MaxRetriesFlagName), | ||
} | ||
|
||
} |
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,48 @@ | ||
package thegraph | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"time" | ||
) | ||
|
||
type RetryQuerier struct { | ||
GraphQLQuerier | ||
Backoff time.Duration | ||
MaxRetries int | ||
} | ||
|
||
var _ GraphQLQuerier = (*RetryQuerier)(nil) | ||
|
||
func NewRetryQuerier(q GraphQLQuerier, backoff time.Duration, maxRetries int) *RetryQuerier { | ||
return &RetryQuerier{ | ||
GraphQLQuerier: q, | ||
Backoff: backoff, | ||
MaxRetries: maxRetries, | ||
} | ||
} | ||
|
||
func (q *RetryQuerier) Query(ctx context.Context, query any, variables map[string]any) error { | ||
|
||
retryCount := 0 | ||
backoff := q.Backoff | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return ctx.Err() | ||
default: | ||
if retryCount > q.MaxRetries { | ||
return errors.New("max retries exceeded") | ||
} | ||
retryCount++ | ||
|
||
err := q.GraphQLQuerier.Query(ctx, query, variables) | ||
if err == nil { | ||
return nil | ||
} | ||
|
||
time.Sleep(backoff) | ||
backoff *= 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package thegraph_test | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"testing" | ||
"time" | ||
|
||
"github.com/Layr-Labs/eigenda/core/thegraph" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/mock" | ||
) | ||
|
||
type MockGraphQLQuerier struct { | ||
mock.Mock | ||
} | ||
|
||
func (m *MockGraphQLQuerier) Query(ctx context.Context, query any, variables map[string]any) error { | ||
args := m.Called(ctx, query, variables) | ||
return args.Error(0) | ||
} | ||
|
||
func TestRetryQuerier_Query(t *testing.T) { | ||
ctx := context.Background() | ||
query := "query" | ||
variables := map[string]any{"key": "value"} | ||
|
||
mockQuerier := new(MockGraphQLQuerier) | ||
mockQuerier.On("Query", ctx, query, variables).Return(errors.New("query error")).Once() | ||
mockQuerier.On("Query", ctx, query, variables).Return(errors.New("query error")).Once() | ||
mockQuerier.On("Query", ctx, query, variables).Return(nil) | ||
|
||
retryQuerier := thegraph.NewRetryQuerier(mockQuerier, time.Millisecond, 2) | ||
|
||
err := retryQuerier.Query(ctx, query, variables) | ||
assert.NoError(t, err) | ||
|
||
mockQuerier.AssertExpectations(t) | ||
} | ||
|
||
func TestRetryQuerier_ExceedMaxRetries(t *testing.T) { | ||
ctx := context.Background() | ||
query := "query" | ||
variables := map[string]any{"key": "value"} | ||
|
||
mockQuerier := new(MockGraphQLQuerier) | ||
mockQuerier.On("Query", ctx, query, variables).Return(errors.New("query error")).Once() | ||
mockQuerier.On("Query", ctx, query, variables).Return(errors.New("query error")).Once() | ||
mockQuerier.On("Query", ctx, query, variables).Return(errors.New("query error")).Once() | ||
|
||
retryQuerier := thegraph.NewRetryQuerier(mockQuerier, time.Millisecond, 2) | ||
|
||
err := retryQuerier.Query(ctx, query, variables) | ||
assert.ErrorContains(t, err, "max retries exceeded") | ||
|
||
mockQuerier.AssertExpectations(t) | ||
} | ||
|
||
func TestRetryQuerier_Timeout(t *testing.T) { | ||
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) | ||
defer cancel() | ||
query := "query" | ||
variables := map[string]any{"key": "value"} | ||
|
||
mockQuerier := new(MockGraphQLQuerier) | ||
mockQuerier.On("Query", ctx, query, variables).Return(errors.New("query error")).Once() | ||
mockQuerier.On("Query", ctx, query, variables).Return(errors.New("query error")).Once() | ||
mockQuerier.On("Query", ctx, query, variables).Return(nil) | ||
|
||
retryQuerier := thegraph.NewRetryQuerier(mockQuerier, 100*time.Millisecond, 2) | ||
|
||
err := retryQuerier.Query(ctx, query, variables) | ||
assert.ErrorContains(t, err, "context deadline exceeded") | ||
|
||
} |
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
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
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.