-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathusage.go
More file actions
129 lines (108 loc) · 3.21 KB
/
Copy pathusage.go
File metadata and controls
129 lines (108 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package randomorg
import (
"context"
"time"
)
// Usage holds information related to the the usage of a given API key.
type Usage struct {
// A string indicating the API key's current status, which may be stopped, paused or running.
// An API key must be running for it to be able to serve requests.
Status string
// A timestamp at which the API key was created.
CreationTime time.Time
// An integer containing the (estimated) number of remaining true random bits available to the client.
BitsLeft int
// An integer containing the (estimated) number of remaining API requests available to the client.
RequestsLeft int
// An integer containing the number of bits used by this API key since it was created.
TotalBits int
// An integer containing the number of requests used by this API key since it was created.
TotalRequests int
// Defines if this instance contains all information.
isComplete bool
}
// usageFields are the usage-related fields present, wholly or partially, in
// nearly every Random.org API response. Pointer fields distinguish "absent"
// from "present with the zero value".
type usageFields struct {
Status *string `json:"status"`
CreationTime *string `json:"creationTime"`
BitsLeft *int `json:"bitsLeft"`
RequestsLeft *int `json:"requestsLeft"`
TotalBits *int `json:"totalBits"`
TotalRequests *int `json:"totalRequests"`
}
// mergeUsage merges fields into the cached Usage, tracking whether every
// field required for a complete Usage was present in this response.
func (r *Random) mergeUsage(fields usageFields) {
r.usageMutex.Lock()
defer r.usageMutex.Unlock()
usage := r.usage
if usage == nil {
usage = &Usage{}
}
isComplete := true
if fields.Status != nil {
usage.Status = *fields.Status
} else {
isComplete = false
}
if fields.CreationTime != nil {
creationTime, err := parseAPITime(*fields.CreationTime)
if err == nil {
usage.CreationTime = creationTime
} else {
isComplete = false
}
} else {
isComplete = false
}
if fields.BitsLeft != nil {
usage.BitsLeft = *fields.BitsLeft
} else {
isComplete = false
}
if fields.RequestsLeft != nil {
usage.RequestsLeft = *fields.RequestsLeft
} else {
isComplete = false
}
if fields.TotalBits != nil {
usage.TotalBits = *fields.TotalBits
} else {
isComplete = false
}
if fields.TotalRequests != nil {
usage.TotalRequests = *fields.TotalRequests
} else {
isComplete = false
}
usage.isComplete = isComplete
r.usage = usage
}
// GetUsage returns information related to the the usage of a given API key.
func (r *Random) GetUsage(ctx context.Context) (Usage, error) {
params := baseParams{APIKey: r.apiKey}
fields, err := invokeRequest[usageFields](ctx, r, "getUsage", params)
if err != nil {
return Usage{}, err
}
r.mergeUsage(fields)
r.usageMutex.Lock()
defer r.usageMutex.Unlock()
return *r.usage, nil
}
// Usage returns the API usage. This will return a cached version of the last request, if there is one.
func (r *Random) Usage(ctx context.Context) (Usage, error) {
r.usageMutex.Lock()
cached := r.usage != nil && r.usage.isComplete
var usage Usage
if cached {
usage = *r.usage
}
r.usageMutex.Unlock()
if cached {
return usage, nil
}
return r.GetUsage(ctx)
}