Skip to content

Commit

Permalink
Merge pull request #94 from hwki/feat/http-reduce-data-usage-minor
Browse files Browse the repository at this point in the history
add caching
  • Loading branch information
hwki authored Oct 10, 2021
2 parents 8735d5d + d22904b commit d72d8b4
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,6 @@ data class Widget(
fun coinName() = coinCustomName ?: coin.coinName

fun isOld(refresh: Int) = System.currentTimeMillis() - lastUpdated > (60000 * refresh * 1.5)

fun shouldRefresh(refresh: Int, manual: Boolean): Boolean {
// if this is a manual refresh, don't pull down new data if its been less than
// 60 seconds since last time, to avoid HTTP 429 errors
// otherwise, refresh if its close enough to the scheduled refresh time
val since = System.currentTimeMillis() - lastUpdated
return if (manual) {
since > 60000
} else {
since > (60000 * refresh * .25)
}
}
}

@Entity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.brentpanther.bitcoinwidget.exchange

import com.brentpanther.bitcoinwidget.WidgetApplication
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonObject
Expand All @@ -8,7 +9,8 @@ import java.io.IOException
import java.io.InputStream
import java.util.concurrent.TimeUnit

internal object ExchangeHelper {
object ExchangeHelper {


private val SPEC = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3)
Expand All @@ -27,7 +29,23 @@ internal object ExchangeHelper {
CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
.build()

val connectionPool = ConnectionPool()
var useCache = true
val cache : Cache?
get() = if (!useCache) null else Cache(WidgetApplication.instance.cacheDir, 256 * 1024L) // 256k

private val client: OkHttpClient by lazy {
OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(5, TimeUnit.SECONDS)
.connectionSpecs(listOf(SPEC, ConnectionSpec.CLEARTEXT))
.retryOnConnectionFailure(false)
.connectionPool(ConnectionPool())
.cache(cache)
.addNetworkInterceptor { chain -> intercept(chain) }
.hostnameVerifier { _, _ -> true }.build()
}

@Throws(IOException::class)
@JvmOverloads
Expand All @@ -45,21 +63,23 @@ internal object ExchangeHelper {
private fun getString(url: String, headers: Headers? = null) = get(url, headers).body!!.string()

private fun get(url: String, headers: Headers? = null): Response {
val client = OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(5, TimeUnit.SECONDS)
.connectionSpecs(listOf(SPEC, ConnectionSpec.CLEARTEXT))
.retryOnConnectionFailure(false)
.connectionPool(connectionPool)
.hostnameVerifier { _, _ -> true }.build()
var builder: Request.Builder = Request.Builder().url(url)
var builder = Request.Builder().url(url)
headers?.let {
builder = builder.headers(it)
}
val request = builder.build()
return client.newCall(request).execute()
}

@Throws(IOException::class)
private fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request().newBuilder()
.header("Cache-Control", "public, max-age=60")
.build()
val response = chain.proceed(request)
return response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "max-age=60")
.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ import android.content.Context
import android.util.Log
import com.brentpanther.bitcoinwidget.WidgetState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import java.io.IOException

open class PriceWidgetDataStrategy(context: Context, widgetId: Int) : WidgetDataStrategy(context, widgetId) {

override suspend fun loadData(manual: Boolean, force: Boolean): Unit = withContext(Dispatchers.IO) {
val config = getConfig()

if (loading(config.refresh, manual, force)) return@withContext
if (manual) {
delay(750)
}
try {
val currency = widget.currencyCustomName ?: widget.currency
val coin = widget.coinCustomId ?: widget.coin.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.brentpanther.bitcoinwidget.WidgetApplication
import com.brentpanther.bitcoinwidget.WidgetType
import com.brentpanther.bitcoinwidget.db.Widget
import com.brentpanther.bitcoinwidget.db.WidgetDatabase
import kotlinx.coroutines.delay

abstract class WidgetDataStrategy(context: Context, val widgetId: Int) {

Expand All @@ -27,19 +26,6 @@ abstract class WidgetDataStrategy(context: Context, val widgetId: Int) {

abstract suspend fun loadData(manual: Boolean, force: Boolean)

protected suspend fun loading(refresh: Int, manual: Boolean, force: Boolean): Boolean {
val shouldRefresh = widget.shouldRefresh(refresh, manual)
return if (!force && !shouldRefresh) {
// give time for the loading indicator to be noticeable if manual
if (manual) {
delay(750)
}
true
} else {
false
}
}

suspend fun save() {
dao.update(widget)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.brentpanther.bitcoinwidget

import com.brentpanther.bitcoinwidget.exchange.Exchange.valueOf
import com.brentpanther.bitcoinwidget.exchange.ExchangeData
import com.brentpanther.bitcoinwidget.exchange.ExchangeHelper
import org.junit.Test
import java.io.InputStream
import java.util.*
Expand All @@ -16,6 +17,7 @@ class ExchangeTest {
@Test
@Throws(Exception::class)
fun removedCoins() {
ExchangeHelper.useCache = false
val coins = EnumSet.allOf(Coin::class.java).sorted()
for (coin in coins) {
val entry = CoinEntry(coin.name, coin.coinName, coin.name, coin)
Expand Down

0 comments on commit d72d8b4

Please sign in to comment.