implement rudimentary caching for yahoo finance to avoid http 429 rate limiting
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
13291da691
commit
61074bfd80
15
providers/staticjsonYahooFinance/cache.go
Normal file
15
providers/staticjsonYahooFinance/cache.go
Normal file
@ -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
|
||||||
|
}
|
@ -3,10 +3,11 @@ package staticjsonYahooFinance
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A chart response is what we get back from Yahoo Finance
|
// A chartResponse response is what we get back from Yahoo Finance
|
||||||
type chart struct {
|
type chartResponse struct {
|
||||||
Chart struct {
|
Chart struct {
|
||||||
Result []struct {
|
Result []struct {
|
||||||
Meta struct {
|
Meta struct {
|
||||||
@ -69,8 +70,16 @@ type chart struct {
|
|||||||
} `json:"chart"`
|
} `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) {
|
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{})
|
err := c.get(fmt.Sprintf("/chart/%s", symbol), chartResponse, url.Values{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("http get request error: %v", err)
|
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))
|
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
|
return int(chartResponse.Chart.Result[0].Meta.RegularMarketPrice * 1000), nil
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type security struct {
|
type security struct {
|
||||||
@ -48,6 +47,8 @@ func (p *Provider) Configure() error {
|
|||||||
return fmt.Errorf("failed to create new client: %v", err)
|
return fmt.Errorf("failed to create new client: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chartCache = make(map[string]chartCacheEntry)
|
||||||
|
|
||||||
return nil
|
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)
|
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
|
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)
|
balances = append(balances, balance)
|
||||||
ynabAccountIDs = append(ynabAccountIDs, p.data.Accounts[i].YnabAccountID)
|
ynabAccountIDs = append(ynabAccountIDs, p.data.Accounts[i].YnabAccountID)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user