Skip to content

Instantly share code, notes, and snippets.

@gruzovator
Last active April 20, 2020 12:57
Show Gist options
  • Save gruzovator/96abceef9397be1d3d2473b56f250da0 to your computer and use it in GitHub Desktop.
Save gruzovator/96abceef9397be1d3d2473b56f250da0 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"sync"
)
type CurrencyRateFuture func() (float64, error)
func NewCurrencyRateFuture() CurrencyRateFuture {
var (
val float64
err error
mtx sync.Mutex
)
mtx.Lock()
go func() {
defer mtx.Unlock()
v, e := ReadCurrencyRateFromRBC()
val = v
if e != nil {
err = fmt.Errorf("reading currency rate: %s", e)
}
}()
return func() (float64, error) {
mtx.Lock()
defer mtx.Unlock()
return val, err
}
}
func main() {
currRateFuture := NewCurrencyRateFuture()
rate, err := currRateFuture()
if err != nil {
panic(err)
}
fmt.Println(rate)
rate, err = currRateFuture()
if err != nil {
panic(err)
}
fmt.Println(rate)
}
func ReadCurrencyRateFromRBC() (float64, error) {
log.Print("currency rate reading begin")
defer log.Print("currency rate reading end")
const convAPI = "https://cash.rbc.ru/cash/json/converter_currency_rate/?currency_from=USD&currency_to=RUR&source=cbrf&sum=2&date="
resp, err := http.Get(convAPI)
if err != nil {
return 0, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return 0, fmt.Errorf("bad HTTP status code: %d", resp.StatusCode)
}
reply := struct {
Data struct{ Rate1 float64 }
Status int
}{}
err = json.NewDecoder(resp.Body).Decode(&reply)
if err != nil {
return 0, fmt.Errorf("bad API response: %s", err)
}
if reply.Status != 200 {
return 0, fmt.Errorf("bad API reply status code: %d", reply.Status)
}
return reply.Data.Rate1, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment