Add F[_] type parameter to DataSource - #171
Conversation
| q.query[Author].list | ||
| } | ||
| def transactor[F[_]: ConcurrentEffect]: F[Transactor[F]] = | ||
| for { |
There was a problem hiding this comment.
| for { | |
| createTransactor.flatTap(_.trans(dropTable *> createTable *> authors.traverse(addAuthor) ) |
The flatTap allows you to tee and use the output for a side-effectful computation.
There was a problem hiding this comment.
I tried it but I got a type mismatch between doobie.h2.H2Transactor and doobie.Transactor.
| * identity wasn't found, it won't appear in the keys. | ||
| */ | ||
| def batch[F[_] : ConcurrentEffect](ids: NonEmptyList[I]): F[Map[I, A]] = | ||
| def batch(ids: NonEmptyList[I])(implicit C: ConcurrentEffect[F]): F[Map[I, A]] = |
There was a problem hiding this comment.
So, one problem with using implicit parameters is that you can not override them or remove them from a method in the subclass: the subclasses must keep a similar signature to the parent.
We could leave here no implementation, or add one that only used an Applicative constraint (to use with List.traverse), and then move the implementation using ConcurrentEffect to a different mix-in trait.
trait ConcurrentBatch[F[_]] extends DataSource[F] {
implicit protected ConcF: ConcurrentEffect[F]
def batch(ids: NonEmptyList[I]): F[Map[I, A]] = /****/
}This would allow you to decouple the tests from the ConcurrentEffect type class.
There was a problem hiding this comment.
The ConcurrentEffect type class is something we can't escape from since it'll be required by Fetch when running or creating fetches. Having the implicit ConcurrentEffect in scope is something that you want when defining data fetches, since very few of those will require only Applicative.
Remember that Fetch is a library for reordering and optimizing IO, in particular reading data. In practice, you will be using the ConcurrentEffect API to express resource allocation, asynchronous effects and lifting IO computations to F so I think it's fine.
f11f027 to
d0330b6
Compare
Codecov Report
@@ Coverage Diff @@
## master #171 +/- ##
==========================================
+ Coverage 95.2% 96.55% +1.34%
==========================================
Files 6 6
Lines 167 174 +7
Branches 7 4 -3
==========================================
+ Hits 159 168 +9
+ Misses 8 6 -2
Continue to review full report at Codecov.
|
Codecov Report
@@ Coverage Diff @@
## master #171 +/- ##
==========================================
+ Coverage 95.2% 96.57% +1.36%
==========================================
Files 6 6
Lines 167 175 +8
Branches 7 6 -1
==========================================
+ Hits 159 169 +10
+ Misses 8 6 -2
Continue to review full report at Codecov.
|
In the old version of Fetch, one needed to define the data source as an
implicit object. This way, we ensured that each DataSource had only one instance using reference equality.
A data source used to look like the following:
```scala
implicit object Users extends DataSource[UserId, User]{
// ...
}
```
Now that we've introduced an `F[_]` type parameter in `DataSource` we no
longer can define it as an `object`. Thus, we need a way to identify
requests to a data source to be able to perform optimizations.
Now there's a new trait called `Data`, that identifies requests for a
particular piece of data, and is used to identify and group requests for
the same data.
A `Data` definition looks like the following:
```scala
object Users extends Data[Int, User] {
def name = "Users"
}
```
Then, when defining the data source for users, we have to specify which
`Data` the `DataSource` is fetching:
```scala
def usersSource[F[_]]: DataSource[F, Int, User] = new DataSource[F, Int,
User] {
def data = Users
// ...
}
```
Now that we have `Data` and `DataSource` we can create a `Fetch` por a `User`:
```scala
def fetchUser(id: Int): Fetch[F, User] =
Fetch(id, usersSource)
```
See the `examples` directory and the tests for plenty of examples.
59a45b8 to
4e0f1c6
Compare
| val combined = acc.get(dsId).fold( | ||
| (ds, blocked) | ||
| )({ | ||
| case (ds, req) => { |
There was a problem hiding this comment.
The ds variable here shadows the one from line 136. Should they always be the same?
There was a problem hiding this comment.
In that case, perhaps we should use back-quotes? As it is right now, the second ds is a completely different variable, that just happens to have the same name.
|
@purrgrammer can you open an issue on Kollect to replicate this in case it makes sense? |
Add F[_] type parameter to DataSource
In the old version of Fetch, one needed to define the data source as an
implicit object. This way, we ensured that each DataSource had only one instance using reference equality.
A data source used to look like the following:
Now that we've introduced an
F[_]type parameter inDataSourcewe nolonger can define it as an
object. Thus, we need a way to identifyrequests to a data source to be able to perform optimizations.
Now there's a new trait called
Data, that identifies requests for aparticular piece of data, and is used to identify and group requests for
the same data.
A
Datadefinition looks like the following:Then, when defining the data source for users, we have to specify which
DatatheDataSourceis fetching:Now that we have
DataandDataSourcewe can create aFetchpor aUser:See the
examplesdirectory and the tests for plenty of examples.