Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • 15:07
    pshirshov ready_for_review #1444
  • 15:07
    pshirshov synchronize #1444
  • 15:06
    pshirshov synchronize #1444
  • 14:56
    pshirshov closed #1438
  • 14:56
    pshirshov commented #1438
  • 14:56
    pshirshov edited #1438
  • 14:56
    pshirshov edited #1444
  • 14:52
    pshirshov synchronize #1444
  • 14:18
    pshirshov synchronize #1444
  • Apr 13 19:46
    pshirshov synchronize #1444
  • Apr 13 19:32
    pshirshov synchronize #1444
  • Apr 13 18:54
    pshirshov synchronize #1444
  • Apr 13 17:50
    pshirshov synchronize #1444
  • Apr 13 15:31
    pshirshov synchronize #1444
  • Apr 13 15:17
    pshirshov review_requested #1444
  • Apr 13 15:17
    pshirshov review_requested #1444
  • Apr 13 15:17
    pshirshov opened #1444
  • Apr 13 15:17
    pshirshov review_requested #1444
  • Apr 12 14:22
    VladPodilnyk review_requested #1422
  • Apr 12 06:02
    scala-steward review_requested #1443
Kai
@neko-kai
@Edvin-san Applying a function like this worked for me with your example above:
  def interruptibleZManaged[R, E, A](zmanaged: ZManaged[R, E, A]): ZManaged[R, E, A] =
    ZManaged(zmanaged.zio.interruptible)
Hmm, maybe Lifecycle.fromZIO can include this as a workaround... (Although, this is reproducible in plain Lifecycle and cats Resource too, as long as ZIO fork is used, so maybe no)
Edvin Lundberg
@Edvin-san
@neko-kai Nice, thank you! That was exactly the workaround I was looking for. I added a comment for future readers.
This feels like a gotcha in zio, because I suppose it is quite common to use forkManaged.
Edvin Lundberg
@Edvin-san

Hi! I'm trying to improve the logging in my project and make LogStage work with GCL structured logging.
Right now, my log is setup like this:

make[LogIO2[IO]].from(LogIO2.fromLogger[IO] _)

I'm also using distage-extension-config and have in my application.conf

logger {
  levels {
    ...
  }
  json = false
}

1) Is there any docs about this special config that seems to affect the logging?

If is set json = true I do get json output. However, to make it work with GCL I would need to change the json a bit.
For example, in the logstage json there is meta.level: "debug" and GCL needs severity: "DEBUG".
2) How can I configure the json output?

Edvin Lundberg
@Edvin-san

Hmm my current guess is to write my own RenderingPolicy, similar to LogstageCirceRenderingPolicy and do something like this:

make[LogIO2[IO]].from(LogIO2.fromLogger[IO](IzLogger(sink = ConsoleSink(MyGCLRenderingPolicy))))

Still don't understand the config stuff though.

Edvin Lundberg
@Edvin-san
Update: Extending LogstageCirceRenderingPolicy seems like the correct solution. It is quite nice. Also need to make sure other stuff gets routed through my logger.
The loggerconfig is still somewhat of a mystery to me, and how to make sure my logger is used by distage (some other loggers defined in LogAppBootModule).
Kai
@neko-kai

@Edvin-san
There's no documentation for that config, but the case class being read is the following SimpleLoggerConfigurator.SinksConfig (example usage) and the component responsible for reading the config is the SimpleLoggerConfigurator there.

and how to make sure my logger is used by distage (some other loggers defined in LogAppBootModule).

You may override make[IzLogger] instead of LogIO2 - this will affect the LogIO1/2 etc. automatically since they depend on IzLogger themselves. User bindings override any default / builtin modules, so no additional steps are required beyond just defining a component in your own plugins.

The loggerconfig is still somewhat of a mystery to me

Yeah, it's a function that got somewhat forgotten, it does need to be documented and untied from distage in the future (so that users of logstage-core-only can use it too)

