.
contact contact

B.08.30 / Release Notes / DLG Protocol Version 2

Eloquence B.08.30 DLG Protocol Version 2

 
.
 


Introduction

Eloquence B.08.30 eloqcore introduces DLG protocol version 2, intended to improve DLG protocol performance especially for wide-area (Internet) network connections.

To make better use of available network bandwidth, the size of a single DLG transaction has been significantly reduced, and data compression is selectively applied.

To lower network latency, multiple DLG transactions are batched into a single network transmission. This requires that bulk mode is active.

To further reduce network traffic, eloqcore maintains a cache which holds recent attribute values. When a program invokes DLG GET, and the addressed attribute value is stored in the cache, it can be returned to the program without performing a network transmission.

Furthermore, the maximum string length limitation of the first DLG protocol (8075 bytes) has been removed.

Please note: The DLG v2 protocol is enabled when a compatible DLG server connects. This is currently JDLG 2.0.


Bulk mode

The DLG v2 bulk protocol is enabled by default. The eloq.config (or .eloqrc) config option OPTION DLGBULK may be used to modify the default:

OPTION DLGBULK {0|1|2}

0 - bulk mode is not enabled by default
1 - bulk mode is enabled by default with JDLG 2.0
2 - same as (1) but DLG SET .async is ignored (force bulk mode)

The default is 1.
If bulk mode is enabled, DLG transactions are batched into a single network transmission, which is transmitted as soon as a synchronous DLG call is issued. Synchronous DLG calls, such as DLG GET or DLG DO, require immediate execution.

Also, a DLG call becomes synchronous when a status return variable is assigned. For example, DLG SET Path$,Value$;Stat requires immediate execution to return the resulting DLG status in Stat.

The first DLG protocol supports the .async mode to reduce call latency. If .async mode is enabled, certain DLG calls such as DLG NEW and DLG SET are transmitted without expecting a response, thus lowering network latency but at the same time losing status about failed DLG calls.

The DLG v2 protocol still supports .async mode but combines it with bulk mode (i.e., when async mode is active, bulk mode is implicitly activated as well). This allows for enhanced diagnostics to obtain details about failed DLG calls along with the originating location (segment/file/line).

Furthermore, the DLG LOAD call temporarily activates bulk mode if inactive. As a result, DLG LOAD can be executed in a single network transmission (depending on the size of the loaded DLG file). Programs no longer need to explicitly activate .async mode to optimize DLG LOAD performance.

When bulk mode is active and a DLG instruction issues a runtime error, it is possible that this error is related to an earlier DLG call which was batched previously and now turns out to have failed after the bulk response has been received. Enhanced diagnostics may then be used to find out about which particular DLG instruction has failed.

While bulk mode and .async mode appear to have similar effects, in .async mode any DLG error is ignored by default, while in bulk mode a runtime error is triggered, but probably later when a synchronous DLG call is executed.

Summary:

OPTION DLGBULK 1 is the default. It provides all bulk mode performance enhancements while maintaining backward compatibility. It is recommended to modify ON ERROR handlers to use enhanced diagnostics.

OPTION DLGBULK 2 can be used if programs don't use .async mode, or when it is expected that all DLG calls are successful while .async mode is active. Programs which rely on the fact that failed DLG calls are ignored while .async mode is active may no longer work as before, in which case OPTION DLGBULK 1 must be configured.

OPTION DLGBULK 0 might be useful when single-stepping a program while expecting that DLG calls are executed immediately.

Related attributes:

.bulk : integer, get/set

Allows to programmatically set or query the OPTION DLGBULK configuration.

On DLG SET, the OPTION DLGBULK configuration is modified. In addition, if the program is connected to JDLG 2.0, bulk mode is activated or deactivated.

.async : integer, get/set

Allows to programmatically activate/deactivate or query async mode.

Nonzero: async mode is active. On DLG SET, async mode is activated and .async_status is reset.

Zero: async mode is inactive. On DLG SET, async mode is deactivated and .async_status is updated to the status code of the first DLG call which failed since async mode was activated.

