Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jun 13 16:54
    mergify[bot] labeled #5199
  • Jun 13 16:53
    scala-steward opened #5199
  • Jun 13 16:45

    adamgfraser on 2.x

    fix publishing (#5198) (compare)

  • Jun 13 16:45
    adamgfraser closed #5198
  • Jun 13 16:26
    adamgfraser review_requested #5198
  • Jun 13 16:26
    adamgfraser opened #5198
  • Jun 13 15:12

    adamgfraser on 2.x

    Update Documentation On Series … (compare)

  • Jun 13 15:12
    adamgfraser closed #5197
  • Jun 13 14:13
    adamgfraser synchronize #5197
  • Jun 13 13:45
    adamgfraser opened #5197
  • Jun 13 12:09
    khajavi synchronize #5102
  • Jun 13 07:03
    khajavi synchronize #5102
  • Jun 12 20:40

    renovate[bot] on net.alchim31.maven-scala-maven-plugin-4.x

    (compare)

  • Jun 12 20:40

    renovate[bot] on master

    chore(deps): update dependency … (compare)

  • Jun 12 20:40
    renovate[bot] closed #5196
  • Jun 12 19:33
    renovate[bot] labeled #5196
  • Jun 12 19:33
    renovate[bot] opened #5196
  • Jun 12 19:33

    renovate[bot] on net.alchim31.maven-scala-maven-plugin-4.x

    chore(deps): update dependency … (compare)

  • Jun 12 16:10

    adamgfraser on 2.x

    Update zio.version to v1.0.8 (#… Update nyaya-gen to 0.10.0 (#51… Update silencer-lib, silencer-l… and 45 more (compare)

  • Jun 12 14:59

    adamgfraser on master

    Show all failures in the presen… (compare)

toxicafunk
@toxicafunk:matrix.org
[m]
https://github.com/ollls/zio-tls-http is not bad either, but not as battle-tested as http4s
Ashkan Kh. Nazary
@ashkann

Hi everyone. Thank you all for the amazing work. I have a question regarding timeout + blocking calls :

           Runtime.default
                    .unsafeRun(zio.blocking.blocking(healthy.transact(transactor)).timeout(3.seconds).either)

I have tried every combination that I could think of but I can't make the zio.blocking.blocking(healthy.transact(transactor)) to timout after 3 seconds (it just blocks indefinitely) ... what is it I'm missing ?

healthy is a query to check database connection and rest is standard doobie. I know this is blocking so I passed it to blocking in the hope to get a ZIO value out that could be then normally combined with a timeout ... apparently not :D
toxicafunk
@toxicafunk:matrix.org
[m]
hi @ashkann, please note most everyone has moved over to discord (link in the subject)
u'll get a lot more help there
blocking is just for making sure your code runs on the blocking threadpool, how long do u think healthy.transact(transactor) should take?
Ashkan Kh. Nazary
@ashkann
thank you @toxicafunk:matrix.org , reposteed on discord
Maatary
@Maatary
Hi All, quick question. I'm learning about different monad in the classic book "Functional programing in Scala" and stumble upon the ST Monad which i find interesting. To my suprise tho, it seems like the scala eco sys does not support it. Neither Cats (confirmed) or Zio as far i looked into the api. Hence questions (1) do ZIO indeed do not provide an implementation of the ST Monad, and if so out of curiosity if it is possible to answer, Why ? Is the alternative for someone doing impure (mutating) code to simply wrap it in an IO Monad and that is the scala approach ?
toxicafunk
@toxicafunk:matrix.org
[m]
hi @Maatary , first of all please do notice we have migrated to dscord (link on the channel's subject) so I suggest you join and reask your question there
in regards to your question, ZIO does not provide Monad implementations, but rather ZIO is a Monad
combined with a typed error channel and a built in reader monad
so ZIO is a different take on how to do FP in Scala
while Cats and Scalaz more or less copy/follow haskell's take on FP, ZIO tries to do FP in an more ergonomic/natural Scala
Maatary
@Maatary
Understood thanks
Maatary
@Maatary
Will do a slight modification to take into account your input @toxicafunk:matrix.org
objektwerks
@objektwerks
objektwerks @objektwerks 19:23
Warning to discord zio dev - the discord login/claim-account insanity has and will continue to turn away prospective zio users.
nafg
@nafg
What are you referring to?
toxicafunk
@toxicafunk:matrix.org
[m]
i guess @objektwerks doesn't want to create a discord account
objektwerks
@objektwerks
@nafg @toxicfunk Sorry I lost my cool last night. I do have a discord account. It's just that Discord tends to forget that simple fact, making zio-discord inaccessible and/or unusable.
toxicafunk
@toxicafunk:matrix.org
[m]
@obj
@objektwerks: no worries, I'm no stranger to discord's amnesia. Unfortunately the ZIO account was created at a time when Giteer was unsuable (before it got integrated with matrix) and after exploring different options discord was the most convenient for the community at the moment
I know @softinio has experimented with a bridge btw gitter and discord but its not without issues
Jeff May
@jeffmay
I'm trying to write a CSV parser in ZIO. I want to read the first row of the file and then read the remaining rows into a ZStream... I'm running into an issue where it reads the header row, then the first 16 lines, and then crashes with:
Fiber failed.
An unchecked error was produced.
zio.csv.ParsingException: Parsing failed due to exception: java.nio.channels.ClosedChannelException
Caused by: java.nio.channels.ClosedChannelException
    at java.base/sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:150)
    at java.base/sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:209)
    at zio.stream.ZStreamPlatformSpecificConstructors.$anonfun$fromFile$14(platform.scala:225)
    at scala.runtime.java8.JFunction0$mcI$sp.apply(JFunction0$mcI$sp.scala:17)
    at zio.blocking.package$Blocking$Service.$anonfun$effectBlockingInterrupt$5(package.scala:126)
    at zio.ZIO$.$anonfun$effectSuspend$1(ZIO.scala:2678)

The basic code I'm using is:

    val readHeader = rows.peel(ZSink.head[Row]).map { case (maybeHead, tail) ⇒
      maybeHead.map { firstRow ⇒
        val header = HeaderCtx.fromRow(firstRow)
        (header, tail)
      }
    }
    val readAll = readHeader.flatMap {
      case Some((header, dataRows)) ⇒
        println(s"HEADER = ${header.columns}")
        ZManaged.succeedNow {
          dataRows.mapM { row ⇒
            val env = Has.allOf(header, row.rowContext)
            println(s"LINE ${row.rowIndex}: ${row.cells}")
            decoder.decode(row).provide(env).map { record ⇒
              println(s"Parsed Record: $record")
              record
            }
          }
        }
      case NoneZManaged.succeedNow(ZStream.empty)
    }
    ZStream.fromEffect(readAll.useNow).flatten

Where the RowDecoder[Has[HeaderCtx], A].decode() returns a ZIO[Has[HeaderCtx], RowDecodingFailure, A]

Jeff May
@jeffmay
I see the header is parsed correctly, and then I see LINE 1 through LINE 16 before the crash
I'm running this stream with:
    decodeRecords.run {
      ZSink.foldLeft(ImportResults()) {
        case (res, record) ⇒
          res.recordSuccess(record)
      }
    }.orDie
and then printing the count
the CsvParser that produces the ZManaged looks like:
object CsvParser {

  def fromFile(
    path: Path,
    format: CSVFormat,
  ): ZStream[Blocking, ReadingFailure, Row] = {
    val parser = new CSVParser(format)
    ZStream.fromFile(path)
      .transduce(ZTransducer.utf8Decode >>> ZTransducer.splitLines)
      .refineOrDie {
        case NonFatal(ex) ⇒ ParsingException(ex)
      }
      .zipWithIndex
      .mapM { case (line, index) ⇒
        ZIO.fromEither {
          parser.parseLine(line).map(Row(index, _)).toRight {
            RowInvalidSyntax(index, s"Malformed Input: $line", None)
          }
        }
      }
  }
}
Jeff May
@jeffmay
the project for this is at https://github.com/jeffmay/dsa-members
Jeff May
@jeffmay
ok, I figured it out... I needed to use ZStream.managed() on the result of mapping the header and remaining rows into a ZManaged[R, E, ZStream[R, E, A]] to get a ZStream[R, E, ZStream[R, E, A]] and then .flatten it.
    val rows = CsvParser.fromFile("example.csv")
    val readHeaderThenAllRows = CsvDecoder.readHeaderInfo(rows).map {
      case Some((header, dataRows)) ⇒
        dataRows.mapM { row ⇒
          val env = Has.allOf(header, row.rowContext)
          decoder.decode(row).provide(env)
        }
      case NoneZStream.empty
    }
    // flatten the ZManaged ZStream into a single ZStream
    val decodeRecords = ZStream.managed(readHeaderThenAllRows).flatten
    decodeRecords.run {
      ZSink.foldLeft(ImportResults()) {
        case (res, record) ⇒
          res.recordSuccess(record)
      }
    }.orDie
My issue was using .useNow instead of ZStream.managed to unwrap the ZManaged into a ZStream
brinklec
@brinklec

Hello, I'm a senior architect very new to ZIO, still only advanced intermediate level in Scala, but passionate about the idea of purely functional programming. I have a large doobie project creating a purely functional replacement for a very large imperative API over a complex engineering RDBMS application.

In my doobie API, there is a pain point I'm in doubt whether ZIO could somehow help with. The old imperative API had many interface calls that could each result in any of multiple patterns/sequences of "cascade" calls for detailed operations, depending on data-driven conditional logic. In doobie, each distinct pattern of cascade operations results in a different monadic return type that requires its own for-comprehension, and the API calls themselves have to return complex, manually defined algebraic data types encapsulating all the possible cases.

My understanding has been that this is an inherent limitation of for-comprehension syntax with monadic datatypes, with no workaround. But ZIO has apparently been defying a lot of conventional wisdom, so I thought it was worth asking. It's far from my only reason for interest, but relates to current pain.

Luis Martinez
@luis3m
@brinklec hi, you're better off asking on ZIO Discord. This channel is dead. However unfortunately ZIO can't escape this monadic limitation. Hope I understood your pain point correctly but anyway it's probably worth asking on Discord anyway as I'm not familiar enough with doobie.
esmailzadeh
@mz_esmailzadeh_twitter
@ashkann how are you doing ashkan:D?! go to discord that is a much more active community there
nafg
@nafg
Is there a straightforward and safe way to go back and forth between a concrete cats-effect IO and a ZIO?
toxicafunk
@toxicafunk:matrix.org
[m]
@nafg: please ask in discord instead, that's where everyone is :)
nafg
@nafg
I did already. Thanks
Alessandro D'Armiento
@adarmiento
Good morning everyone. I just started using ZIO.
Sorry this question will sound stupid, but it's taking me a couple o days trying to understand what does not work. Your help would be appreciated
I am trying to use the ZLayer pattern
with Vertical Composition
So i created two services (please don't mind the quality, I just wanted to see how one service can refer to another):
object SampleModule {

  type SampleModuleEnv = Has[SampleModule.Service]

  trait Service {
    def greetings(name: String): Task[Unit]
  }

  val live: ZLayer[Any, Nothing, SampleModuleEnv] = ZLayer.succeed((name: String) => Task(println("Greetings " + name)))

  def greetings(name: String): ZIO[SampleModuleEnv, Throwable, Unit] = ZIO.accessM(_.get.greetings(name))
}


object SampleDependencyModule {
  type SampleDependencyModuleEnv = Has[SampleDependencyModule.Service]

  class Service(sample: SampleModule.Service) {
    def dependency(name: String): Task[Unit] = {
      sample.greetings(name)
    }
  }

  val live: ZLayer[SampleModuleEnv, Nothing, SampleDependencyModuleEnv] =
    ZLayer.fromService[SampleModule.Service, SampleDependencyModule.Service](sample => new SampleDependencyModule.Service(sample))

  val sampleDependencyLayer: ZLayer[Any, Nothing, SampleDependencyModuleEnv] = SampleModule.live >>> SampleDependencyModule.live

  def dependency(name: String): ZIO[SampleDependencyModuleEnv, Nothing, Unit] = ZIO.accessM(_.get.dependency(name))

}
Alessandro D'Armiento
@adarmiento
In my run for comprehension I was expecting to be able to provide the composite layer this way
object Launcher extends zio.App {

  val sampleCompositeLayer:  ZLayer[Any, Nothing, SampleDependencyModuleEnv] = SampleModule.live >>> SampleDependencyModule.live

  override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = {
    val logic: ZIO[ZEnv  with SampleModuleEnv with SampleDependencyModuleEnv , Nothing, ExitCode] = (for {
      name <- putStrLn("Name: ") *> getStrLn
      _ <- SampleDependencyModule.dependency(name)
    } yield ()).exitCode

    logic.provideCustomLayer(sampleCompositeLayer)
  }
}
But I keep receiving this error, which I think it means I am missing some layer somewhere
Error:(19, 29) Cannot prove that zio.ZEnv with test.zio.layer.SampleDependencyModule.SampleDependencyModuleEnv <:< zio.ZEnv with prova.zio.layer.SampleModule.SampleModuleEnv with prova.zio.layer.SampleDependencyModule.SampleDependencyModuleEnv.
    logic.provideCustomLayer(sampleCompositeLayer)
Alessandro D'Armiento
@adarmiento
And I don't really understand what's missing
Any advice?
I was also looking for tutorials online about the ZLayer pattern, but I couldn't find an (updated) one in which it uses vertical composition along with for comprehension in the run method
Luis Martinez
@luis3m
@adarmiento have you tried >+> instead of >>>?
Alessandro D'Armiento
@adarmiento
No I did not. And now seems to be work. At least my sample project Ahaha
Thank you! I knew it was something very stupid. I will go to search the difference between the different composition operators. Seems still quite clumsy to me
Luis Martinez
@luis3m
You're welcome :)
EeshanBembi
@EeshanBembi
What are the best resources to get started with zio?
Luis Martinez
@luis3m
@EeshanBembi maybe https://www.zionomicon.com/ but I'd suggest to ask on Discord for better answers given that the community moved there a while ago