Skip to content

Commit 71e4630

Browse files
authored
feat(mongodb): add waiters for mongodb api (scaleway#2259)
1 parent 4f7cff3 commit 71e4630

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package mongodb
2+
3+
import (
4+
"time"
5+
6+
"github.com/scaleway/scaleway-sdk-go/errors"
7+
"github.com/scaleway/scaleway-sdk-go/internal/async"
8+
"github.com/scaleway/scaleway-sdk-go/scw"
9+
)
10+
11+
const (
12+
defaultInstanceRetryInterval = 15 * time.Second
13+
defaultInstanceTimeout = 15 * time.Minute
14+
)
15+
16+
// WaitForInstanceRequest is used by WaitForInstance method.
17+
type WaitForInstanceRequest struct {
18+
InstanceID string
19+
Region scw.Region
20+
Timeout *time.Duration
21+
RetryInterval *time.Duration
22+
}
23+
24+
type WaitForSnapshotRequest struct {
25+
InstanceID string
26+
SnapshotID string
27+
Region scw.Region
28+
Timeout *time.Duration
29+
RetryInterval *time.Duration
30+
}
31+
32+
// WaitForInstance waits for the instance to be in a "terminal state" before returning.
33+
// This function can be used to wait for an instance to be ready or in another final state.
34+
func (s *API) WaitForInstance(req *WaitForInstanceRequest, opts ...scw.RequestOption) (*Instance, error) {
35+
timeout := defaultInstanceTimeout
36+
if req.Timeout != nil {
37+
timeout = *req.Timeout
38+
}
39+
retryInterval := defaultInstanceRetryInterval
40+
if req.RetryInterval != nil {
41+
retryInterval = *req.RetryInterval
42+
}
43+
44+
terminalStatus := map[InstanceStatus]struct{}{
45+
InstanceStatusReady: {},
46+
InstanceStatusLocked: {},
47+
InstanceStatusError: {},
48+
}
49+
50+
instance, err := async.WaitSync(&async.WaitSyncConfig{
51+
Get: func() (interface{}, bool, error) {
52+
res, err := s.GetInstance(&GetInstanceRequest{
53+
Region: req.Region,
54+
InstanceID: req.InstanceID,
55+
}, opts...)
56+
if err != nil {
57+
return nil, false, err
58+
}
59+
60+
// Check if the instance has reached a terminal state
61+
_, isTerminal := terminalStatus[res.Status]
62+
63+
return res, isTerminal, nil
64+
},
65+
Timeout: timeout,
66+
IntervalStrategy: async.LinearIntervalStrategy(retryInterval),
67+
})
68+
if err != nil {
69+
return nil, errors.Wrap(err, "waiting for instance failed")
70+
}
71+
return instance.(*Instance), nil
72+
}
73+
74+
// WaitForSnapshot waits for the snapshot to reach a "terminal state" before returning.
75+
func (s *API) WaitForSnapshot(req *WaitForSnapshotRequest, opts ...scw.RequestOption) (*Snapshot, error) {
76+
timeout := defaultInstanceTimeout
77+
if req.Timeout != nil {
78+
timeout = *req.Timeout
79+
}
80+
retryInterval := defaultInstanceRetryInterval
81+
if req.RetryInterval != nil {
82+
retryInterval = *req.RetryInterval
83+
}
84+
85+
terminalStatus := map[SnapshotStatus]struct{}{
86+
SnapshotStatusReady: {},
87+
SnapshotStatusError: {},
88+
SnapshotStatusLocked: {},
89+
}
90+
91+
snapshot, err := async.WaitSync(&async.WaitSyncConfig{
92+
Get: func() (interface{}, bool, error) {
93+
opts = append(opts, scw.WithAllPages())
94+
listSnapshotResponse, err := s.ListSnapshots(&ListSnapshotsRequest{
95+
Region: req.Region,
96+
InstanceID: &req.InstanceID,
97+
}, opts...)
98+
if err != nil {
99+
return nil, false, err
100+
}
101+
102+
for _, snapshot := range listSnapshotResponse.Snapshots {
103+
if snapshot.ID == req.SnapshotID {
104+
_, isTerminal := terminalStatus[snapshot.Status]
105+
return snapshot, isTerminal, nil
106+
}
107+
}
108+
return nil, false, nil
109+
},
110+
Timeout: timeout,
111+
IntervalStrategy: async.LinearIntervalStrategy(retryInterval),
112+
})
113+
if err != nil {
114+
return nil, errors.Wrap(err, "waiting for snapshot failed")
115+
}
116+
return snapshot.(*Snapshot), nil
117+
}

0 commit comments

Comments
 (0)