diff --git a/providers/staticjsonYahooFinance/cache.go b/providers/staticjsonYahooFinance/cache.go new file mode 100644 index 0000000..91a9bf9 --- /dev/null +++ b/providers/staticjsonYahooFinance/cache.go @@ -0,0 +1,15 @@ +package staticjsonYahooFinance + +import ( + "time" +) + +const cacheAgeSeconds = 900 + +// intialized in providerImpl.go's Configure +var chartCache map[string]chartCacheEntry + +type chartCacheEntry struct { + Chart chartResponse + LastUpdated time.Time +} diff --git a/providers/staticjsonYahooFinance/chart.go b/providers/staticjsonYahooFinance/chart.go index ae0ce26..8c31041 100644 --- a/providers/staticjsonYahooFinance/chart.go +++ b/providers/staticjsonYahooFinance/chart.go @@ -3,10 +3,11 @@ package staticjsonYahooFinance import ( "fmt" "net/url" + "time" ) -// A chart response is what we get back from Yahoo Finance -type chart struct { +// A chartResponse response is what we get back from Yahoo Finance +type chartResponse struct { Chart struct { Result []struct { Meta struct { @@ -69,8 +70,16 @@ type chart struct { } `json:"chart"` } +// getChart first checks if the symbol chartCacheEntry is valid, +// and if not then it downloads fresh chart data func (c client) getChart(symbol string) (int, error) { - chartResponse := &chart{} + if cacheItem, ok := chartCache[symbol]; ok { + // if the cacheEntry is still valid, use it + if time.Now().Before(cacheItem.LastUpdated.Add(cacheAgeSeconds)) { + return int(cacheItem.Chart.Chart.Result[0].Meta.RegularMarketPrice * 1000), nil + } + } + chartResponse := &chartResponse{} err := c.get(fmt.Sprintf("/chart/%s", symbol), chartResponse, url.Values{}) if err != nil { return 0, fmt.Errorf("http get request error: %v", err) @@ -80,5 +89,7 @@ func (c client) getChart(symbol string) (int, error) { return 0, fmt.Errorf("unexpected length of results - expected 1 but got %d", len(chartResponse.Chart.Result)) } + chartCache[symbol] = chartCacheEntry{Chart: *chartResponse, LastUpdated: time.Now()} + return int(chartResponse.Chart.Result[0].Meta.RegularMarketPrice * 1000), nil } diff --git a/providers/staticjsonYahooFinance/providerImpl.go b/providers/staticjsonYahooFinance/providerImpl.go index 857c989..9a4265e 100644 --- a/providers/staticjsonYahooFinance/providerImpl.go +++ b/providers/staticjsonYahooFinance/providerImpl.go @@ -6,7 +6,6 @@ import ( "fmt" "io" "os" - "time" ) type security struct { @@ -48,6 +47,8 @@ func (p *Provider) Configure() error { return fmt.Errorf("failed to create new client: %v", err) } + chartCache = make(map[string]chartCacheEntry) + return nil } @@ -63,7 +64,6 @@ func (p *Provider) GetBalances() ([]int, []string, error) { return balances, ynabAccountIDs, fmt.Errorf("failed to get quote for security with symbol '%s': %v", p.data.Accounts[i].Securities[j].Symbol, err) } balance += price * p.data.Accounts[i].Securities[j].Quantity - time.Sleep(time.Second) // Disgusting way to avoid HTTP 429 rate limiting } balances = append(balances, balance) ynabAccountIDs = append(ynabAccountIDs, p.data.Accounts[i].YnabAccountID)