Note: Before Eloquence B.08.30 RC4 the value was bit-coded (bit 0: async mode, bit 1: bulk mode). This has been changed for full backward compatibility.

.async_status : integer, get

Returns the status code of the first DLG call which failed since async mode was activated.

Zero is returned if no DLG call failure was recorded.

Notes:

  • Must be invoked after async mode was deactivated.
  • Can only be queried once, i.e., DLG GET internally sets it to zero.
  • If DLG protocol v2 is active, enhanced diagnostics can be used to obtain details about which DLG call failed when .async_status is nonzero.

Example:

DLG SET ".async",1
...
...
DLG SET ".async",0
DLG GET ".async_status",Stat
! Stat is the status of the first failed asynchronous
! DLG call since async mode was activated
! or zero if no DLG call failure was recorded


Enhanced diagnostics

When bulk mode is active and a DLG instruction issues a runtime error, it is possible that this error is related to an earlier DLG call which was batched previously and only now turns out to have failed after the bulk response has been received.

When .async mode is active, failed DLG calls are ignored. When async mode is deactivated again, .async_status is set.

In both cases, if failed DLG calls are detected which have been batched and therefore are not related to the DLG call currently executed by the program, detailed diagnostic information can be obtained by configuring a log file (eloqcore -log) and setting the G1 log level (-dG1). The calls including their arguments, the status code, and the originating location (segment/file/line) are logged.

Example: DLG SET "main.foo",0 returning status 657 (649+8)

G1: req = DMDRV_SET
G1: obj.path = main.foo
G1: data.type = INT
G1: data.value= 0
G1: res = DMDRV_STATUS
G1: status.iv = 8
G1: DLG STATUS 657 IN SUB Setup FILE /prog/FOOBAR LINE 30
In addition, a program may use the attributes below to obtain enhanced diagnostics if a DLG runtime error is triggered:

.status : integer, get

Returns the status code of the last failed DLG call, or returns async_status if set.

Zero is returned if no DLG call failure was recorded.

Note: Unlike .async_status, this can be queried multiple times.

Example:

DLG GET ".status",Stat;Rc
IF NOT Rc THEN
  ! DLG v2 extended diagnostics available
  ! Stat contains last DLG status or async_status
  ! or zero if no DLG call failure was recorded
END IF

.status_msg : string, get

Returns a status message related to the last failed DLG call, or related to the first failed DLG call since async mode was activated.

The message is formatted like below:
"DLG STATUS 657 IN SUB Setup FILE /prog/FOOBAR LINE 30"

An empty string is returned if no DLG call failure was recorded.

Example:

DLG GET ".status_msg",Msg$;Rc
IF NOT Rc THEN
  ! DLG v2 extended diagnostics available
  ! Msg$ contains DLG status message like:
  ! "DLG STATUS 657 IN SUB Setup FILE /prog/FOOBAR LINE 30"
  ! or is empty if no DLG call failure was recorded
END IF

.status_seg : string, get

Returns the name of the program segment (main or SUB or FN) related to the last failed DLG call, or related to the first failed DLG call since async mode was activated.

An empty string is returned if no DLG call failure was recorded.

Example:

DLG GET ".status_seg",Seg$;Rc
IF NOT Rc THEN
  ! DLG v2 extended diagnostics available
  ! Seg$ contains the segment name (main or SUB or FN)
  ! or is empty if no DLG call failure was recorded
END IF

.status_file : string, get

Returns the file name related to the last failed DLG call, or related to the first failed DLG call since async mode was activated.

An empty string is returned if no DLG call failure was recorded.

Example:

DLG GET ".status_file",File$;Rc
IF NOT Rc THEN
  ! DLG v2 extended diagnostics available
  ! File$ contains the file name
  ! or is empty if no DLG call failure was recorded
END IF

.status_line : integer, get

Returns the line number related to the last failed DLG call, or related to the first failed DLG call since async mode was activated.

Zero is returned if no DLG call failure was recorded.

Example:

DLG GET ".status_line",Line;Rc
IF NOT Rc THEN
  ! DLG v2 extended diagnostics available
  ! Line contains the line number
  ! or zero if no DLG call failure was recorded
