awltech / org.parallelj

ParallelJ-Runtime is a part of the ParallelJ project corresponding to the runtime part (obviously). It contains the execution engine, and all runtime related components. More information can be found on our website: http://www.parallelj.org
http://www.parallelj.org
GNU Lesser General Public License v2.1
4 stars 2 forks source link

Provide Flow Callstack as Java Object #14

Open aneveux opened 13 years ago

aneveux commented 13 years ago

Although //J logs the visited Programs and Procedures like

11-19 14:32:56.220 [main] INFO  internal.log.Logs. (Logs.aj:62) - [0] 0.0.0.0/0.0.0.0 1290173576220:1290173576220:1290173576220:0 prolog main 
11-19 14:32:56.236 [main] INFO  internal.util.Formatter.print (Formatter.java:136) - I0001  building program [class executable.MyProgram]
11-19 14:32:56.252 [main] INFO  internal.log.Logs.ajc$before$org_parallelj_internal_log_Logs$1$e1af1f7 (Logs.aj:76) - [0] 0.0.0.0/1.0.0.0 1290173576252:1290173576252:1290173576252:0 executable.MyProgram main 
11-19 14:32:56.252 [main] INFO  internal.log.Logs.ajc$before$org_parallelj_internal_log_Logs$1$e1af1f7 (Logs.aj:82) - [0] 1.0.0.0/1.1.0.0 1290173576252:1290173576252:1290173576252:0 run:executable.MyExecutable main 
11-19 14:32:56.267 [main] INFO  internal.log.Logs.ajc$after$org_parallelj_internal_log_Logs$3$a8c3a8c (Logs.aj:123) - [1] 1.0.1.0/1.1.1.1 1290173576252:1290173576252:1290173576267:15 SUCCEEDED main name=run+executable.MyProgram%40b988a6
11-19 14:32:56.267 [main] INFO  internal.log.Logs.ajc$after$org_parallelj_internal_log_Logs$2$2c56f784 (Logs.aj:102) - [1] 0.0.0.0/1.0.1.0 1290173576252:1290173576252:1290173576267:15 COMPLETED main name=name&value=a+complex+string+with+special+char+%26%3B%3C%3E

it might be helpful, also to provide a Callstack as an object (e.g. Logs.getCallstack()) to allow //J users to use it in their programs (e.g. to pass it as a parameter to an Exception). That allows programmers who use //J to write their own flow logging as they like.

aneveux commented 13 years ago

Following comments are imported from our previous issue tracker:

aneveux commented 13 years ago

I'm a little bit confused with the callstack because, in your example, the method that will throw the exception is part of the callstack. So it will be present in the stack trace of the exception. What kind of additional information do you need in your callstack?

aneveux commented 13 years ago

I do not request any additional information. I like to have the Callstack (executable.MyProgram main -> executable.MyExecutable main) available via a Java Object. By that //J users can switch of the //J output as seen in the example above and replace it by their own output or they can evaluate it in their code for other needs.

aneveux commented 13 years ago

I propose to add the interface

interface Call {

   String getName(); // return the name of the corresponding procedure

   Process<?> getProcess(); // return the process that launched the procedure call

}

And an helper class to get an instance of Call.

For instance, in a Runnable:

public class MyRunnable implements Runnable {

    public void run() {
        Call call = MyHelperClass.getCall(this);
        System.out.println("procedure: " + call.getName());
        // ...
    }

}

What do you think?

aneveux commented 13 years ago

I think the Call interface is a great idea, which brings us a big step forward. To complete what I have asked for, we could use this Call interface to get a complete Call StackTrace. So imagine we have:

public class MyRunnable implements Runnable {

    public void run() {
        Call[] stackTraces = Procedure.getStackTrace();
        System.out.println("Current Procedure(A): " + stackTrace[0].getName());
        System.out.println("Procedure(B) that called A : " + stackTrace[1].getName());
        System.out.println("Procedure(C) that called B : " + stackTrace[2].getName());
        //and so on...
    }
}

As you have recognized this concept corresponds a little to java.lang.Thread.getStackTrace().

aneveux commented 13 years ago

There is no call stack in //J. If you have a -> b -> c. it correspond to:

process() {
  a();
  b();
  c();
}

but not to:

process() {
  a();
}
a() {
  b();
}
b() {
  c();
}

Also, you can know where you are in the process but you cannot know why you are at this stage of the process. The calls executed before are not kept in memory. In my example, in c(), you cannot know that a() and b() were executed before. It would be a big effort to implement that (and a memory leak issue for batch processes).