Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
Repo info
  • Sep 05 2019 14:43
    @typelevel-bot banned @jdegoes
  • Jan 31 2019 21:17
    codecov-io commented #484
  • Jan 31 2019 21:08
    scala-steward opened #484
  • Jan 31 2019 18:19
    andywhite37 commented #189
  • Jan 31 2019 02:41
    kamilongus starred typelevel/cats-effect
  • Jan 30 2019 00:01
    codecov-io commented #483
  • Jan 29 2019 23:51
    deniszjukow opened #483
  • Jan 29 2019 23:37
  • Jan 29 2019 23:22
  • Jan 29 2019 20:26
    Rui-L starred typelevel/cats-effect
  • Jan 29 2019 18:01
    jdegoes commented #480
  • Jan 29 2019 17:04
    thomaav starred typelevel/cats-effect
  • Jan 28 2019 17:43
    asachdeva starred typelevel/cats-effect
  • Jan 28 2019 07:12
    alexandru commented #480
  • Jan 28 2019 05:45
    codecov-io commented #482
  • Jan 28 2019 05:35
    daron666 opened #482
  • Jan 27 2019 13:56
    codecov-io commented #481
  • Jan 27 2019 13:46
    lrodero opened #481
  • Jan 27 2019 05:47
    codecov-io commented #460
  • Jan 27 2019 05:37
    codecov-io commented #460
