Maybe some context to the need of multithreaded related information.

As you may know, unlike many in this group, I am teaching programming on a business university from zero to Java programming without Java in a single semester (four months) with four hours lecture per week. Half of the students usually have no programming skills at all. There is no comparable introduction to a programming course anywhere in the world that I am aware of that is able to teach successfully the rich content. Here a link to a small paper reporting about it: <https://research.wu.ac.at/files/32933846/2021_Flatscher_Mueller_BusinessProgramming_from_proceedings.pdf> ("Business Programming" – Critical Factors from Zero to Portable GUI Programming in Four Hours).

As reported there one of the critical success factors are the programming languages one chooses, in this case the students learn Rexx, ooRexx and BSF4ooRexx (in that sequence) in a single semester four hours per week.

Multithreading is not a concept that you would dare to teach beginners, yet it becomes a necessity when running ooRexx scripts in the context of applications that apply multithreading like Windows GUI applications (ooDialog as an example) and later in Java GUI applications. Notabene: the host apps are Windows or Java libraries in these cases, the code is ooRexx.

If there are errors, hangups, deadlocks experienced in the context of multithreaded execution it is currently practically impossible for the students to find out what, why and where the problem is because currently there is no information supplied by ooRexx that would allow to understand in which multithreaded context a program executes.

Having a TID in the context of a trace helps to understand that there are different contexts in which the ooRexx program executes and or hangs. So any addition of the thread information is helpful if it easy apprehended from the output such that it becomes possible to see which part of an ooRexx program runs on which thread.

The idea of encoding the thread number in the trace output is intriguing. There might be a little problem going with it though that may make it a little difficult to immediately comprehend: encoding the thread number in the middle of a string may make it difficult to identify and extract it directly. Also the thread number may not remain at a single digit such that the column outlines may become irregular if more than 9 threads get reported this way.

Maybe the legibility/spotting of the thread number could be improved (maybe not) by injecting an underscore right before the thread number, the two-digit thread number scenario could be probably handled by formatting by default for two right-adjusted digits with underscore as pad character.

So Mike's short example:

   14 *-*   dthen=dthen.i
       >C3>     DTHEN.I => "DTHEN.1"
       >V3>     DTHEN.I => "2023-03-26"
       >>3>     "2023-03-26"
       >=3>     DTHEN <= "2023-03-26"

would then look like:

   14 *-*   dthen=dthen.i
       >C_3>   DTHEN.I => "DTHEN.1"
       >V_3>   DTHEN.I => "2023-03-26"
       >>_3>   "2023-03-26"
       >=_3>   DTHEN <= "2023-03-26"

or with two digits right-adjusted (keeping every number for better legibility right adjusted and aligned even if more than nine threads are executing) something like:

   14 *-*   dthen=dthen.i
       >C__3>  DTHEN.I => "DTHEN.1"
       >V__3>  DTHEN.I => "2023-03-26"
       >>__3>  "2023-03-26"
       >=__3>  DTHEN <= "2023-03-26"


If foregoing the possibility that there are programs that parse such output one could use a space instead of an underline as pad such that the output would look like:

   14 *-*   dthen=dthen.i
       >C 3>   DTHEN.I => "DTHEN.1"
       >V 3>   DTHEN.I => "2023-03-26"
       >> 3>   "2023-03-26"
       >= 3>   DTHEN <= "2023-03-26"

or with right-adjusted with two digits place would then look like:

   14 *-*   dthen=dthen.i
       >C  3>  DTHEN.I => "DTHEN.1"
       >V  3>  DTHEN.I => "2023-03-26"
       >>  3>  "2023-03-26"
       >=  3>  DTHEN <= "2023-03-26"

---

Still, there is a need for further context information when debugging or analyzing multithreaded ooRexx programs that might not meet the eye.

To elaborate please let me describe some of the power of ooRexx briefly (and excuse me if you are already aware of it):

 * ooRexx is a powerful interpreter that allows for quickly creating and using 
/any number of
   /independent Rexx interpreter instances (RII):

     o each RII shares the .environment directory, i.e. all objects therein: 
these objects come
       mostly from ooRexx at load time, but .enviornment can be used by ooRexx 
programmers for
       storing objects there and use them for coupling different ooRexx 
programs that may even run
       on different RIIs

     o each RII has a proper .local directory which all ooRexx programs running 
under that RII
       share objects with each other, but no one else: this allows for coupling 
ooRexx programs
       that get executed on a specific RII (BSF4ooRexx uses .local to redirect 
ooRexx .input,
       .output and .error to the Java supplied standard files)

 * in each RII there may be ooRexx programs that get executed in a 
multithreaded, dynamic fashion,
   creating a powerful, but complex environment in which all those ooRexx 
programs may execute
   within a process on different threads under different Rexx interpreter 
instances concurrently

