Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/usage/pkg/scheduler/ledger_job.go
2498 views
1
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package scheduler
6
7
import (
8
"context"
9
"fmt"
10
"time"
11
12
"github.com/gitpod-io/gitpod/common-go/log"
13
v1 "github.com/gitpod-io/gitpod/usage-api/v1"
14
"github.com/robfig/cron"
15
"google.golang.org/protobuf/types/known/timestamppb"
16
)
17
18
func NewLedgerTriggerJob(schedule time.Duration, job Job) (JobSpec, error) {
19
parsed, err := cron.Parse(fmt.Sprintf("@every %s", schedule.String()))
20
if err != nil {
21
return JobSpec{}, fmt.Errorf("failed to parse period into schedule: %w", err)
22
}
23
24
return JobSpec{
25
Job: job,
26
ID: "ledger",
27
Schedule: parsed,
28
InitialLockDuration: schedule,
29
}, nil
30
}
31
32
type ClientsConstructor func() (v1.UsageServiceClient, v1.BillingServiceClient, error)
33
34
func NewLedgerTrigger(clientConstructor ClientsConstructor) *LedgerJob {
35
return &LedgerJob{
36
clientsConstructor: clientConstructor,
37
}
38
}
39
40
type LedgerJob struct {
41
clientsConstructor ClientsConstructor
42
}
43
44
func (r *LedgerJob) Run() (err error) {
45
ctx := context.Background()
46
now := time.Now().UTC()
47
hourAgo := now.Add(-1 * time.Hour)
48
49
defer func() {
50
reportLedgerCompleted(err)
51
}()
52
53
logger := log.
54
WithField("from", hourAgo).
55
WithField("to", now)
56
57
usageClient, billingClient, err := r.clientsConstructor()
58
if err != nil {
59
return fmt.Errorf("failed to construct usage and billing client: %w", err)
60
}
61
62
logger.Info("Running ledger job. Reconciling usage records.")
63
_, err = usageClient.ReconcileUsage(ctx, &v1.ReconcileUsageRequest{
64
From: timestamppb.New(hourAgo),
65
To: timestamppb.New(now),
66
})
67
if err != nil {
68
logger.WithError(err).Errorf("Failed to reconcile usage with ledger.")
69
return fmt.Errorf("failed to reconcile usage with ledger: %w", err)
70
}
71
72
logger.Info("Starting invoice reconciliation.")
73
_, err = billingClient.ReconcileInvoices(ctx, &v1.ReconcileInvoicesRequest{})
74
if err != nil {
75
logger.WithError(err).Errorf("Failed to reconcile invoices.")
76
return fmt.Errorf("failed to reconcile invoices: %w", err)
77
}
78
79
return nil
80
}
81
82