Skip to content

Commit d56b9ba

Browse files
Merge pull request #538 from jordiolivares/bugfix/fix-deadlock
Fix problem with fibers being cancelled due to timeout and causing fetch deadlock
2 parents 7b9f6d0 + 42ee937 commit d56b9ba

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

fetch/src/main/scala/datasource.scala

+13-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package fetch
1919
import cats.data.NonEmptyList
2020
import cats.effect._
2121
import cats.effect.implicits._
22-
import cats.effect.std.Queue
22+
import cats.effect.std.{Queue, Supervisor}
2323
import cats.kernel.{Hash => H}
2424
import cats.syntax.all._
2525

@@ -75,8 +75,10 @@ object DataSource {
7575
implicit F: Temporal[F]
7676
): F[List[T]] = {
7777
Ref[F].of(List.empty[T]).flatMap { ref =>
78-
val takeAndBuffer = queue.take.flatMap { x =>
79-
ref.updateAndGet(list => x :: list)
78+
val takeAndBuffer = F.uncancelable { poll =>
79+
poll(queue.take).flatMap { x =>
80+
ref.updateAndGet(list => x :: list)
81+
}
8082
}
8183
val bufferUntilNumElements = takeAndBuffer.iterateUntil { buffer =>
8284
buffer.size == maxElements
@@ -112,14 +114,16 @@ object DataSource {
112114
): Resource[F, DataSource[F, I, A]] = {
113115
type Callback = Either[Throwable, Option[A]] => Unit
114116
for {
115-
queue <- Resource.eval(Queue.unbounded[F, (I, Callback)])
117+
queue <- Resource.eval(Queue.unbounded[F, (I, Callback)])
118+
supervisor <- Supervisor[F]
116119
workerFiber = upToWithin(
117120
queue,
118121
dataSource.maxBatchSize.getOrElse(Int.MaxValue),
119122
delayPerBatch
120-
).flatMap {
121-
case Nil => F.start(F.unit)
122-
case x =>
123+
).flatMap { x =>
124+
if (x.isEmpty) {
125+
supervisor.supervise(F.unit)
126+
} else {
123127
val asMap = x.groupBy(_._1).mapValues(callbacks => callbacks.map(_._2))
124128
val batchResults = dataSource.batch(NonEmptyList.fromListUnsafe(asMap.keys.toList))
125129
val resultsHaveBeenSent = batchResults.map { results =>
@@ -132,7 +136,8 @@ object DataSource {
132136
callbacks.foreach(cb => cb(Left(ex)))
133137
}
134138
}
135-
F.start(fiberWork)
139+
supervisor.supervise(fiberWork)
140+
}
136141
}.foreverM[Unit]
137142
_ <- F.background(workerFiber)
138143
} yield {

0 commit comments

Comments
 (0)