Giter VIP home page Giter VIP logo

Comments (10)

jdegoes avatar jdegoes commented on July 26, 2024 2

@jdegoes If I interpret this idea correctly, due to referential transparency MyConfig would be re-evaluated each time config[MyConfig] is summoned? (For example, re-reading a json or hocon file etc)

Yes, but in most common cases, config will be defined in terms of ZIO.succeed.

The actual loading of the data occurs in the effect returned by Config.make, which will typically occur during startup as the dependencies are wired together.

So it will not be necessary for a user to concern themselves with this; from their perspective, the config data is a constant across their entire application.

Now, the interface allows one to provide a config module backed by "live" data, so it could change; but the default implementation would not do that. In fact, one could make that mandatory by making config: A, although it's not strictly necessary for the above reasons.

from zio-config.

jdegoes avatar jdegoes commented on July 26, 2024 1

Yes that's right, and you can see it will not be reloaded every time you access it.

from zio-config.

leigh-perry avatar leigh-perry commented on July 26, 2024

@jdegoes If I interpret this idea correctly, due to referential transparency MyConfig would be re-evaluated each time config[MyConfig] is summoned? (For example, re-reading a json or hocon file etc)

from zio-config.

afsalthaj avatar afsalthaj commented on July 26, 2024

@jdegoes
Thanks for that. It sounds really good the idea of MyConfig as part of the Environment rather than the ConfigSource. It sounds much more intuitive for the user to consider Config[MyConfig] to be part of the environment everywhere.

As @leigh-perry mentioned, to avoid the re-evaluation, lets say

trait Config[A] {
  def config: A
}

object config {
  def config[A]: ZIO[Config, Nothing, A] = ZIO.accessM(_.config)
}

object Config {
  ...
  def fromEnv[A](configDescriptor: ConfigDescriptor[A]): UIO[Config[A]] =
      envSource.flatMap(sysEnv => read(configDescriptor).provide(sysEnv))
  ...
}

And at the user site:

 import zio.config._

val myApp: ZIO[Config, Nothing, A] =  
 for {
     myConfig <- config[MyConfig]
  } yield (myConfig.port, myConfig.server)
val configDescription: ConfigDescriptor[MyConfig] = 
   (int("PORT") |@| string("SERVER"))(MyConfig.apply, MyConfig.unapply)


Config.fromEnv(configDescription).flatMap(myConfig => myApp.provide(myConfig))

from zio-config.

leigh-perry avatar leigh-perry commented on July 26, 2024

This is part of a real-world app pattern where you want to do some relatively heavyweight setup only once as part of a bootstrap phase, as shown in @afsalthaj 's comment. For example, reading config, creating a Spark session, etc.

The developer needs to be aware that referential transparency can cause constant re-evaluation, so the bootstrap phase is to resolve the program, providing it with those once-only environmental dependencies.

I have a sample app template that prototypes this. The essential part is:

  override def run(args: List[String]): ZIO[Environment, Nothing, Int] =
    for {
      log <- Log.slf4j(prefix = "TESTING")
      r <- resolvedProgram(log).foldM(
        e => log.error(s"Application failed: $e") *> ZIO.succeed(1),
        _ => log.info("Application terminated with no error indication") *> ZIO.succeed(0)
      )
    } yield r

  final case class SomeResult()

  def resolvedProgram(log: Log): ZIO[Any, MainAppError, Unit] =
    for {
      // Config is loaded separately in order to provide to `program`
      cfg <- Bootstrap.ConfigSupport.Live.load.mapError(ConfigLoadError)
      sparkSession <- Bootstrap.SparkSupport.Live.sparkSession("TESTING").mapError(ExceptionEncountered).provide(Blocking.Live)
      resolved <- program.provide(
        new AppRuntime.All(cfg, log, sparkSession) with Blocking.Live {}
      )
    } yield resolved

  def program: ZIO[
    AppRuntime.Config with AppRuntime.Logging with AppRuntime.Spark with Blocking,
    MainAppError,
    Unit
  ] =
    ZIO.accessM {
      env => ...

Any better suggestions are welcome :-)

from zio-config.

afsalthaj avatar afsalthaj commented on July 26, 2024

@jdegoes that’s nice.

To reinforce my understanding,
Config.make is nothing but

read(description).provide(env).map(result => new Config{ override def Config = Zio.succeed(result)}

And user calls at this only in the main.
This means accessing MyConfig by the user anywhere from the environment is accessing a constant value. Isn’t it?

from zio-config.

afsalthaj avatar afsalthaj commented on July 26, 2024

#50

from zio-config.

afsalthaj avatar afsalthaj commented on July 26, 2024

This is resolved (exactly the same pattern) in #72
Thanks John

from zio-config.

afsalthaj avatar afsalthaj commented on July 26, 2024

Reopening, since we can keep this for another round of review during direct-discussion.

from zio-config.

afsalthaj avatar afsalthaj commented on July 26, 2024

This is done!

from zio-config.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.