Skip to content

Commit

Permalink
Make polling parameters configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-helmich committed Sep 11, 2024
1 parent 41f5b54 commit 0172cfd
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 12 deletions.
14 changes: 10 additions & 4 deletions api/mittwaldv2/client_app_installation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"github.com/google/uuid"
"time"
)

func (c *appClient) RequestAppInstallation(ctx context.Context, projectID string, body AppRequestAppinstallationJSONRequestBody) (string, error) {
Expand All @@ -20,7 +21,7 @@ func (c *appClient) RequestAppInstallation(ctx context.Context, projectID string
}

func (c *appClient) GetAppInstallation(ctx context.Context, appInstallationID string) (*DeMittwaldV1AppAppInstallation, error) {
return poll(ctx, func() (*DeMittwaldV1AppAppInstallation, error) {
return poll(ctx, pollOpts{}, func() (*DeMittwaldV1AppAppInstallation, error) {
response, err := c.client.AppGetAppinstallationWithResponse(ctx, uuid.MustParse(appInstallationID))
if err != nil {
return nil, err
Expand All @@ -46,17 +47,22 @@ func (c *appClient) WaitUntilAppInstallationIsReady(ctx context.Context, appID s
}

if response.JSON200.AppVersion.Current == nil {
return false, nil
return false, errPollShouldRetry
}

if *response.JSON200.AppVersion.Current != response.JSON200.AppVersion.Desired {
return false, nil
return false, errPollShouldRetry
}

return true, nil
}

if ready, err := poll(ctx, runner); err != nil {
o := pollOpts{
InitialDelay: 1 * time.Second,
MaxDelay: 60 * time.Second,
}

if ready, err := poll(ctx, o, runner); err != nil {
return err
} else if !ready {
return errors.New("app installation is not ready")
Expand Down
6 changes: 3 additions & 3 deletions api/mittwaldv2/client_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (c *databaseClient) DeleteMySQLDatabase(ctx context.Context, databaseID str
}

func (c *databaseClient) PollMySQLDatabase(ctx context.Context, databaseID string) (*DeMittwaldV1DatabaseMySqlDatabase, error) {
return poll(ctx, func() (*DeMittwaldV1DatabaseMySqlDatabase, error) {
return poll(ctx, pollOpts{}, func() (*DeMittwaldV1DatabaseMySqlDatabase, error) {
response, err := c.client.DatabaseGetMysqlDatabaseWithResponse(ctx, uuid.MustParse(databaseID))
if err != nil {
return nil, err
Expand Down Expand Up @@ -91,7 +91,7 @@ func (c *databaseClient) SetMySQLUserPassword(ctx context.Context, userID string
}

func (c *databaseClient) PollMySQLUsersForDatabase(ctx context.Context, databaseID string) ([]DeMittwaldV1DatabaseMySqlUser, error) {
return poll(ctx, func() ([]DeMittwaldV1DatabaseMySqlUser, error) {
return poll(ctx, pollOpts{}, func() ([]DeMittwaldV1DatabaseMySqlUser, error) {
response, err := c.client.DatabaseListMysqlUsersWithResponse(ctx, uuid.MustParse(databaseID))
if err != nil {
return nil, err
Expand All @@ -106,7 +106,7 @@ func (c *databaseClient) PollMySQLUsersForDatabase(ctx context.Context, database
}

func (c *databaseClient) PollMySQLUser(ctx context.Context, userID string) (*DeMittwaldV1DatabaseMySqlUser, error) {
return poll(ctx, func() (*DeMittwaldV1DatabaseMySqlUser, error) {
return poll(ctx, pollOpts{}, func() (*DeMittwaldV1DatabaseMySqlUser, error) {
response, err := c.client.DatabaseGetMysqlUserWithResponse(ctx, uuid.MustParse(userID))
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion api/mittwaldv2/client_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (c *projectClient) DeleteProject(ctx context.Context, projectID string) err
}

func (c *projectClient) PollProject(ctx context.Context, projectID string) (*DeMittwaldV1ProjectProject, error) {
return poll(ctx, func() (*DeMittwaldV1ProjectProject, error) {
return poll(ctx, pollOpts{}, func() (*DeMittwaldV1ProjectProject, error) {
response, err := c.client.ProjectGetProjectWithResponse(ctx, uuid.MustParse(projectID))
if err != nil {
return nil, err
Expand Down
34 changes: 30 additions & 4 deletions api/mittwaldv2/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,37 @@ import (
"time"
)

func poll[T any](ctx context.Context, f func() (T, error)) (T, error) {
var errPollShouldRetry = errors.New("poll should retry")

type pollOpts struct {
InitialDelay time.Duration
MaxDelay time.Duration
BackoffFactor float64
}

func (o *pollOpts) applyDefaults() {
if o.InitialDelay == 0 {
o.InitialDelay = 100 * time.Millisecond
}

if o.MaxDelay == 0 {
o.MaxDelay = 10 * time.Second
}

if o.BackoffFactor == 0 {
o.BackoffFactor = 1.1
}
}

func poll[T any](ctx context.Context, o pollOpts, f func() (T, error)) (T, error) {
var null T

res := make(chan T)
err := make(chan error)

d := 100 * time.Millisecond
o.applyDefaults()

d := o.InitialDelay
t := time.NewTicker(d)

defer func() {
Expand All @@ -29,12 +53,14 @@ func poll[T any](ctx context.Context, f func() (T, error)) (T, error) {
return
}

d = time.Duration(math.Max(float64(d)*1.1, float64(10*time.Second)))
d = time.Duration(math.Max(float64(d)*o.BackoffFactor, float64(o.MaxDelay)))
t.Reset(d)

r, e := f()
if e != nil {
if notFound := (ErrNotFound{}); errors.As(e, &notFound) {
if errors.Is(e, errPollShouldRetry) {
continue
} else if notFound := (ErrNotFound{}); errors.As(e, &notFound) {
continue
} else if permissionDenied := (ErrPermissionDenied{}); errors.As(e, &permissionDenied) {
continue
Expand Down

0 comments on commit 0172cfd

Please sign in to comment.