Daniel Spiewak
where that IO is defined by IO.never with an onCancel that allows you to call things
it's slightly janky, but interrupting synchronous things is most definitely not intended to be a primary use-case
you can't do it reliably, and it's relatively rare that an upstream library defines a deterministic way of doing so without also being asynchronous
@Avasil Trick with guaranteeCase worked. Thanks! Also I didn't realize that value returned from IO on which I call .bracketCase is sort of seed value. Generally I feel like whole thing is much more complicated than it should be. At least compared to zio.
Piotr Gawryś
ZIO works the same way in this regard. The main purpose of bracket is safe acquisition and release of resources, e.g. file handle or database connection. You have (acquire)(use)(release). Neither acquire nor release can be cancelable because we could end up with corrupted state or leak resources
Gavin Bisesi
it's pretty clear that zio has to work the same way because you can use ZIO with cats-effect Bracket
Is there any kind of (fa: F[A]).recoverSomeT[E2]( e: E => ???: E2 ) => EitherT[F, E2, A]
John A. De Goes
@unoexperto Easy-peasy.
ZIO.uninterruptible {
  for {
    statement <- createStatement(query)
    fiber     <- ZIO.interruptible(executeStatement(statement).fork)
    results   <- fiber.join.onInterrupt(cancelStatement(statement)).ensuring {
  } yield results
Be sure to surround the blocking bits by blocking { ... }.
Ross A. Baker
v2.0.0-RC1 is here: notes, tweet
Gavin Bisesi
lovely, somehow I deadlocked my IOApp with a lazy val on a parent trait :|
Daniel Spiewak
@Daenyth yeaaaaaah… the curse of lazy val
Ryan Peters
@djspiewak @Daenyth I'm curious - can you elaborate? Does it have to do with how the laziness from IO/etc is different from the nature of lazy val being more of a memoized def?
Daniel Spiewak
it's unfortunately more than a memoized def
it's an exactly-once memoized def with support for concurrent access
that implies two things
first, accessing one is a memory barrier, even if it's already been evaluated
second, there's a lock wrapped up inside it which covers the evaluation
Ryan Peters
Well, heck. Good to keep in mind.
Daniel Spiewak
yeah they're kind of terrible
what I really want is a "deferred evaluation" lazy val
Paul Phillips, ages and ages ago, proposed adding an annotation for this
I would absolutely love that as a feature, but it never made it
Ross A. Baker
Runar has a library with various lazy semantics. I don't think I'd take it as a dependency, but it's interesting reading on the tradeoffs. There's an SIP out there, too.
Daniel Spiewak
yeah it's a fun little library
there are some gotchas to it though
Ryan Peters
It sounds like in most cases where I'd want a lazy val I'd be better off structuring my app around Deferred instead.
Daniel Spiewak
in many cases, yes
the few times I use lazy val intentionally these days are when constructing infinite recursive effects
I could just use def instead but it cuts down on the allocations
Ryan Zeigler
Related to the concurrent structures. Is there a use case that MVar really excels at. Every time I reach for it, I pause and then find a different primitive fits better for what I want
Daniel Spiewak
MVar doesn't work well for much of anything. It kind of conflates two concerns in this rather odd way
I've seen people use it as a singleton semaphore for tests
but even that seemed a bit less useful than… Semaphore
Piotr Gawryś
Maybe some producer-consumer scenarios but there is also just 1-element async queue
Fabio Labella
@rzeigler I reached the same conclusion, which then led me to design Ref + Deferred the way they are, to avoid conflating concurrent state and synchronisation
Guys, I've asked few questions about fiber cancelation yesterday and look like release handler of IO.bracketCase() is called in the same thread I'm executing IO with. For me it means if IO contains blocking operation I can't really cancel it. Is there a way to overcome it ?
Dan Di Spaltro
@rzeigler I was thinking like token refreshes on some client side api
Ryan Zeigler
ah, like it has expired so don't use it until we insert a new one that can be consumed?
Oleg Pyzhcov
@unoexperto in case of cancellation, finalizer call originates on thread that triggers cancellation.
Gavin Bisesi
So far we've bit ourselves multiple times by having failures preventing our IOApp from coming up. Does anyone have a pattern or example of some kind of automated testing? Maybe some kind of scalatest src/it magic that can launch an IOApp main process into a separate jvm or something and perform some kind of health check -> sigterm ?
Ross A. Baker
What is "not coming up"? Not working and not exiting?
Gavin Bisesi
Latest example was a deadlock on a lazy val on the object which was trying to lzyCompute$ from inside an IO
but I also have hit classpath issues which got masked by the "doesn't exit jvm when not NonFatal" bug
Ross A. Baker
I don't know how we'd implement a universal health check. There isn't really a life cycle beyond List[String] => IO[ExitCode].
Gavin Bisesi
Well, the deadlock didn't respond to SIGTERM :)
If I could get "launch jvm with main, capture stdout + exitcode" that would be enough to see whether it crashed or locked
and I could have it emit a positive message to stdout once successfully initialized, and check for that with if I had the output
Rohde Fischer

I'm trying to make a very simple looping function with a delay using CATS effects (2.0.0-RC1 due to Scala 13).

import cats.effect._

import scala.concurrent.duration.FiniteDuration

object TaskScheduler {
  def loop[F[_] : Sync](delay: FiniteDuration, fun: () => F[Unit])
      (implicit timer: Timer[F]): F[Unit] =
    for {
      _ <- timer.sleep(delay)
      _ <- fun()
      _ <- loop(delay, fun)
    } yield ()

however, when I try to compile this I get:

sbt:root> tickets/compile
[info] Compiling 15 Scala sources to /home/rohdef/git/smart-tickets/tickets/target/scala-2.13/classes ...
[error] /home/rohdef/git/smart-tickets/tickets/src/main/scala/dk/rohdef/scheduler/TaskScheduler.scala:11:23: value flatMap is not a member of type parameter F[Unit]
[error]       _ <- timer.sleep(delay)
[error]                       ^
[error] /home/rohdef/git/smart-tickets/tickets/src/main/scala/dk/rohdef/scheduler/TaskScheduler.scala:12:15: value flatMap is not a member of type parameter F[Unit]
[error]       _ <- fun()
[error]               ^
[error] /home/rohdef/git/smart-tickets/tickets/src/main/scala/dk/rohdef/scheduler/TaskScheduler.scala:13:16: value map is not a member of type parameter F[Unit]
[error]       _ <- loop(delay, fun)
[error]                ^
[error] three errors found
[error] (tickets / Compile / compileIncremental) Compilation failed
[error] Total time: 2 s, completed Aug 10, 2019 1:23:20 PM

which puzzles me thoroughly, since Sync is a Monad as far as I can see, so both map and flatMap should be present to my knowledge. So, what am I doing wrong?