Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Channing Walton
    @channingwalton
    Nice. We should add that to the examples.
    Alexey Alekhin
    @laughedelic
    Hi everybody. Is this project still alive?
    Gerard Murphy
    @sageserpent-open
    As it happens, I've just submitted a PR that was merged (and I have yet to say thank you for, so I'll go off and do that now....). So, yes, it is.
    Channing Walton
    @channingwalton
    Hi @laughedelic, it's alive but I'm guessing it's not hugely popular so we aren't used to having visitors ;)
    Vladimir Koshelev
    @koshelev
    Hi! Thanks a lot for this useful library!
    Is a release with scalaz 7.2.0 planned?
    Channing Walton
    @channingwalton
    Hi, sorry for the delay. Yes we will release a scalaz 7.2.0 asap.
    @koshelev ^
    Vladimir Koshelev
    @koshelev
    @channingwalton Great news! Thanks a lot for your answer!
    Channing Walton
    @channingwalton
    I have a build with scalaz 7.2.1. I'll publish 1.3.0 shortly
    Channing Walton
    @channingwalton
    @koshelev 1.3.0 with scalaz 7.2.1 is released :)
    Tell us how it goes.
    Vladimir Koshelev
    @koshelev
    @channingwalton All my tests passed after update. Thanks a lot!
    Channing Walton
    @channingwalton
    Great
    Vladimir Koshelev
    @koshelev

    @channingwalton Would it make sense to have something like
    ```
    trait LogTreeSyntax[Annotation, Error: Show] {
    type LogTree = Tree[LogTreeLabel[Annotation]]
    type LogTreeWriter[Value] = Writer[LogTree, Value]
    type DescribedComputation[Value] = EitherT[LogTreeWriter, Error, Value]

    ```?

    Channing Walton
    @channingwalton
    I'll have to star me it ;)
    'Stare'
    @lancewalton what do you think?
    Channing Walton
    @channingwalton
    @koshelev I see what you want to do, unfortunately traits cannot have type parameters with context bounds, but I'll fiddle around and see what I can come up with.
    Vladimir Koshelev
    @koshelev

    @channingwalton probably having

    implicit def logTreeShow(implicit annotationShow: Show[Annotation], errorShow: Show[Error])

    will be enough?

    Channing Walton
    @channingwalton
    yes I think so
    but then type DescribedComputation[Value] doesn't work out
    Vladimir Koshelev
    @koshelev
    Why? Because of description having type String?
    Channing Walton
    @channingwalton
    yes
    Is it that we need methods like def failure[V](description: String)to be def failure[V, Err: Show](description: Err)
    Vladimir Koshelev
    @koshelev
    What if both success and failure descriptions will have the same type?
    Channing Walton
    @channingwalton
    hmm
    Vladimir Koshelev
    @koshelev
    The advantage would be we will be able to write tests asserting a computation produces exactly the tree we expecting
    Channing Walton
    @channingwalton
    yes ok
    I'll keep trying :)
    Vladimir Koshelev
    @koshelev
    I’m starring at LogTreeLabel now and thinking, if description can be of any type, are annotations really needed? :)
    Channing Walton
    @channingwalton
    :D
    I think we need @lancewalton to come back from holiday
    Vladimir Koshelev
    @koshelev
    Seems so. In the meantime I will try to find nice way to work with dependant computations of Future[DescribedComputation[V]] :)
    Channing Walton
    @channingwalton
    heh
    Vladimir Koshelev
    @koshelev

    yep.
    Now i have ugly combination of

    case class FutureDescribedComputation[A](run: Future[DescribedComputation[A]]) {
      def flatMap[B](f : A => FutureDescribedComputation[B])
                    (implicit exec: ExecutionContext) : FutureDescribedComputation[B] =
        FutureDescribedComputation(
          run.flatMap { dca : DescribedComputation[A] =>
            dca.run.value.fold(
                s => Future.successful( EitherT.left[LogTreeWriter, String, B]( dca.run.map(_ => s) ) ),
                (a : A) => f(a).run.map { x => dca.flatMap { _ => x } } )
          }
        )
    
      def map[B](f : A => B)(implicit exec: ExecutionContext) : FutureDescribedComputation[B] =
        FutureDescribedComputation( run.map { x => x.map { f } } )
    }

    and future.recover{ case t => failure("Client lookup”) ~~ t}

    But I do belive there should be a better way :)
    Channing Walton
    @channingwalton
    yeah, I think I might know someone that needed something similar, I'll ask
    Vladimir Koshelev
    @koshelev
    Cool, thank you a lot
    Gerard Murphy
    @sageserpent-open
    @koshelev - I've used annotations to mark out sections of a large log tree as being relevant to different downstream consumers - the idea is to prune the log tree into simpler trees by annotation, then route each simplified tree to SLF4J using the annotation as an SLF4J context, as well as routing the original unpruned tree to a 'tell-me-everything' logger. Given this is in production at a client site, I think they would very much like to keep the notion of annotations. My point is that annotations allow a single log tree to carry multiple contexts that coexist in the same tree with the same type of description - and that these annotations can be applied at a root node of a tree, distinct from the nodes where the descriptions were produced (in case you were thinking of encoding the annotation in the description via case classes / shapeless). Not that I'm against the idea of generalising the description to an arbitrary showable, though...
    @koshelev - BTW, regarding Future[DescribedComputation[V]] - have you taken a look at EMM? We had a similar problem, wherein we had a 'ManagedResource[Process[Task, DescribedComputation[X]]]' - the plan (shelved for the time being last time I checked) was to try to use EMM to at least fuse 'Process' and 'DescribedComputation' into a stacked monad...
    Vladimir Koshelev
    @koshelev
    @sageserpent-open good point on annotations.
    both eff-scalaz and Emm are on my list, but I’m not sure it will help much. The ugly things about Future[DescribedComputation[V]] are both have notion of success and failure and failed future will loose log.
    Harry Chen
    @chenharryhua
    @lancewalton I don't know how to recover from failure:
    val rec = "test" ~< { val dc = "compute".left[Int] ~>? (l => l, r => r.toString) dc.handleError { x => 1 ~> "recoveried" } } println(rec.run.written.show)
    which print out Failed: test Failed: compute recoveried
    is it possible (or how to) make the test tag success because it is recoveried from errors? thanks. nice lib by the way
    Harry Chen
    @chenharryhua
    Ok. I figured out the reason is that in branchHoister method which check allSuccessful(children)... I can modify it myself....
    Gerard Murphy
    @sageserpent-open

    @chenharryhua You could just pattern match against rec.run.value. If I do this:

    import scalaz.std.string._
    
    import treelog.LogTreeSyntaxWithoutAnnotations
    import treelog.LogTreeSyntaxWithoutAnnotations._
    import scalaz.syntax.plus._
    import scalaz.syntax.show._
    import scalaz.syntax.monadError._
    
    val planAThatDoesntWork: LogTreeSyntaxWithoutAnnotations.DescribedComputation[Int] = failure[Int]("Oh dear....")
    
    val backupPlan: LogTreeSyntaxWithoutAnnotations.DescribedComputation[Int] = 42 ~> "This one works"
    
    val putThemTogether = planAThatDoesntWork <+> backupPlan
    
    putThemTogether.run.value // Yields a value, 42.
    putThemTogether.run.written.shows // Shows that there *was* a failure, and that we recover.
    
    val anotherWay = planAThatDoesntWork.handleError(_ => backupPlan)
    
    anotherWay.run.value
    anotherWay.run.written.shows

    , I see values (along with the failure in the log).

    Harry Chen
    @chenharryhua
    cool. thanks @sageserpent-open
    Harry Chen
    @chenharryhua
    Channing Walton
    @channingwalton
    Thanks to ronanM we now have a cats version!
    "com.casualmiracles" %% "treelog-cats" % "1.4.1-SNAPSHOT"
    If all goes well I'll publish a full release version
    Shingo Omura
    @everpeace
    Could we handle IO[V] values in treelog?? lancewalton/treelog#13
    actually I suspect that becuase LogTreeWriter is not WriterT but just WriterT[Id, _]. I think handling monadic values with treelog would be not so rare demand.