diff options
-rw-r--r-- | docker-compose.yaml | 2 | ||||
-rw-r--r-- | hived/hived.go | 96 |
2 files changed, 53 insertions, 45 deletions
diff --git a/docker-compose.yaml b/docker-compose.yaml index b01901f..25245d4 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -60,6 +60,8 @@ services: ports: - "8009:8009" entrypoint: ["/arbiter/arbiter"] + volumes: + - /etc/letsencrypt/archive/api.terminaldweller.com/:/certs/ cap_drop: - ALL environment: diff --git a/hived/hived.go b/hived/hived.go index 51ea933..927e633 100644 --- a/hived/hived.go +++ b/hived/hived.go @@ -36,6 +36,7 @@ var ( redisPassword = flag.String("redispassword", "", "determines the password of the redis db") redisDB = flag.Int64("redisdb", 0, "determines the db number") botChannelID = flag.Int64("botchannelid", 146328407, "determines the channel id the telgram bot should send messages to") + cacheDuration = flag.Float64("cacheDuration", 300_000, "determines the price cache validity duration in miliseconds") rdb *redis.Client ) @@ -89,45 +90,41 @@ type errorChanStruct struct { err error } -func getPriceFromCoinGecko( - name, unit string, +type APISource int + +const ( + CryptoCompareSource = iota + CoinGeckoSource + CoinCapSource +) + +// TODO-add more sources +// TODO-do a round robin +func chooseGetPriceSource() int { + return CryptoCompareSource +} + +func getPrice(name, unit string, wg *sync.WaitGroup, priceChan chan<- priceChanStruct, errChan chan<- errorChanStruct) { - defer wg.Done() - - params := "/simple/price?fsym=" + url.QueryEscape(name) + "&" + - "tsyms=" + url.QueryEscape(unit) - path := coingeckoAPIURLv3 + params - resp, err := http.Get(path) - if err != nil { - priceChan <- priceChanStruct{name: name, price: 0.} - errChan <- errorChanStruct{hasError: true, err: err} - log.Error().Err(err) - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + // check price cache + ctx := context.Background() + val, err := rdb.Get(ctx, name+"_price").Float64() if err != nil { - priceChan <- priceChanStruct{name: name, price: 0.} - errChan <- errorChanStruct{hasError: true, err: err} - log.Error().Err(err) - } + fmt.Println("price cache miss") + source := chooseGetPriceSource() - jsonBody := make(map[string]interface{}) - err = json.Unmarshal(body, &jsonBody) - if err != nil { - priceChan <- priceChanStruct{name: name, price: 0.} - errChan <- errorChanStruct{hasError: true, err: err} - log.Error().Err(err) + if source == CryptoCompareSource { + getPriceFromCryptoCompare(name, unit, wg, priceChan, errChan) + } + } else { + fmt.Println("price cache hit ", val) + priceChan <- priceChanStruct{name: name, price: val} + errChan <- errorChanStruct{hasError: false, err: nil} + wg.Done() } - - price := jsonBody[name].(map[string]interface{})[unit].(float64) - - log.Info().Msg(string(body)) - - priceChan <- priceChanStruct{name: name, price: price} - errChan <- errorChanStruct{hasError: false, err: nil} } func getPriceFromCryptoCompare( @@ -166,6 +163,13 @@ func getPriceFromCryptoCompare( log.Info().Msg(string(body)) + // add a price cache + ctx := context.Background() + err = rdb.Set(ctx, name+"_price", jsonBody[unit], time.Duration(*cacheDuration*1000000)).Err() + if err != nil { + log.Error().Err(err) + } + priceChan <- priceChanStruct{name: name, price: jsonBody[unit]} errChan <- errorChanStruct{hasError: false, err: nil} } @@ -205,7 +209,8 @@ func PriceHandler(w http.ResponseWriter, r *http.Request) { defer close(errChan) defer close(priceChan) wg.Add(1) - go getPriceFromCryptoCompare(name, unit, &wg, priceChan, errChan) + // TODO- check cache + go getPrice(name, unit, &wg, priceChan, errChan) wg.Wait() select { @@ -272,8 +277,8 @@ func PairHandler(w http.ResponseWriter, r *http.Request) { defer close(errChan) wg.Add(2) - go getPriceFromCryptoCompare(one, "USD", &wg, priceChan, errChan) - go getPriceFromCryptoCompare(two, "USD", &wg, priceChan, errChan) + go getPrice(one, "USD", &wg, priceChan, errChan) + go getPrice(two, "USD", &wg, priceChan, errChan) wg.Wait() for i := 0; i < 2; i++ { @@ -363,7 +368,8 @@ func alertManager() { wg.Add(len(vars)) for i := range vars { - go getPriceFromCryptoCompare(vars[i], "USD", &wg, priceChan, errChan) + // TODO-get from cache + go getPrice(vars[i], "USD", &wg, priceChan, errChan) } wg.Wait() @@ -652,15 +658,15 @@ func robotsHandler(w http.ResponseWriter, r *http.Request) { func startServer(gracefulWait time.Duration) { r := mux.NewRouter() cfg := &tls.Config{ - MinVersion: tls.VersionTLS13, - // CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, - // PreferServerCipherSuites: true, - // CipherSuites: []uint16{ - // tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - // tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - // tls.TLS_RSA_WITH_AES_256_GCM_SHA384, - // tls.TLS_RSA_WITH_AES_256_CBC_SHA, - // }, + MinVersion: tls.VersionTLS13, + CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, + PreferServerCipherSuites: true, + CipherSuites: []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + tls.TLS_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_RSA_WITH_AES_256_CBC_SHA, + }, } srv := &http.Server{ Addr: "0.0.0.0:" + *flagPort, |