Skip to content

Commit c61ec05

Browse files
author
Dmitry Voronov
committed
Transit to guava cache
1 parent d9584ca commit c61ec05

File tree

4 files changed

+36
-101
lines changed

4 files changed

+36
-101
lines changed

src/main/scala/io/iohk/ethereum/db/cache/SimpleLRU.scala

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/main/scala/io/iohk/ethereum/jsonrpc/server/http/RateLimit.scala

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package io.iohk.ethereum.jsonrpc.server.http
22

3+
import java.time.Duration
4+
5+
import akka.NotUsed
36
import akka.http.scaladsl.model.{RemoteAddress, StatusCodes}
47
import akka.http.scaladsl.server.{Directive0, Route}
5-
import io.iohk.ethereum.db.cache.SimpleLRU
68
import io.iohk.ethereum.jsonrpc.server.http.JsonRpcHttpServer.RateLimitConfig
79
import akka.http.scaladsl.server.Directives._
10+
import com.google.common.base.Ticker
11+
import com.google.common.cache.CacheBuilder
812
import io.iohk.ethereum.jsonrpc.JsonRpcError
913
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
1014
import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers
@@ -15,30 +19,50 @@ class RateLimit(config: RateLimitConfig) extends Directive0 with Json4sSupport {
1519
private implicit val serialization: Serialization = native.Serialization
1620
private implicit val formats: Formats = DefaultFormats + JsonSerializers.RpcErrorJsonSerializer
1721

18-
protected def getCurrentTime: Long = System.currentTimeMillis()
22+
protected def getCurrentTimeNanos: Long = System.nanoTime()
23+
24+
private[this] val ticker: Ticker = new Ticker {
25+
override def read(): Long = getCurrentTimeNanos
26+
}
1927

20-
lazy val lru = new SimpleLRU[RemoteAddress](
21-
config.latestTimestampCacheSize,
22-
config.minRequestInterval.toMillis
23-
) {
24-
override protected def getCurrentTime: Long = RateLimit.this.getCurrentTime
28+
private[this] lazy val lru = {
29+
val nanoDuration = config.minRequestInterval.toNanos
30+
val javaDuration = Duration.ofNanos(nanoDuration)
31+
CacheBuilder
32+
.newBuilder()
33+
.weakKeys()
34+
.expireAfterAccess(javaDuration)
35+
.ticker(ticker)
36+
.build[RemoteAddress, NotUsed]()
2537
}
2638

2739
// Such algebras prevent if-elseif-else boilerplate in the JsonRPCServer code
2840
// It is also guaranteed that:
2941
// 1) config.enabled is checked only once - on route init
3042
// 2) no IP address is extracted unless config.enabled is true
3143
// 3) no LRU is created unless config.enabled is true
44+
// 4) cache is accessed only once (using get)
3245
val rateLimitAlgebra: (Unit => Route) => Route = {
3346
if (config.enabled) {
3447
val minInterval = config.minRequestInterval.toSeconds
35-
f =>
48+
f => {
3649
extractClientIP { ip =>
37-
if (lru.checkAndRefreshEntry(ip)) {
50+
var exists = true
51+
lru.get(
52+
ip,
53+
() => {
54+
exists = false
55+
NotUsed
56+
}
57+
)
58+
if (exists) {
3859
val err = JsonRpcError.RateLimitError(minInterval)
3960
complete((StatusCodes.TooManyRequests, err))
40-
} else f.apply(())
61+
} else {
62+
f.apply(())
63+
}
4164
}
65+
}
4266
} else _.apply(())
4367
}
4468

src/test/scala/io/iohk/ethereum/db/cache/SimpleLRUSpec.scala

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class JsonRpcHttpServerSpec extends AnyFlatSpec with Matchers with ScalatestRout
214214
status shouldEqual StatusCodes.TooManyRequests
215215
}
216216

217-
mockJsonRpcHttpServerWithRateLimit.mockedTime = 50L
217+
mockJsonRpcHttpServerWithRateLimit.mockedTime = 50000000L
218218

219219
postRequest ~> Route.seal(mockJsonRpcHttpServerWithRateLimit.route) ~> check {
220220
status shouldEqual StatusCodes.OK
@@ -472,7 +472,7 @@ class FakeJsonRpcHttpServer(
472472
var mockedTime:Long = 0L
473473

474474
override protected val rateLimit: RateLimit = new RateLimit(config.rateLimit) {
475-
override protected def getCurrentTime: Long = FakeJsonRpcHttpServer.this.mockedTime
475+
override protected def getCurrentTimeNanos: Long = FakeJsonRpcHttpServer.this.mockedTime
476476
}
477477

478478
}

0 commit comments

Comments
 (0)