by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • May 31 23:09
    ahoy-jon opened #3737
  • May 31 23:08
    ahoy-jon opened #3736
  • May 31 21:32
    simpadjo opened #3735
  • May 31 19:36
    CLAassistant commented #3734
  • May 31 19:35
    CLAassistant commented #3734
  • May 31 19:35
    CLAassistant commented #3734
  • May 31 19:35
    svroonland review_requested #3734
  • May 31 19:35
    svroonland opened #3734
  • May 31 13:28
    simpadjo commented #3727
  • May 31 11:31
    ajaychandran synchronize #3727
  • May 31 03:48
    scala-steward opened #3733
  • May 30 22:30
    luis3m commented #3732
  • May 30 22:26
    saraiva132 commented #3732
  • May 30 22:25
    saraiva132 commented #3732
  • May 30 22:25
    saraiva132 commented #3732
  • May 30 22:24
    jdegoes commented #3726
  • May 30 22:20
    saraiva132 edited #3732
  • May 30 22:19
    luis3m commented #3732
  • May 30 22:17
    saraiva132 opened #3732
  • May 30 20:45
    adamgfraser commented #3726
Johnnie Walker
@Cereopsis
If it were to require an additional service, say, FooBar then use this (Foobar.live ++ InMemoryAccountRepository.layer) >>> AccountService.live
Luis Martinez
@luis3m
Right, use >>> in case of dependency.
If you need A and B where B depends on A then A >+> B
If you're on an old version then (A >>> B) ++ A)
Johnnie Walker
@Cereopsis
Ooh, I've not used that one yet - new in latest releases isn't it?
Luis Martinez
@luis3m
It was introduced at some point. I assume it's available on RC20
Probably even on RC19-2
Johnnie Walker
@Cereopsis
Yes, must check it out. I want to work out a good system for managing layers without tying oneself in knots. It's a great feature, just trying to work out the intricacies.
Anyway, worth mentioning always that most of the discussions happen on Discord these days!
Luis Martinez
@luis3m
Indeed, this channel is dead contrary to Discord's :)
Debasish Ghosh
@debasishg

@luis3m @Cereopsis The dependency is expressed as follows:

object AccountService {
  trait Service {

    def open(no: String, name: String, rate: Option[BigDecimal], openingDate: Option[Date], 
      accountType: AccountType): UIO[Account]
  }