Kai
@neko-kai
Also, if you don't mind contributing your GCL policy sometime in the future that might help others who try to use LogStage with GCL.
Edvin Lundberg
@Edvin-san
@neko-kai Thanks for clearing that up for me. I might contribute the GCL policy, although it is still quite rudimentary.
Kai
@neko-kai
:+1:
Edvin Lundberg
@Edvin-san
Hi! I think I may have a problem with resources not being cleaned up. When my app receives SIGTERM it starts shutting down (I can see AppShutdownStrategy "Going to shut down..." in logs).
I can also see http4s PoolManager "Shutting down connection pool". But then it just sits there. Do you have any recommendation on how to debug this in distage? Can I see which resource is causing the problem?
Kai
@neko-kai
@Edvin-san
There's nothing specific added to distage to help debug finalization, unfortunately. You may try using a debugger to track it or try adding log messages to release parts of resources to try to track down which finalizer is the last one that launches before freezing.
@Edvin-san
One thing that could help is placing a breakpoint on this line or adjacent. finalizers contains all the finalizers in order and f variable may contain some information about the finalizer, like type name, so you could possibly track which one is the last by resuming at this breakpoint.
Edvin Lundberg
@Edvin-san
Hmm I haven't been able to identify it completely using your suggested methods. Tricky problem.
Kai
@neko-kai
You may also try to check thread dumps (jstack <process-pid> or intellij debugger's dump threads button) – if the hang is on blocking IO / or otherwise in synchronous chunks you'll see the hanging thread stack there
Kai
@neko-kai
If the hang is in asynchronous code, you won't see much in thread dump, just a lot of parked threads – this may indeed be very tricky to debug. I've sometimes had to inspect heap dumps looking for unfilled promises or stuck fibers to figure out a hang – if you're using ZIO each fiber (zio.internal.FiberContext) has a synthetic stacktrace that is accessible from the heap that can tell the history of computations – there's also a zio.Fiber.dump function and zio-zmx project that is supposed to provide an ability to dump global fiber state more easily.
Edvin Lundberg
@Edvin-san
Ok, unfortunately it looks like a lot of parked threads. I'm using ZIO and may investigate the fiber dumps in more detail later.
hughsimpson
@hughsimpson
Hey. Struggling a little with a requirement I have from this beautiful little project. I need the runtime to know the difference between a type PositiveInt <: Int and an Int, and it all works fine in Scala 2.13. Looking towards the dotty future, I've tried to make a pr that 'works' for my use case in Scala3 but I'm a bit lost in the inheritance macros. Can someone help me out a little plz?
To be clear: I can't see any behavioural issues in the tests, but there's a significant difference between the inheritance types in Scala 2 Vs scala 3 and I don't know what that means, or if it's even important
hughsimpson
@hughsimpson
I strongly suspect it doesn't matter, but I can't explain why. All I know is that it's not breaking the most obvious use cases or existing tests - although given the nascent state of this lib in the context of scala 3, that no indication that I haven't borked things. I've published it locally for now, but would be much more comfortable if it were supported...
Kai
@neko-kai
@hughsimpson Hi! Sorry for holding you up, I was hoping to make some time to review your PR properly again and provide more pointers, but I'll probably won't be able to in a realistic timeframe... I think you're right, minor differences in encoding aren't going to matter unless they demonstrably break something – and at this point the dotty version is somewhat broken anyway and you use it at your risk etc etc, so I think I'll go ahead and release your fix later today. Thank you for contributing!
hughsimpson
@hughsimpson
Thanks!
Damian Reeves
@DamianReeves
Hey I’ve got a question on izumi reflect which I’m usinhg in ZIO
I’m trying to find the easiest way to make a custom Has type in ZIO and I have this:
object data {
  type Data[A] = Has[DataValue[A]]  
final case class DataValue[A](value: A)
  object Data {
    def apply[A: Tag](value: A): Data[A] = Has(DataValue(value))
    def get[R,A]:(f:R => A):A = ???
}
I’m wondering how can I implement get such that it work’s like Has’ get but only for “Data”…. If I should ask this in ZIO let me know… Adam suggested trying here
Didac
@umbreak

Is there a way I can do the following wiring:
A have an interface A that is implemented in several places and wired as follows

many[A].add(...)

Then in 2 places I depend on the aggregate of them:

many[B].from((aSet: Set[A]) => new B(aSet))

// Here I do not depend on all As, but only on a subset of them
many[C].from((aSubset: Set[A]) => new B(aSubset))

Is there a way (maybe tagged) when building the many[A] to add some sort of tag/group to it and then to fetch the dependency (aSubset: Set[A]) from that tag/group ?

I know I could subclass A and just do it inside the from method. But let’s say that’s not possible in my setup
Kai
@neko-kai
@umbreak You may build two sets - one full set and a subset using exact same values - like this:
// build subset
many[A].named("subset").add(...)
// add subset to full set
many[A].refSet[A]("subset")

// use full set
many[B].from((aSet: Set[A]) => new B(aSet))

// use subset
many[C].from((aSubset: Set[A] @Id("subset") => new B(aSubset))
You may add a smaller set to a bigger set using addSet/refSet/weakSet methods, even though you cannot extract a smaller set from a bigger set (other than directly at value level like make[Set[B]].from((_: Set[A]).collect { case b: B => b}))
Kai
@neko-kai
You can use tagged to mark elements that should be in the set at different configurations - but they won't be able to exist all at the same time, different configurations will choose different elements in a mutually exclusive way (see 'Changes in Activation behavior' section in 1.0 release notes: https://github.com/7mind/izumi/releases/tag/v1.0.0), so that's an unrelated instrument, but I think refSet above should work well for your usecase
Didac
@umbreak
@neko-kai yes that works, thanks!
Kai
@neko-kai
:+1:
@DamianReeves I'm not sure what you mean exactly, but it works for me to add Has-like methods like this https://scastie.scala-lang.org/Xg6LV87fT5aMEUdELvQGAw
Damian Reeves
@DamianReeves
@Kai thanks. After playing around a bit yesterday I did happen to stumble on a similar solution.
Didac
@umbreak

@neko-kai It does work what you suggested, but I get the following error:

app   Caused by: izumi.distage.model.exceptions.MissingRefException: Proxy for {type.scala.collection.immutable.Set[=A]} is not yet initialized

This is due to the fact that I have something like:

make[C].from((aSet: Set[A]) => new C(aSet.toList))

Since class C requires a List[A]. It seems that in the moment when that line is executed, the set is not yet fully initialzed. If I change C to require a Set[A] it works, but it is not what I want

Didac
@umbreak
Is there a way to work around this? or I have to do something like:
class C[A](set: Set[A]){
   private lazy val list = set.toList
}
Kai
@neko-kai
@umbreak Is C itself included into Set[A] - perhaps transitively? That's the only thing that would cause a proxy to be generated to allow a cyclic dependency to still work. You may try to print or inspect your wiring data to locate the cycle (https://izumi.7mind.io/distage/debugging#pretty-printing-plans, https://izumi.7mind.io/distage/debugging#graphviz-rendering ) but if it's deliberate than you'd pretty much have to use a lazy constructor
Didac
@umbreak
Well, the setup is more complicated than A, B and C…so it could be that is inluded transitively yes. I’ll check that using the debugging tools. Thanks again :)
Kai
@neko-kai
@umbreak You can also disable support for cycles by using Injector.NoCycles() instead of Injector(), that would cause it to fail earlier and maybe locate the issue easier
Edvin Lundberg
@Edvin-san

Hi, just wanted to say that the new distage 1.0.4 version seems to have fixed my shutdown issues :thumbsup:

Hi! I think I may have a problem with resources not being cleaned up. When my app receives SIGTERM it starts shutting down (I can see AppShutdownStrategy "Going to shut down..." in logs).
I can also see http4s PoolManager "Shutting down connection pool". But then it just sits there. Do you have any recommendation on how to debug this in distage? Can I see which resource is causing the problem?

Kai
@neko-kai
That's great, so it wasn't an issue in your code, but in our :D
jatcwang
@jatcwang:matrix.org
[m]
Hi, I'm having a blast playing around with Tag/LightTypeTag so thanks :) Question: Is it possible to summon LightTypeTag[T] directly? (I don't use anything else from Tag)
jatcwang
@jatcwang:matrix.org
[m]
hm just realized LightTypeTag doesn't have a type param. Guess it won't work then
Kai
@neko-kai
@jatcwang:matrix.org Actually you can summon using LTag[T]
jatcwang
@jatcwang:matrix.org
[m]
Oh lovely thanks!
It's still a wrapper around LightTypeTag so I still need to call tag.tag quite a bit. Still good to have since it's less work for the compiler. Not a big issue
Kai
@neko-kai
@jatcwang:matrix.org The difference between LTag and Tag (aside from the Class[_] field) is that Tag will assemble a Tag from evidence for type parameters, e.g def x[F[_]: TagK, A: Tag]: Tag[F[A]] = Tag[F[A]]
But LTag will break on that. You can also summon "weak" versions using WeakTag[A]/LTag.Weak[A] - these will not attempt to resolve type parameters using tag evidence but will just include unresolved type parameters as written, e.g. def x[A] = WeakTag[A]; x[Int] = literal WeakTag[A], not WeakTag[Int]
jatcwang
@jatcwang:matrix.org
[m]
I'll play around with it and see whether LTag is good enough for me. Thanks for the info :)