Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove Timeout option from WaitFor* methods #291

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/)

### Removed
- **Breaking**, Managed Database: connection related methods in favor of session
- **Breaking**: remove `Timeout` option from `WaitFor*` methods. Use `context.WithTimeout` to define a timeout for these functions.

## [6.12.0]

Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ fmt.Println(fmt.Sprintf("Server %s with UUID %s created", serverDetails.Title, s
err = svc.WaitForServerState(context.Background(), &request.WaitForServerStateRequest{
UUID: serverDetails.UUID,
DesiredState: upcloud.ServerStateStarted,
Timeout: time.Minute * 5,
})

if err != nil {
Expand Down
3 changes: 0 additions & 3 deletions examples/upcloud-cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"flag"
"fmt"
"os"
"time"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud/client"
Expand Down Expand Up @@ -121,7 +120,6 @@ func createServer(s *service.Service) error {
details, err = s.WaitForServerState(ctx, &request.WaitForServerStateRequest{
UUID: details.UUID,
DesiredState: upcloud.ServerStateStarted,
Timeout: 1 * time.Minute,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to wait for server: %#v", err)
Expand Down Expand Up @@ -160,7 +158,6 @@ func deleteServers(s *service.Service) error {
_, err = s.WaitForServerState(ctx, &request.WaitForServerStateRequest{
UUID: server.UUID,
DesiredState: upcloud.ServerStateStopped,
Timeout: 1 * time.Minute,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to wait for server to reach desired state: %#v", err)
Expand Down
3 changes: 0 additions & 3 deletions upcloud/request/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package request
import (
"encoding/json"
"fmt"
"time"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
)
Expand Down Expand Up @@ -93,7 +92,6 @@ func (r *DeleteKubernetesClusterRequest) RequestURL() string {
// to enter a desired state
type WaitForKubernetesClusterStateRequest struct {
DesiredState upcloud.KubernetesClusterState `json:"-"`
Timeout time.Duration `json:"-"`
UUID string `json:"-"`
}

Expand All @@ -105,7 +103,6 @@ func (r *WaitForKubernetesClusterStateRequest) RequestURL() string {
// to enter a desired state
type WaitForKubernetesNodeGroupStateRequest struct {
DesiredState upcloud.KubernetesNodeGroupState `json:"-"`
Timeout time.Duration `json:"-"`
ClusterUUID string `json:"-"`
Name string `json:"-"`
}
Expand Down
1 change: 0 additions & 1 deletion upcloud/request/managed_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,6 @@ func (r *GetManagedDatabaseVersionsRequest) RequestURL() string {
type WaitForManagedDatabaseStateRequest struct {
UUID string
DesiredState upcloud.ManagedDatabaseState
Timeout time.Duration
}

// StartManagedDatabaseRequest represents a request to start an existing managed database instance
Expand Down
4 changes: 0 additions & 4 deletions upcloud/request/managed_object_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package request

import (
"fmt"
"time"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
)
Expand Down Expand Up @@ -291,7 +290,6 @@ func (r *DeleteManagedObjectStorageUserAccessKeyRequest) RequestURL() string {
// to enter a desired state
type WaitForManagedObjectStorageOperationalStateRequest struct {
DesiredState upcloud.ManagedObjectStorageOperationalState `json:"-"`
Timeout time.Duration `json:"-"`
UUID string `json:"-"`
}

Expand All @@ -304,7 +302,6 @@ func (r *WaitForManagedObjectStorageOperationalStateRequest) RequestURL() string
// to enter a desired state
type WaitForManagedObjectStorageUserOperationalStateRequest struct {
DesiredState upcloud.ManagedObjectStorageUserOperationalState `json:"-"`
Timeout time.Duration `json:"-"`
ServiceUUID string `json:"-"`
Username string `json:"-"`
}
Expand All @@ -318,7 +315,6 @@ func (r *WaitForManagedObjectStorageUserOperationalStateRequest) RequestURL() st
// to be deleted
type WaitForManagedObjectStorageDeletionRequest struct {
DesiredState upcloud.ManagedObjectStorageOperationalState `json:"-"`
Timeout time.Duration `json:"-"`
UUID string `json:"-"`
}

Expand Down
1 change: 0 additions & 1 deletion upcloud/request/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ type WaitForServerStateRequest struct {
UUID string
DesiredState string
UndesiredState string
Timeout time.Duration
}

// StartServerRequest represents a request to start a server
Expand Down
3 changes: 0 additions & 3 deletions upcloud/request/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package request
import (
"encoding/json"
"fmt"
"time"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
)
Expand Down Expand Up @@ -238,7 +237,6 @@ func (r TemplatizeStorageRequest) MarshalJSON() ([]byte, error) {
type WaitForStorageStateRequest struct {
UUID string
DesiredState string
Timeout time.Duration
}

// LoadCDROMRequest represents a request to load a storage as a CD-ROM in the CD-ROM device of a server
Expand Down Expand Up @@ -355,7 +353,6 @@ func (r *GetStorageImportDetailsRequest) RequestURL() string {
// for storage import to complete.
type WaitForStorageImportCompletionRequest struct {
StorageUUID string
Timeout time.Duration
}

// ResizeStorageFilesystemRequest represents a request to resize storage filesystem
Expand Down
46 changes: 13 additions & 33 deletions upcloud/service/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"log"
"net/http"
"time"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud/request"
Expand Down Expand Up @@ -77,20 +76,14 @@ func (s *Service) DeleteKubernetesCluster(ctx context.Context, r *request.Delete
// specified state. If the state changes favorably, cluster details are returned. The method will give up
// after the specified timeout
func (s *Service) WaitForKubernetesClusterState(ctx context.Context, r *request.WaitForKubernetesClusterStateRequest) (*upcloud.KubernetesCluster, error) {
attempts := 0
sleepDuration := time.Second * 5

for {
attempts++
time.Sleep(sleepDuration)

details, err := s.GetKubernetesCluster(ctx, &request.GetKubernetesClusterRequest{
return retry(ctx, func(i int, c context.Context) (*upcloud.KubernetesCluster, error) {
details, err := s.GetKubernetesCluster(c, &request.GetKubernetesClusterRequest{
UUID: r.UUID,
})
if err != nil {
// Ignore first two 404 responses to avoid errors caused by possible false NOT_FOUND responses right after cluster has been created.
var ucErr *upcloud.Problem
if errors.As(err, &ucErr) && ucErr.Status == http.StatusNotFound && attempts < 3 {
if errors.As(err, &ucErr) && ucErr.Status == http.StatusNotFound && i < 3 {
log.Printf("ERROR: %+v", err)
} else {
return nil, err
Expand All @@ -100,57 +93,44 @@ func (s *Service) WaitForKubernetesClusterState(ctx context.Context, r *request.
if details.State == r.DesiredState {
return details, nil
}

if time.Duration(attempts)*sleepDuration >= r.Timeout {
return nil, fmt.Errorf("timeout reached while waiting for Kubernetes cluster to enter state \"%s\"", r.DesiredState)
}
}
return nil, nil
}, nil)
}

// WaitForKubernetesNodeGroupState blocks execution until the specified Kubernetes node group has entered the
// specified state. If the state changes favorably, node group is returned. The method will give up
// after the specified timeout
func (s *Service) WaitForKubernetesNodeGroupState(ctx context.Context, r *request.WaitForKubernetesNodeGroupStateRequest) (*upcloud.KubernetesNodeGroup, error) {
attempts := 0
sleepDuration := time.Second * 5

for {
attempts++
time.Sleep(sleepDuration)

ng, err := s.GetKubernetesNodeGroup(ctx, &request.GetKubernetesNodeGroupRequest{
return retry(ctx, func(i int, c context.Context) (*upcloud.KubernetesNodeGroup, error) {
ng, err := s.GetKubernetesNodeGroup(c, &request.GetKubernetesNodeGroupRequest{
ClusterUUID: r.ClusterUUID,
Name: r.Name,
})
if err != nil {
// Ignore first two 404 responses to avoid errors caused by possible false NOT_FOUND responses right after cluster or node group has been created.
// Ignore first two 404 responses to avoid errors caused by possible false NOT_FOUND responses right after cluster has been created.
var ucErr *upcloud.Problem
if !(errors.As(err, &ucErr) && ucErr.Status == http.StatusNotFound) || attempts >= 3 {
if errors.As(err, &ucErr) && ucErr.Status == http.StatusNotFound && i < 3 {
log.Printf("ERROR: %+v", err)
} else {
return nil, err
}
}

if ng.State == r.DesiredState {
return &ng.KubernetesNodeGroup, nil
}

if time.Duration(attempts)*sleepDuration >= r.Timeout {
return nil, fmt.Errorf("timeout reached while waiting for Kubernetes node group to enter state \"%s\"", r.DesiredState)
}
}
return nil, nil
}, nil)
}

// GetKubernetesKubeconfig retrieves kubeconfig of a Kubernetes cluster.
func (s *Service) GetKubernetesKubeconfig(ctx context.Context, r *request.GetKubernetesKubeconfigRequest) (string, error) {
// TODO: should timeout be part of GetKubernetesKubeconfigRequest ?
const timeout time.Duration = 10 * time.Minute
data := struct {
Kubeconfig string `json:"kubeconfig"`
}{}

_, err := s.WaitForKubernetesClusterState(ctx, &request.WaitForKubernetesClusterStateRequest{
DesiredState: upcloud.KubernetesClusterStateRunning,
Timeout: timeout,
UUID: r.UUID,
})
if err != nil {
Expand Down
3 changes: 0 additions & 3 deletions upcloud/service/kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"net/http"
"testing"
"time"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud/client"
Expand Down Expand Up @@ -524,7 +523,6 @@ func TestWaitForKubernetesClusterState(t *testing.T) {
_, err := svc.WaitForKubernetesClusterState(context.Background(), &request.WaitForKubernetesClusterStateRequest{
UUID: "_UUID_",
DesiredState: upcloud.KubernetesClusterStateRunning,
Timeout: time.Second * 20,
})
assert.NoError(t, err)
assert.Equal(t, 3, requestsMade)
Expand Down Expand Up @@ -584,7 +582,6 @@ func TestWaitForKubernetesNodeGroupState(t *testing.T) {
_, err := svc.WaitForKubernetesNodeGroupState(context.Background(), &request.WaitForKubernetesNodeGroupStateRequest{
ClusterUUID: "_UUID_",
DesiredState: upcloud.KubernetesNodeGroupStateRunning,
Timeout: time.Second * 20,
Name: "_NAME_",
})
assert.NoError(t, err)
Expand Down
19 changes: 4 additions & 15 deletions upcloud/service/managed_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"errors"
"fmt"
"time"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud/request"
Expand Down Expand Up @@ -170,13 +169,8 @@ func (s *Service) GetManagedDatabaseVersions(ctx context.Context, r *request.Get
// specified state. If the state changes favorably, the new managed database details is returned. The method will give up
// after the specified timeout
func (s *Service) WaitForManagedDatabaseState(ctx context.Context, r *request.WaitForManagedDatabaseStateRequest) (*upcloud.ManagedDatabase, error) {
attempts := 0
sleepDuration := time.Second * 5

for {
attempts++

details, err := s.GetManagedDatabase(ctx, &request.GetManagedDatabaseRequest{
return retry(ctx, func(_ int, c context.Context) (*upcloud.ManagedDatabase, error) {
details, err := s.GetManagedDatabase(c, &request.GetManagedDatabaseRequest{
UUID: r.UUID,
})
if err != nil {
Expand All @@ -186,13 +180,8 @@ func (s *Service) WaitForManagedDatabaseState(ctx context.Context, r *request.Wa
if details.State == r.DesiredState {
return details, nil
}

time.Sleep(sleepDuration)

if time.Duration(attempts)*sleepDuration >= r.Timeout {
return nil, fmt.Errorf("timeout reached while waiting for managed database instance to enter state \"%s\"", r.DesiredState)
}
}
return nil, nil
}, nil)
}

// StartManagedDatabase starts a shut down existing managed database instance
Expand Down
1 change: 0 additions & 1 deletion upcloud/service/managed_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,6 @@ func waitForManagedDatabaseRunningState(ctx context.Context, rec *recorder.Recor
_, err := svc.WaitForManagedDatabaseState(ctx, &request.WaitForManagedDatabaseStateRequest{
UUID: dbUUID,
DesiredState: upcloud.ManagedDatabaseStateRunning,
Timeout: waitTimeout,
})

return err
Expand Down
Loading
Loading