This power ooRexx offers has no counterpart in classic Rexx. Because of this power analyzing multithreaded ooRexx applications may become quickly very complex, understanding what happens why may become almost impossible as currently there is no context information supplied by ooRexx whatsoever that would give a good insight of what is going on.

Debugging multithreaded ooRexx programs as a result becomes quickly difficult and sometimes almost impossible without resorting to a debug version of ooRexx itself, using a C++ debugger, defining breakpoints to become active and then become able to inspect the environment from a C++ debugger point of view. However, understanding what one gets to see in such C++ debugger environments is incomprehensible if you are not acquainted with the very details of the ooRexx C++ implementation. What may be "easy" for the core ooRexx developers, maybe more than difficult for others, and for those without C++ knowledge impossible.

This is something I cannot expect any of my business administration students to use, despite the fact that they get to run ooRexx programs in such environments like:

 * OpenOffice/LibreOffice,
 * JavaFX,
 * Java web servers,
 * any Java application that uses ooRexx as a scripting/macro language

The Java environment defines a standard scripting framework (cf. package javax.script) with optional features that all are implemented in BSF4ooRexx850 to unleash the power of ooRexx to Java (applications, users).

If Java applications/frameworks like JavaFX or Java web servers use the Java scripting framework (package javax.script) are told to use the "rexx" language for executing scripts a proper Rexx interpreter instance (RII) gets created and the script executed with it.

---

/Example 1, JavaFX (powerful GUI programming made easy with ooRexx):/

JavaFX allows for defining and using multiple different user interfaces ("scenes" to be put on "stages"=windows) with the help of separately defined text files (XML based, dubbed: "FXML"). For each such FXML text file one can denote "rexx" as the programming language to use e.g. for events etc. which at runtime (after loading the respective FXML file to create a "scene") will cause a Rexx interpreter instance (RII) to be created. Multiple FXML files cause multiple RIIs to be created, one per FMXL.

In such an environment there is at least the JavaFX application thread, potentially an awt/swing thread and multiple ooRexx threads that are relevant. If a problem occurs and debugging becomes necessary currently one is lost. The ooRexx thread number in such a case may not be enough to help the ooRexx programmer to quickly analyze and find problematic parts in such a complex environment.

The students who learn how to exploit JavaFX with ooRexx (this is actually *very* easy for them, believe it or not) are usually lost, if hitting multithreading problems.

E.g. even after teaching explicitly about GUI threads and how important it is to update the GUI controls only on the GUI thread or to have long-running actions execute on different threads and how to synchronize was just too difficult to grasp at that point in time (we are talking about beginners here). Observing this over the years, despite trying to improve teaching the necessary concepts, this has finally caused me to come up with the two ooRexx classes .FXGuiThread and .AwtGUIThread possessing a method named runLater() which will make sure that a message to a Rexx object will get sent on the respective GUI thread. Immediately, all of the business administration students became able to write working awt/swing or FX applications with ooRexx not running into those multithreading problems when updating the GUI from a non-GUI thread!

When having a need to kick off a thread on their own (to have some long lasting process execute on a non-GUI thread) it is to be expected that earlier or later they might run into problems.

For situations like this it becomes important to allow them to understand the dynamics and properties of having their programs execute under such a multithreaded context.

---

/Example 2: Java web servers like Tomcat, WebSphere etc.:/ all these Java web servers are implemented according to the same Java specifications such that one ooRexx solution works with any of the other Java web servers. In order for business administration students to create small web servers of their own (e.g. for small or medium sized businesses of their parents, relatives, friends), I created a Java taglib library that employs the Java scripting framework (javax.script) to allow for creating web server pages with ooRexx code only (in the context of JSP).

It is surprising how quickly these students - if motivated because e.g. their relatives/friends own a business with a web server need or simply being interested in the architecture of a web server etc. - apprehend what is necessary to become almost immediately productive in creating web server applications in ooRexx only. To teach the necessary skills to get them up and running takes a lecture of 90 minutes at the end of that "business programming" course!

Here a bachelor thesis of one of my students (this one knew how to program already and learned ooRexx because interested in a new language) who created a web shop with cart, remote picture uploading, RDBMS, e-mail newsletter functionality: all in pure ooRexx exploiting the Java class libraries (like one may exploit C++ libraries from ooRexx without a need to learn about C++). Here the link to the PDF file for interested readers: <https://wi.wu.ac.at/rgf/diplomarbeiten/BakkStuff/2021/202102_Lux_IntroductionToWebApplicationDevelopment.pdf>. You could take up his work and adapt it to your own needs, if you wished and have a running web server within hours that you can change, extend in ooRexx.

What happens in such an environment is briefly the following:

 * a web server may consist of one or more web applications,
 * each web application may consist of one or more ooRexx programs, sharing 
even functionality and
   resources with other web applications, including other ooRexx web apps,
 * when a client requests a resource from the web server serviced by ooRexx 
implemented web apps
   (JSPs or raw ooRexx programs) then for each such a request a Rexx 
