Skip to content

Commit ce619c9

Browse files
authored
Merge pull request #2329 from ActiveState/DX-1490
2 parents b4aa32a + 16d0af9 commit ce619c9

629 files changed

Lines changed: 14414 additions & 165260 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

activestate.generators.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ scripts:
8888
language: bash
8989
description: Generates graph server and client files
9090
value: |
91-
type gqlgen &>/dev/null || go install github.com/99designs/gqlgen@v0.13.0
92-
cd ./cmd/state-svc && gqlgen
91+
go install github.com/99designs/gqlgen@v0.17.24
92+
cd ./cmd/state-svc && gqlgen --verbose
9393
- name: generate-test-update
9494
language: bash
9595
standalone: true

cmd/state-svc/internal/resolver/resolver.go

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package resolver
22

33
import (
44
"encoding/json"
5+
"github.com/ActiveState/cli/cmd/state-svc/internal/rtusage"
56
"sort"
67
"time"
78

@@ -30,6 +31,8 @@ type Resolver struct {
3031
cfg *config.Instance
3132
depPoller *poller.Poller
3233
updatePoller *poller.Poller
34+
authPoller *poller.Poller
35+
usageChecker *rtusage.Checker
3336
projectIDCache *projectcache.ID
3437
an *sync.Client
3538
anForClient *sync.Client // Use separate client for events sent through service so we don't contaminate one with the other
@@ -49,11 +52,22 @@ func New(cfg *config.Instance, an *sync.Client, auth *authentication.Auth) (*Res
4952
return upchecker.Check()
5053
})
5154

55+
pollAuth := poller.New(1*time.Minute, func() (interface{}, error) {
56+
if auth.SyncRequired() {
57+
return nil, auth.Sync()
58+
}
59+
return nil, nil
60+
})
61+
62+
usageChecker := rtusage.NewChecker(cfg, auth)
63+
5264
anForClient := sync.New(cfg, auth)
5365
return &Resolver{
5466
cfg,
5567
pollDep,
5668
pollUpdate,
69+
pollAuth,
70+
usageChecker,
5771
projectcache.NewID(),
5872
an,
5973
anForClient,
@@ -64,6 +78,7 @@ func New(cfg *config.Instance, an *sync.Client, auth *authentication.Auth) (*Res
6478
func (r *Resolver) Close() error {
6579
r.depPoller.Close()
6680
r.updatePoller.Close()
81+
r.authPoller.Close()
6782
r.anForClient.Close()
6883
return r.rtwatch.Close()
6984
}
@@ -158,16 +173,34 @@ func (r *Resolver) AnalyticsEvent(_ context.Context, category, action string, _l
158173
return &graph.AnalyticsEventResponse{Sent: true}, nil
159174
}
160175

161-
func (r *Resolver) RuntimeUsage(ctx context.Context, pid int, exec string, dimensionsJSON string) (*graph.RuntimeUsageResponse, error) {
176+
func (r *Resolver) ReportRuntimeUsage(_ context.Context, pid int, exec string, dimensionsJSON string) (*graph.ReportRuntimeUsageResponse, error) {
162177
logging.Debug("Runtime usage resolver: %d - %s", pid, exec)
163178
var dims *dimensions.Values
164179
if err := json.Unmarshal([]byte(dimensionsJSON), &dims); err != nil {
165-
return &graph.RuntimeUsageResponse{Received: false}, errs.Wrap(err, "Could not unmarshal")
180+
return &graph.ReportRuntimeUsageResponse{Received: false}, errs.Wrap(err, "Could not unmarshal")
166181
}
167182

168183
r.rtwatch.Watch(pid, exec, dims)
169184

170-
return &graph.RuntimeUsageResponse{Received: true}, nil
185+
return &graph.ReportRuntimeUsageResponse{Received: true}, nil
186+
}
187+
188+
func (r *Resolver) CheckRuntimeUsage(_ context.Context, organizationName string) (*graph.CheckRuntimeUsageResponse, error) {
189+
logging.Debug("CheckRuntimeUsage resolver")
190+
191+
usage, err := r.usageChecker.Check(organizationName)
192+
if err != nil {
193+
return nil, errs.Wrap(err, "Could not check runtime usage: %s", errs.JoinMessage(err))
194+
}
195+
196+
result := &graph.CheckRuntimeUsageResponse{
197+
Limit: int(usage.LimitDynamicRuntimes),
198+
Usage: int(usage.ActiveDynamicRuntimes),
199+
}
200+
201+
logging.Debug("Returning %v, based on %v", result, usage)
202+
203+
return result, nil
171204
}
172205

173206
func (r *Resolver) CheckDeprecation(ctx context.Context) (*graph.DeprecationInfo, error) {
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package rtusage
2+
3+
import (
4+
"github.com/ActiveState/cli/internal/errs"
5+
"github.com/ActiveState/cli/internal/logging"
6+
"github.com/ActiveState/cli/pkg/platform/api/graphql"
7+
"github.com/ActiveState/cli/pkg/platform/api/graphql/model"
8+
"github.com/ActiveState/cli/pkg/platform/api/graphql/request"
9+
"github.com/ActiveState/cli/pkg/platform/authentication"
10+
"github.com/patrickmn/go-cache"
11+
"time"
12+
)
13+
14+
const cacheKey = "runtime-usage-"
15+
16+
// Checker is the struct that we use to do checks with
17+
type Checker struct {
18+
config configurable
19+
cache *cache.Cache
20+
auth *authentication.Auth
21+
}
22+
23+
// configurable defines the configuration function used by the functions in this package
24+
type configurable interface {
25+
ConfigPath() string
26+
GetTime(key string) time.Time
27+
Set(key string, value interface{}) error
28+
Close() error
29+
}
30+
31+
// NewChecker returns a new instance of the Checker struct
32+
func NewChecker(configuration configurable, auth *authentication.Auth) *Checker {
33+
checker := &Checker{
34+
configuration,
35+
cache.New(1*time.Hour, 1*time.Hour),
36+
auth,
37+
}
38+
39+
return checker
40+
}
41+
42+
// Check will check the runtime usage for the given organization, it may return a cached result
43+
func (c *Checker) Check(organizationName string) (*model.RuntimeUsage, error) {
44+
if cached, ok := c.cache.Get(cacheKey + organizationName); ok {
45+
return cached.(*model.RuntimeUsage), nil
46+
}
47+
48+
client := graphql.New()
49+
50+
orgsResponse := model.Organizations{}
51+
if err := client.Run(request.OrganizationsByName(organizationName), &orgsResponse); err != nil {
52+
return nil, errs.Wrap(err, "Could not fetch organization: %s", organizationName)
53+
}
54+
if len(orgsResponse.Organizations) == 0 {
55+
return nil, errs.New("Could not find organization: %s", organizationName)
56+
}
57+
org := orgsResponse.Organizations[0]
58+
59+
usageResponse := model.RuntimeUsageResponse{}
60+
if err := client.Run(request.RuntimeUsage(org.ID), &usageResponse); err != nil {
61+
return nil, errs.Wrap(err, "Could not fetch runtime usage information")
62+
}
63+
64+
if len(usageResponse.Usage) == 0 {
65+
logging.Debug("No runtime usage information found for organization: %s", organizationName)
66+
return nil, nil
67+
}
68+
69+
c.cache.Set(cacheKey+organizationName, &usageResponse.Usage[0], 0)
70+
71+
return &usageResponse.Usage[0], nil
72+
}

0 commit comments

Comments
 (0)