END IF


Error handler examples

Programs can now integrate enhanced DLG error diagnostics in their ON ERROR handler. The example below checks whether a DLG status message is available, the error handler could then for example output it to a log file:

DLG GET ".status_msg",Msg$;Rc
IF NOT Rc AND LEN(Msg$) THEN
  ! DLG v2 status message available
  ! Msg$ contains DLG status message like:
  ! "DLG STATUS 657 IN SUB Setup FILE /prog/FOOBAR LINE 30"
  ...
END IF

Alternatively, the components of a DLG status message can be obtained as separate elements:

DLG GET ".status",Stat;Rc
IF NOT Rc AND Stat THEN
  ! DLG v2 status available
  ! Stat contains last DLG status or async_status
  DLG GET ".status_seg",Seg$
  ! Seg$ contains the segment name (main or SUB or FN)
  DLG GET ".status_file",File$
  ! File$ contains the file name
  DLG GET ".status_line",Line
  ! Line contains the line number
  ...
END IF

When .async mode is used, .async_status may be queried after .async mode has been deactivated. The example below demonstrates how a nonzero .async_status is turned into a DLG runtime error so that the ON ERROR handler is invoked:

DLG SET ".async",1
...
...
DLG SET ".async",0
DLG GET ".async_status",Stat
IF Stat THEN FORCE ERROR Stat


Statistics

If DLG protocol v2 is active and JDLG 2.0 disconnects, typically at the end of a program, DLG statistics can be obtained by configuring a log file (eloqcore -log) and setting the G1 log level (-dG1).

DLG SET ".reset_statistics",0 may be called to log intermediate statistics (see below).

Example:

G1: --- DLG Statistics
G1: DLG calls     : 103573
G1: Client/server : 3723 (3.59457%)
G1: GET calls     : 96147
G1: GET cached    : 92450 (96.1548%)
G1: Values cached : 3699
G1: Values bytes  : 136915
Lines having a zero value are not logged.

  • DLG calls: The total number of DLG calls the program has issued.
  • Client/server: The number of network transmissions.
  • GET calls: The total number of DLG GET calls.
  • GET cached: The number of DLG GET calls which did not require a network transmission because the value was returned from the cache.
  • Values cached: The maximum number of cached values.
  • Values bytes: The maximum number of bytes used for cached values.
The ratio between DLG calls and client/server transmissions indicates how efficiently bulk mode has reduced the number of network transmissions. In the above example, 103573 DLG calls resulted in 3723 network transmissions, which is a ratio of ~3.6%. The previous DLG protocol would have used 100% (103573 network transmissions).

The ratio of GET calls and GET cached indicates how efficiently a program uses the cache. In the above example, the efficiency is ~96%, which means that only ~4% of all DLG GET calls required a network transmission.

In addition, a program may use the attributes below to programmatically obtain or reset the statistics:

.statistics : string, get

Returns the current statistics, as shown in the above example. Lines are separated by LF (ASCII 10).

Lines having a zero value are not returned. An empty string is returned if no statistics have been collected so far.

.statistics[] : integer or string, get

May be used to obtain a specific statistics entry, for example the number of DLG GET calls, which is 96147 in the above example.

When used with a positive index (starting with 1), the statistics value of the corresponding line is returned as integer. For example, line 3 contains the number of DLG GET calls, so DLG GET ".statistics[3]",St would set St to 96147 in the above example. Zero is returned if the index is out of range.

When used with a negative index (starting with -1), the statistics title of the corresponding line is returned as string. For example, line 3 contains the number of DLG GET calls, so DLG GET ".statistics[-3]",St_title$ sets St_title$ to "GET calls". An empty string is returned if the index is out of range.

.reset_statistics : integer, set

Resets the statistics. The value is ignored.

The current statistics are logged if the G1 log level is set and any statistics have been collected so far.



 
 
 
  Privacy | Webmaster | Terms of use | Impressum Revision: 2019-07-31  
  Copyright © 1995-2024 Marxmeier Software AG