Skip to content

Commit

Permalink
billing APIをキャッシュする
Browse files Browse the repository at this point in the history
  • Loading branch information
hekki committed Oct 25, 2024
1 parent 32f9b1e commit 31febb4
Showing 1 changed file with 44 additions and 1 deletion.
45 changes: 44 additions & 1 deletion platform/bill.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,42 @@ import (
"errors"
"fmt"
"sync"
"time"

"github.com/sacloud/iaas-api-go"
"github.com/sacloud/iaas-api-go/types"
)

var (
BILL_API_UPDATE_HOUR_JST = 4

Check failure on line 29 in platform/bill.go

View workflow job for this annotation

GitHub Actions / lint-go

ST1003: should not use ALL_CAPS in Go names; use CamelCase instead (stylecheck)

Check failure on line 29 in platform/bill.go

View workflow job for this annotation

GitHub Actions / lint-go

ST1003: should not use ALL_CAPS in Go names; use CamelCase instead (stylecheck)
BILL_API_UPDATE_MINUTE_JST = 30

Check failure on line 30 in platform/bill.go

View workflow job for this annotation

GitHub Actions / lint-go

ST1003: should not use ALL_CAPS in Go names; use CamelCase instead (stylecheck)

Check failure on line 30 in platform/bill.go

View workflow job for this annotation

GitHub Actions / lint-go

ST1003: should not use ALL_CAPS in Go names; use CamelCase instead (stylecheck)
)

// BillClient calls SakuraCloud bill API
type BillClient interface {
Read(context.Context) (*iaas.Bill, error)
}

func getBillClient(caller iaas.APICaller) BillClient {
return &billClient{caller: caller}
return &billClient{
caller: caller,
cache: *newCache(30 * time.Minute),
}
}

type billClient struct {
caller iaas.APICaller
accountID types.ID
once sync.Once
cache cache
}

func (c *billClient) Read(ctx context.Context) (*iaas.Bill, error) {
ca := c.cache.get()
if ca != nil {
return ca.(*iaas.Bill), nil
}

var err error
c.once.Do(func() {
var auth *iaas.AuthStatus
Expand Down Expand Up @@ -74,5 +89,33 @@ func (c *billClient) Read(ctx context.Context) (*iaas.Bill, error) {
bill = b
}
}

n, err := nextCacheExpiresAt()
if err != nil {
return nil, err
}
c.cache.set(bill, n)

Check failure on line 97 in platform/bill.go

View workflow job for this annotation

GitHub Actions / lint-go

Error return value of `c.cache.set` is not checked (errcheck)

Check failure on line 97 in platform/bill.go

View workflow job for this annotation

GitHub Actions / lint-go

Error return value of `c.cache.set` is not checked (errcheck)

return bill, nil
}

// キャッシュの有効期限を算出する
//
// Billing APIは1日1回 AM4:30 (JST) にデータが更新される。
// このため、現在時刻がAM4:30 (JST) よりも早ければ当日のAM4:30 (JST)、
// 現在時刻がAM4:30 (JST) よりも遅ければ翌日のAM4:30 (JST) を有効期限として扱う。
func nextCacheExpiresAt() (time.Time, error) {
jst, err := time.LoadLocation("Asia/Tokyo")
if err != nil {
return time.Time{}, err
}

// 実行環境のタイムゾーンは不定のためJSTを基準にする
now := time.Now().In(jst)
expiresAt := time.Date(now.Year(), now.Month(), now.Day(), BILL_API_UPDATE_HOUR_JST, BILL_API_UPDATE_MINUTE_JST, 0, 0, jst)
if now.Equal(expiresAt) || now.After(expiresAt) {
expiresAt = expiresAt.Add(24 * time.Hour)
}

return expiresAt, nil
}

0 comments on commit 31febb4

Please sign in to comment.