Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coupon APIをキャッシュする #204

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions platform/bill.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (c *billClient) Read(ctx context.Context) (*iaas.Bill, error) {
}
}

n, err := nextCacheExpiresAt()
n, err := c.nextCacheExpiresAt()
if err != nil {
return nil, err
}
Expand All @@ -107,7 +107,7 @@ func (c *billClient) Read(ctx context.Context) (*iaas.Bill, error) {
// Billing APIは1日1回 AM4:30 (JST) にデータが更新される。
// このため、現在時刻がAM4:30 (JST) よりも早ければ当日のAM4:30 (JST)、
// 現在時刻がAM4:30 (JST) よりも遅ければ翌日のAM4:30 (JST) を有効期限として扱う。
func nextCacheExpiresAt() (time.Time, error) {
func (c *billClient) nextCacheExpiresAt() (time.Time, error) {
jst, err := time.LoadLocation("Asia/Tokyo")
if err != nil {
return time.Time{}, err
Expand Down
42 changes: 41 additions & 1 deletion platform/coupon.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"errors"
"sync"
"time"

"github.com/sacloud/iaas-api-go"
"github.com/sacloud/iaas-api-go/types"
Expand All @@ -29,16 +30,25 @@ type CouponClient interface {
}

func getCouponClient(caller iaas.APICaller) CouponClient {
return &couponClient{caller: caller}
return &couponClient{
caller: caller,
cache: *newCache(30 * time.Minute),
}
}

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

func (c *couponClient) Find(ctx context.Context) ([]*iaas.Coupon, error) {
ca := c.cache.get()
if ca != nil {
return ca.([]*iaas.Coupon), nil
}

var err error
c.once.Do(func() {
var auth *iaas.AuthStatus
Expand All @@ -63,5 +73,35 @@ func (c *couponClient) Find(ctx context.Context) ([]*iaas.Coupon, error) {
return nil, err
}

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

return searched.Coupons, nil
}

// キャッシュの有効期限を算出する
//
// Billing APIは1日1回 AM4:30 (JST) にデータが更新される。
// このため、現在時刻がAM4:30 (JST) よりも早ければ当日のAM4:30 (JST)、
// 現在時刻がAM4:30 (JST) よりも遅ければ翌日のAM4:30 (JST) を有効期限として扱う。
func (c *couponClient) nextCacheExpiresAt() (time.Time, error) {
Copy link
Member Author

@hekki hekki Oct 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

platform/bill.go とロジックが重複してしまっていますが、キャッシュの有効期限はキャッシュを使う側が決定するほうが自然と考えたので、こちらに実装しています。

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(), BillAPIUpdateHourJST, BillAPIUpdateMinuteJST, 0, 0, jst)
if now.Equal(expiresAt) || now.After(expiresAt) {
expiresAt = expiresAt.Add(24 * time.Hour)
}

return expiresAt, nil
}