New Feature This release features full dependency introspection of a result. It is useful for checking
that developed accessors or transreptors are working correctly. It is also useful for gaining an understanding of
how deep the dependencies can get and how NetKernel manages them.
License
Unlike the other NetKernel modules, which are distributed under the 1060 Public License, the Debugger is licensed under a
non-commercial use license. You are free to evaluate the debugger and
free to use it for non-commercial use. The debugger is not restricted in any way
and includes full documentation - rather than restrict the product, we prefer to trust you and hope that you will respect that trust by purchasing
a license. Please visit 1060 Research for a license if you intend to use the debugger for
development of commercial applications.
Principles
This debugger is like no other. It doesn't debug at the high level of any language like
DPML- it debugs at the level of URI requests made to the NetKernel scheduler. The kernel implements
a small API that allows the setting and revoking of breakpoints and the viewing and releasing of breakpointed
requests. The debugger application itself is just another user level module.
Breakpoints can be defined as regular expression
matches on the URI of a request and optionally the request's parent request and grandparent request.
Because the debugger application runs as a user-side application on the NetKernel that you are debugging,
certain precautions must be taken. Antibreakpoints act as inhibitors to stop breakpoints getting
triggered at places that might effect critical user-side applications.
Practical Debugger
Breakpoints
When you go to the debugger main entrypoint with your browser you'll be
presented with a list of breakpoints:
From here you can add, remove and edit breakpoints.
Currently there are two types of breakpoints. Their ordering has no useful
effect on the way they work.
Regular Breakpoints
Regular Breakpoints define requests which will be stopped in the debugger to allow
their introspection. Editing or adding a new breakpoint will present you with the following
page:
A description of the fields:
- Enabled The breakpoint will only have an effect if it is enabled
- When Breakpointing before a request has been executed will in future
versions allow you to step into a request. If you breakpoint after a request (default) you
will be able to see the result.
- Request Type The breakpoint will only operate on a request of the
given type.
- Request URI Regex If not empty this regular expression must match the
rewritten URI of the request.
- Parent URI Regex If not empty this regular expression must match the
rewritten URI of the parent request of the current request.
- Grandparent URI Regex If not empty this regular expression must match the
rewritten URI of the grandparent request of the current request.
AntiBreakpoints
AntiBreakpoints inhibit any other breakpoints
from operating when they match. They are defined as a regular expression on a root (transport initiated)
request URI. If the expression matches then all sub-requests will be allowed to proceed.
You may have noticed that when you first enter the debugger breakpoints page there
are already two antiBreakpoints there. These are removeable but have been added to prevent
a breakpoint from ever stopping requests targetted at the debugger and introspect modules.
This means that requests to the debugger application itself will not trigger general breakpoints that were
intended for your application. In short, with these antibreakpoints the debugger won't start debugging the debugger!
Editing or adding a new antiBreakpoint will present you with the following page:
The antiBreakpoint will only have an effect if it is enabled. The root URI regex is
a regular expression that must match the un-rewritten transport initiated request which
enters NetKernel.
Performance
The evaluation of breakpoints has a very small effect on scheduler performance. If you
have finished using the debugger, certainly on a live system, ensure you have no breakpoints
(or antiBreakpoints) registered. If no breakpoints are registered the debugger has no performance penalty.
Since the debugger application is web-based it is by definition a remote debugger. If you wish you can perform emergency remote
debugging even on a live production server.
Stopped Requests
When working with the debugger in development you may want to increase the deadlock period in
the System Config to a high enough period not to terminate your
breakpointed request. In addition, if you anticipate breakpointing many concurrent requests, you will want to
increase the throttle to a level that will allow you to control the system whilst there are many other pending
requests.
Viewing of Resource
Clicking on the view link for a stopped request will request a detailed view of the
stopped request. The left pane of this view shows the request call stack, starting at the
module which the intiating transport is residing in, down to the location at which the breakpoint
occurred. On the way there may be intermediate modules and accessors that have handled the
request. Shown between the modules is the request that was issued symbolized with an arrow icon.
Clicking on that arrow focusses the right pane on the details of that request. Initially
the right pane focusses on the deepest request in the call stack. This pane shows all the data
associated with the request and its result if available.
The request fields have the following meaning:
- type on of the five basic request verbs, SOURCE, SINK, NEW, DELETE, EXISTS, TRANSREPRESENT
- uri the un-rewritten request issued by the module
- time the time the request was issued
- arguments the list of all pass-by-value and pass-by-reference arguments. Pass-by-value
arguments can be identified by the additional displayed metadata. Aspects are the Java interfaces
that the resource representations exhibit.
The result fields have the following meaning:
- mime The mimetype of the result
- expiry The pessimistic expiry time of the resource in seconds, i.e.
the number of seconds from now that you can assume the resource is valid for without
re-requesting it
- cost The cumulative cost of obtaining this resource from the ground up
- aspects The Java interfaces that the resource representation exhibits.
The dependencies table shows a hierarchical table of dependencies of the result. Each dependency
shows if it has expired and what its cost of creation is.
Example: Debugging a DPML Instruction
We have said that the debugger operates at the URI request level not at the language interpreter level. This means that any
request can be stopped. It is pretty simple to debug a DPML process. Suppose we have a DPML process in a file
ffcpl:/process.idoc which has one instruction to perform an xslt operation.
<idoc> <seq> <instr>
<type>xslt</type>
<operand>this:param</operand>
<operator>ffcpl:/style.xsl</operator>
<target>this:response</target>
</instr>
</seq>
</idoc>
We can debug the xslt instruction by setting up a request breakpoint
active:xslt.*ffcpl:/style.xsl.*
This will break all xslt requests using the ffcpl:/style.xsl stylesheet which might be all we need. However if the stylesheet is used
in lots of processes we'd get stopped requests for all of them and we might not be able to easily trace the particular xslt in this
DPML process. To get around this we can qualify the breakpoint more tightly by adding a parent breakpoint.
active:dpml.*ffcpl:/process.idoc.*
Now the debugger will only break on xslt requests that were initiated from the dpml ffcpl:/process.idoc. You can add up to three layers of granularity
which when combined with the regex matches gives very high precision to the breakpoint - you've probably grasped, the NetKernel debugger
works on URI "breakspaces" not breakpoints!
Future
The following list of features will be added in future versions of the debugger:
- Step Over, Step Into, Step Out
- Persistent breakpoints that can survive a restart
- Breakpoints on Exceptions
- Stopping requests