@@ -3,7 +3,7 @@ package com.colisweb.distances
3
3
import cats .Parallel
4
4
import cats .effect .Async
5
5
import cats .kernel .Semigroup
6
- import com .colisweb .distances .Cache .{Caching , GetCached }
6
+ import com .colisweb .distances .Cache .{CacheKey , Caching , GetCached }
7
7
import com .colisweb .distances .DistanceProvider .{BatchDistanceF , DistanceF }
8
8
import com .colisweb .distances .Types ._
9
9
import io .circe .{Decoder , Encoder }
@@ -20,16 +20,17 @@ import scala.collection.breakOut
20
20
* @param caching A function which, given a value, caches it and returns it wrapped in a F typeclass instance.
21
21
* @param getCached A function which try to retrieve a value from the cache. The value is wrapped in a Option,
22
22
* which is also wrapped in a F typeclass instance.
23
+ * @param cacheKey A key construction function.
23
24
* @tparam F A typeclass which is constructed from Async and Parallel.
24
25
* @tparam E An error type, specific to the distance provider.
25
26
*/
26
27
class DistanceApi [F [_]: Async : Parallel , E ](
27
28
distanceF : DistanceF [F , E ],
28
29
batchDistanceF : BatchDistanceF [F , E ],
29
30
caching : Caching [F , Distance ],
30
- getCached : GetCached [F , Distance ]
31
+ getCached : GetCached [F , Distance ],
32
+ cacheKey : CacheKey [DirectedPath ]
31
33
) {
32
-
33
34
import DistanceApi ._
34
35
import cats .implicits ._
35
36
import com .colisweb .distances .utils .Implicits ._
@@ -70,8 +71,8 @@ class DistanceApi[F[_]: Async: Parallel, E](
70
71
origins
71
72
.flatMap(origin => destinations.map(Segment (origin, _)))
72
73
.parTraverse { segment =>
73
- val maybeCachedValue =
74
- getCached(decoder, travelMode, segment.origin, segment.destination, maybeTrafficHandling )
74
+ val path = DirectedPath (segment.origin, segment.destination, travelMode, maybeTrafficHandling)
75
+ val maybeCachedValue = getCached(decoder, cacheKey(path) : _* )
75
76
76
77
(segment.pure[F ] -> maybeCachedValue).bisequence
77
78
}
@@ -182,17 +183,18 @@ class DistanceApi[F[_]: Async: Parallel, E](
182
183
origin : LatLong ,
183
184
destination : LatLong ,
184
185
maybeTrafficHandling : Option [TrafficHandling ]
185
- ): F [List [(DirectedPath , Either [E , Distance ])]] =
186
+ ): F [List [(DirectedPath , Either [E , Distance ])]] = {
186
187
modes.parTraverse { mode =>
187
188
for {
188
- cached <- getCached(decoder, mode, origin, destination, maybeTrafficHandling)
189
+ cached <- getCached(decoder, cacheKey( DirectedPath ( origin, destination, mode, maybeTrafficHandling)) : _* )
189
190
errorOrDistance <- cached match {
190
191
case Some (value) => Either .right[E , Distance ](value).pure[F ]
191
192
case None => distanceF(mode, origin, destination, maybeTrafficHandling)
192
193
}
193
194
result <- maybeUpdateCache(errorOrDistance, mode, origin, destination, maybeTrafficHandling)
194
195
} yield DirectedPath (origin, destination, mode, maybeTrafficHandling) -> result
195
196
}
197
+ }
196
198
197
199
private def maybeUpdateCache (
198
200
errorOrDistance : Either [E , Distance ],
@@ -203,7 +205,8 @@ class DistanceApi[F[_]: Async: Parallel, E](
203
205
): F [Either [E , Distance ]] = {
204
206
errorOrDistance match {
205
207
case Right (distance) =>
206
- caching(distance, decoder, encoder, mode, origin, destination, maybeTrafficHandling).map(Right [E , Distance ])
208
+ caching(distance, decoder, encoder, cacheKey(DirectedPath (origin, destination, mode, maybeTrafficHandling)): _* )
209
+ .map(Right [E , Distance ])
207
210
208
211
case Left (error) => error.pure[F ].map(Left [E , Distance ])
209
212
}
@@ -218,9 +221,10 @@ object DistanceApi {
218
221
distanceF : DistanceF [F , E ],
219
222
batchDistanceF : BatchDistanceF [F , E ],
220
223
caching : Caching [F , Distance ],
221
- getCached : GetCached [F , Distance ]
224
+ getCached : GetCached [F , Distance ],
225
+ cacheKey : CacheKey [DirectedPath ]
222
226
): DistanceApi [F , E ] =
223
- new DistanceApi (distanceF, batchDistanceF, caching, getCached)
227
+ new DistanceApi (distanceF, batchDistanceF, caching, getCached, cacheKey )
224
228
225
229
private [DistanceApi ] final val directedPathSemiGroup : Semigroup [DirectedPathMultipleModes ] =
226
230
new Semigroup [DirectedPathMultipleModes ] {
0 commit comments