  val live = ZLayer.fromService[AccountRepository.Service, AccountService.Service] {
    (repo: AccountRepository.Service) =>

    new Service {

      def open(no: String, name: String, rate: Option[BigDecimal], openingDate: Option[Date], 
        accountType: AccountType): UIO[Account] = //..

ok, I can make it >>> ..

  val horizontal: ZLayer[AccountRepository, Nothing, AccountService] = InMemoryAccountRepository.layer >>> AccountService.live

But still program.provideLayer(horizontal).orDie remains the same and I cannot run it. banking.provideSomeLayer[ZEnv](horizontal).orDie does not compile ..

Johnnie Walker
@Cereopsis
Try taking off the ascription - technically speaking you don't have AccountService in that layer it should be Has[AccountService.Service]
Unless you do type AccountService = Has[AccountService.Service]
The type of your horizontal layer should be ZLayer[Any,Nothing,Has[AccountService.Service]]
AccountService.live looks to be: ZLayer[Has[AccountRepository.Service],Nothing,Has[AccountService.Service]]
..and you can shorten those as mentioned by defining the type
John Jimenez
@mayonesa
I'm about to start a considerably-sized enhancement integrating our input/output Spark/Hadoop library w/ a commercially-available encryption library that does not involve:
Asynchronicity,
Concurrency,
Parallelism,
Queueing,
Scheduling, or
Streaming
outside of what Spark and Hadoop do. I want to learn ZIO but I don't want to add ZIO into the mix for that reason alone. Is there value-add to it?
Johnnie Walker
@Cereopsis
What DOES it involve? :-)
If you want to get away from Future, it could serve you. Spark isn't overly pure FP is it?
John Jimenez
@mayonesa
@Cereopsis It involves applying an encryption-UDF to selected DataFrame Columns
@Cereopsis I already did the design and did not discover any Futures in it
Johnnie Walker
@Cereopsis
Yes, so all strictly evaluated?
John Jimenez
@mayonesa
There may be some laziness but nothing all-encompassing
Johnnie Walker
@Cereopsis
...or perhaps lazy but no side-effects at least
John Jimenez
@mayonesa
the side effects are reading the big-data file from HDFS and then writing the selectively-encrypted version back to HDFS
Also, there's a REST call I make to get some meta-data that will guide my encryption actions
Johnnie Walker
@Cereopsis
So I guess you need to work out what's in the guts of that DataFrame => List[Column] => List[EncyptedColumn] => ??? pipeline
John Jimenez
@mayonesa
yes, I've designed it at a UML level
but the implementation will most likely deviate
Debasish Ghosh
@debasishg
@Cereopsis yeah, taking off the ascription I have the type of the horizontal layer as ZLayer[Any,Nothing,Has[AccountService.Service]] and
program.provideLayer(horizontal).orDie has type URIO[Any, Account]. But still I don't get how I can run it.
Johnnie Walker
@Cereopsis
Yes, OK, so ZStream to pull Chunks out of Hadoop map over those and Sink back into Hadoop - a ReST call could be inserted in the middle of that surely.
Runtime.default.unsafeRun(program.provideLayer(horizontal)
Sorry, mixing my metaphors there - that was for @debasishg
John Jimenez
@mayonesa
Thanks, @Cereopsis ! So, if I'm side-effecting, I should consider ZIO
Johnnie Walker
@Cereopsis
It sounds reasonably self contained, I think - and not a massive task unless I'm disregarding some stuff I don't know about :-)
John Jimenez
@mayonesa
@Cereopsis yes, reading and writing piece are pre-existing. The only involvement is the extracting the metadata from different sources, interpreting it, and applying the interpretations to the DataFrame at hand.
i'm thinking since the writing and reading piece are already done, perhaps I will need to wait for another opportunity to adopt ZIO
Debasish Ghosh
@debasishg
Thanks @Cereopsis .. it works .. thanks a lot ..
Johnnie Walker
@Cereopsis
@mayonesa yes, it does sound a bit like it
Particularly if you need to convince the boss 🤪
John Jimenez
@mayonesa
@Cereopsis haha, I'm very blessed to have one of the least micro-managing bosses I've personally known
Johnnie Walker
@Cereopsis
Then, is it a low risk opportunity? Can you wrap your pre-existing read-write ops in ZIO?
Luis Martinez
@luis3m
@debasishg you can also extend zio.App which saves you the unsafeRun part
You just need to provide an URIO[ZEnv, Int] (URIO[ZEnv, ExitCode] in RC20) to the run method
Debasish Ghosh
@debasishg
Thanks @luis3m ..
Debasish Ghosh
@debasishg

One question regarding error handling with ZIO. I am looking at https://zio.dev/docs/overview/overview_handling_errors but till I have some questions regarding the idiomatic practices in ZIO.

When I am using cats or similar frameworks, I usually have something like Kleisli[M, AccountRepository[M], Account] as the return type of functions from the domain service level. This takes an AccountRepository[M] as the environment and returns an M[Account] where I can abstract the errors within M as long as M has an instance of MonadError.

What should be the corresponding type in ZIO ?

I can return a UIO[Either[MyDomainError, Account]] using zio#either but is this idiomatic ? Or is there a better option ? Somehow foldM looks a better option but types don't line up as both the branches of foldM returns the same type while I want to return an error type for the failure branch and a valid domain object for the success branch.

Any help will be appreciated ..

Debasish Ghosh
@debasishg
asked this question on discord ..
Luis Martinez
@luis3m
:+1:
Michal Lacko
@visox

hello fellow devs, after changing zio versions (to higher) i am getting in runtime this ex

[info]   Fiber failed.
[info]   An unchecked error was produced.
[info]   java.lang.ClassCastException: class zio.Reservation cannot be cast to class scala.Tuple2 (zio.Reservation is in unnamed module of loader sbt.internal.LayeredClassLoader @6499adae; scala.Tuple2 is in unnamed module of loader sbt.internal.classpath.ClassLoaderCache$Key$CachedClassLoader @60e48366)
[info]       at zio.ZIO$MapFn.apply(ZIO.scala:3729)
[info]       at zio.ZIO$MapFn.apply(ZIO.scala:3727)
[info]       at zio.internal.FiberContext.evaluateNow(FiberContext.scala:844)
[info]       at zio.internal.FiberContext.$anonfun$evaluateLater$1(FiberContext.scala:712)
[info]       at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[info]       at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[info]       at java.base/java.lang.Thread.run(Thread.java:830)

my zio deps

  val zioV = "1.0.0-RC19-2" //ver depends on zio-nio
  val zioConfigV = "1.0.0-RC18"
  val zioNioV = "1.0.0-RC7"
  val http4sV = "0.21.4"
  val doobieV = "0.9.0"
  val flywayV = "6.4.3"
  val Log4j2V = "2.13.3"
  val slinkyV = "0.6.5"

  lazy val zioDeps = Seq(
    "dev.zio" %% "zio" % zioV,
    "dev.zio" %% "zio-streams" % zioV,
    "dev.zio" %% "zio-interop-cats"    % "2.0.0.0-RC13",
    "dev.zio" %% "zio-config" % zioConfigV,
    "dev.zio" %% "zio-config-magnolia" % zioConfigV,
    "dev.zio" %% "zio-config-typesafe" % zioConfigV,
    "dev.zio" %% "zio-nio" % zioNioV,
  )

it all did work with a bit older zio version

i tried to make the versions line-up based on what latest zio-nio needed