47erbot on scalafmt-core-3.5.3
47erbot on main
Update scalafmt-core to 3.5.3 (compare)
47erbot on scalafmt-core-3.5.3
Update scalafmt-core to 3.5.3 (compare)
47erbot on main
Update files from `.github` to … (compare)
47erbot on jedis-4.2.3
47erbot on main
Update jedis to 4.2.3 (compare)
47erbot on jedis-4.2.3
Update jedis to 4.2.3 (compare)
47erbot on scalatest-3.2.12
47erbot on main
Update scalatest to 3.2.12 (compare)
47erbot on scalatest-3.2.12
Update scalatest to 3.2.12 (compare)
47erbot on sbt-header-5.7.0
47erbot on main
Update sbt-header to 5.7.0 (compare)
Fetch
instances using Fetch#optional
. It will yield a Fetch[F, Option[A]]
, and won't fail if the identity is missing. Let me know if it helps!
@purrgrammer
scala> import cats.syntax.applicative._
import cats.syntax.applicative._
scala> def fetchProduct[F[_] : ConcurrentEffect]: Fetch[F, (User, User)] =
| (getUser(1), getUser(2)).tupled
<console>:181: error: value tupled is not a member of (fetch.Fetch[F,User], fetch.Fetch[F,User])
(getUser(1), getUser(2)).tupled
^
after copy-pasting everything in http://47deg.github.io/fetch/docs.html#syntax-6-companion-object-0 up to the def getUser
IO[T]
to a Fetch[IO, T]
without defining a Data/DataSource for it? i have certain code that’s un-batchable anyway and it would make a lot of my code more straightforward if i could just lift it right into Fetch
.
def liftT[T](io: IO[T]): Fetch[IO, T] = {
object Lift extends Data[IO[T], T] {
val name = "Lifts an IO[T] to a Fetch[IO, T]"
def source: DataSource[IO, IO[T], T] = new DataSource[IO, IO[T], T] {
override def data = Lift
override def CF: ConcurrentEffect[IO] = ConcurrentEffect[IO]
override def fetch(id: IO[T]): IO[Option[T]] = (
id.map(Some(_))
)
}
}
Fetch(io, Lift.source)
}
is there any way to lift an
IO[T]
to aFetch[IO, T]
without defining a Data/DataSource for it? i have certain code that’s un-batchable anyway and it would make a lot of my code more straightforward if i could just lift it right intoFetch
.
that's something that I hadn't thought about, right now Fetch assumes you'll use a Data/DataSource for performing requests. If i understood correctly, you want a way to lift IO actions to Fetch without an associated Data/DataSource, knowing that those requests can't be optimized?
hey @bijancn, regarding the "happy path", one asumption that Fetch does is that your identities will be there, and will short-circuit when one is missing. However, for optional identities, you can construct
Fetch
instances usingFetch#optional
. It will yield aFetch[F, Option[A]]
, and won't fail if the identity is missing. Let me know if it helps!
Yeah thanks I found that as well at some point and it addresses my problem fully
Fetch
queries or mark them as uncachable
for {
user <- Fetch(userId, UsersById)
organization <- Fetch(organizationId, OrganizationsById.source)
_ <- Fetch.liftIO(addUserToOrganization(user, organization) // This may modify an organization object in the DB
_ <- Fetch.clearCache()
organizationJson <- Fetch(organizationId, OrganizationJsonById.source) // This uses the OrganizationsById DataSource but needs to get a new one, not the cached one!
} yield {
organizationJson
}
right now we're doing something like this:
for {
(user, organization) <- Fetch.run[IO])(Fetch(userId, UsersById), Fetch(organizationId, OrganizationsById.source))
_ <- addUserToOrganization(user, organization) // This may modify an organization object in the DB
organizationJson <- Fetch.run[IO](Fetch(organizationId, OrganizationJsonById.source)) // This uses the OrganizationsById DataSource but needs to get a new one, not the cached one!
} yield {
organizationJson
}
which isn’t too bad, but you can see how this can can get out of hand as we have more and more complex cases
Fetch
over TraceT
cedi-dtrace and running into some constraints like the need of implicit ConcurrentEffect
which seems like might not even be needed according to 47deg/fetch#163TraceT
with some extra implicits but would be awesome to know if it's something that's going to be resolved in foreseeable future