trackedfuture

small runtime + java-agent, which brings back full stacktrace for exceptions, generated inside Future callbacks

License

License

GroupId

GroupId

com.github.rssh
ArtifactId

ArtifactId

trackedfuture_2.13
Last Version

Last Version

0.4.2
Release Date

Release Date

Type

Type

jar
Description

Description

trackedfuture
small runtime + java-agent, which brings back full stacktrace for exceptions, generated inside Future callbacks
Project URL

Project URL

https://github.com/rssh/trackedfuture
Project Organization

Project Organization

rssh
Source Code Management

Source Code Management

https://github.com/rssh/trackedfuture

Download trackedfuture_2.13

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.rssh/trackedfuture_2.13/ -->
<dependency>
    <groupId>com.github.rssh</groupId>
    <artifactId>trackedfuture_2.13</artifactId>
    <version>0.4.2</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.rssh/trackedfuture_2.13/
implementation 'com.github.rssh:trackedfuture_2.13:0.4.2'
// https://jarcasting.com/artifacts/com.github.rssh/trackedfuture_2.13/
implementation ("com.github.rssh:trackedfuture_2.13:0.4.2")
'com.github.rssh:trackedfuture_2.13:jar:0.4.2'
<dependency org="com.github.rssh" name="trackedfuture_2.13" rev="0.4.2">
  <artifact name="trackedfuture_2.13" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.rssh', module='trackedfuture_2.13', version='0.4.2')
)
libraryDependencies += "com.github.rssh" % "trackedfuture_2.13" % "0.4.2"
[com.github.rssh/trackedfuture_2.13 "0.4.2"]

Dependencies

compile (2)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.13.5
org.ow2.asm : asm jar 9.1

test (1)

Group / Artifact Type Version
org.scalatest : scalatest_2.13 jar 3.2.7

Project Modules

There are no modules declared in this project.

Tracked Future

Join the chat at https://gitter.im/rssh/trackedfuture

Overview

Contains agent, which substitute in bytecode calls to future method wich accepts callbacks ( Future.apply''' map, flatMap filter``` ... etc) to tracked versions which save origin caller stack.

Ie. tracked version collect stack trace of origin thread when appropriative construction is created and then, when handle exception, merge one with stack trace of this exception;

Useful for debugging.

Usage

  • publishLocal tracked-future to you local repository

  • when debug, enable agent

fork := true
javaOptions += s"""-javaagent:${System.getProperty("user.home")}/.ivy2/local/com.github.rssh/trackedfuture_2.11/0.2/jars/trackedfuture_2.11-assembly.jar"""

Results

Let's look at the next code:

object Main
{

  def main(args: Array[String]):Unit =
  {
    val f = f0("222")
    try {
       val r = Await.result(f,10 seconds)
    } catch {
       // will print with f0 when agent is enabled
       case ex: Throwable => ex.printStackTrace
    }
  }

  def f0(x:String): Future[Unit] =
  {
    System.err.print("f0:");
    f1(x)
  }

  def f1(x: String): Future[Unit] =
   Future{
     throw new RuntimeException("AAA");
   }

}

With tracked future agent enabled, instead traces, which ends in top-level executor:

f0:java.lang.RuntimeException: AAA
  at trackedfuture.example.Main$$anonfun$f1$1.apply(Main.scala:30)
  at trackedfuture.example.Main$$anonfun$f1$1.apply(Main.scala:30)
  at trackedfuture.runtime.TrackedFuture$$anon$1.run(TrackedFuture.scala:21)
  at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
  at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
  at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
  at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
  at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

you will see traces wich include information: from where future was started:

f0:java.lang.RuntimeException: AAA
  at trackedfuture.example.Main$$anonfun$f1$1.apply(Main.scala:30)
  at trackedfuture.example.Main$$anonfun$f1$1.apply(Main.scala:30)
  at trackedfuture.runtime.TrackedFuture$$anon$1.run(TrackedFuture.scala:21)
  at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
  at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
  at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
  at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
  at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
  at java.lang.Thread.getStackTrace(Thread.java:1552)
  at trackedfuture.runtime.TrackedFuture$.apply(TrackedFuture.scala:13)
  at trackedfuture.runtime.TrackedFuture$.rapply(TrackedFuture.scala:39)
  at trackedfuture.runtime.TrackedFuture.rapply(TrackedFuture.scala) 
  at trackedfuture.example.Main$.f1(Main.scala:29)
  at trackedfuture.example.Main$.f0(Main.scala:25)
  at trackedfuture.example.Main$.main(Main.scala:13)
  at trackedfuture.example.Main.main(Main.scala)

Additional Notes

If you want a version with more wrappend methods and with frames cleanup - don't hesitate to submit pull request ;)

Versions

Version
0.4.2
0.4.1