interpreter instance (RII)
   gets created and used  for the duration of the execution of the ooRexx 
programs invoked because
   of each client's request,
 * each client request may get executed on a separate web server thread, where 
each such thread
   gets sometimes re-used by the Java web server (normal in the JSP case), but 
there may be more
   (and different) threads created due to the amount of requests using the same 
ooRexx web
   application ...
 * ...

If there are 1,000 client requests to ooRexx web services there will be 1,000 RIIs created on the web server (is very fast and great) to execute the ooRexx programs on different threads, many of which concurrently!

[Unfortunately, currently there is a repeatable crash in ooRexx when terminating Rexx interpreter instances. Last August I uploaded a c++ only program to ease debugging, cf. <https://sourceforge.net/p/oorexx/feature-requests/_discuss/thread/ea502e70f2/8165/attachment/testTerminate.cpp> and <https://sourceforge.net/p/oorexx/feature-requests/_discuss/thread/ea502e70f2/8165/attachment/Makefile.windows>. Unfortunately, there has been no word so far whether this has helped, what the problem is, whether it is being worked upon, by when one could expect a possible solution, etc. which is a real problem. As a native crash by ooRexx in a process where a Java web server runs will tear down the entire web server with all of its running web services, so I had to stop teaching ooRexx for programming web services as it would be unresponsible to have students currently create such solutions for their parents and friends which is known to cause the web servers to crash because ooRexx crashes. This is also unfortunate, as the ooRexx solution is fast, easier to be programmed and in other aspects ahead of many other scripting languages. There was a presentation at an ApacheCon introducing that script taglib and demonstrating different scripting languages among them ooRexx, for which I wrote that taglib in the first place: <https://sourceforge.net/projects/bsf4oorexx/files/Sandbox/rgf/taglibs/ga/AC21-Flatscher-EnablingScriptingLanguagesInJsps-v05.pdf/download>) which may give more insights, information, e.g. on Groovy, Jython, JavaScript, PHP.]

The dynamics in the web server scenario is such that debugging ooRexx web applications in such a multithreaded environment and in such a context is more than challenging for newcomers as well as experts.

ooRexx multithreading and Java multithreading work nicely with each other!

---

In general, the more context information about such complex environments in which ooRexx programs get executed, including as much of ooRexx context information is available the better the support for the ooRexx programmers to analyze, to understand and to debug such multithreaded deployments, the better!

Having just the thread number may not be sufficient in such cases to efficiently support the ooRexx programmer to get insight and debugging capabilities at his hands.

So the need for more complete multithreaded related trace information.

There *is* a need here for learning e.g. which RII is executing which ooRexx routine and in which method routine (which object/variable pool) and who has the lock in that context. E.g. there may be many web requests to the same service with different argument values causing different code to execute differently on different Rexx interpreter instances with many different threads in the system and different threads in each RII's ooRexx programs that they may incur. There is no limit here in imagination how ooRexx gets excercised in such multithreaded, complex environments.

It is also clear that this kind of multithreaded debug information is meant for such complex deployments and not for simple programs. Therefore this wealth of multithreaded related trace should only be created explicitly - and in addition, separate to the "simple, but helpful" thread number (a welcomed improvement compared to the current situation) display above.

The debug information generated in complex multithreaded environments may be huge, therefore it becomes also important to become able to better analyze the amount of acquired trace data. This is where the Rexx companion utility "tracer.rex" comes into play that creates a CSV file from the multithreaded debug data that one can load into a spreadsheet. Why is this important?

Modern spreadsheets allow for easy filtering of data, creating cross-references, diagrams and the like. It becomes easy to filter e.g. by a specific Rexx interpreter instance (for a specific FXML scene, a specific web app) and all its trace output, analyzing the multithreaded environment and states, coming up even with simple/coarse statistical data (if timestamps could be made available to the trace string output even some gross form of profiling could be applied) and much more.

The debug data needs to be easily understood and parseable, such that analysis becomes easy=human-centric!, i.e. quickly possible.

In the CSV application case it can be regarded as some sort of post-mortem analysis tool of one own's multithreaded ooRexx programs.

This is not a feature that is academic, or nice to have, it is a productivity improving feature for ooRexx programmers learning, debugging or moving along the limits of multithreaded programming in (naturally) complex environments!

---

We have all the means available, it is the ooRexx programmer who can take advantage of rich multithreaded trace information that can be supplied to help putting spotlights on the different parts of the current execution context. If the ooRexx porgrammer does not want to, he does not have to use it, he is not forced to, no one gets impeded at all!

As ooRexx makes multithreading available in a very human-friendly manner (it is fascinating how easy it is to create multithreaded programs in ooRexx), it also is supposed to make it easy to fully understand and to fully debug such an important ability by making tracing/debugging multithreaded ooRexx code human-centric and powerful as well!

 ---rony

_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to