« Back

Events: How can performance and stability of event implementation be tested

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Events: How can performance and stability of event implementation be tested
community documentation adoscript trigger
Answer
3/27/14 12:30 PM
How is it possibile to validate the scalability of event implementations in ADOxx? In the test-case at hand, a model with 100 objects in different view modes is established, the view switch takes time to be performed. The event used is "AfterUpdateGrObjects".

RE: Events: How can performance and stability of event implementation be te
Answer
4/8/13 12:24 PM as a reply to Anonymous.
For testing of performance and scalability, a automated testscript as the one below can be used to go through the view modes, analyse the classes available in each and create a predefined number of objects in the model currently open. For the test runs, the number of for instances per class and view have been defined in the header, additional code to be performed after each instance creation can be added accordingly. The script helps when test-driving the up-scale of the implementation to potentially analyze clitches in performance when it comes to event implementation.

Highlights:
- Configuration of model size
- Validation of "core" events and performance
- Additional custom code can be added
- Log file is written to a dockable window in the modelling tool, and provided at the end as an EDITBOX to save and further analyse

Limitations:

- Relation classes are currently not considered and need to be tested separetly

To run the code, integrate it in a menu item or run directly from the AdoScript Debug Shell:
EXECUTE file: ("PATH_TO_LOCAL_FILE\\NumberOfObjects.asc")

 1# create a debug window to display result messages
 2SETG sDebugWINID: ("debug")
 3SETG nNumberOfObjects: (40)
 4SETG lSkipClasses: ("Organisation")
 5SETG xPos: (2)
 6SETG yPos: (2)
 7SETG nCounter: (1)
 8SETG logMessages: ("")
 9DEBUG_PRINTER debugmessage: ("START OF LOGGING for " + STR nNumberOfObjects + " each model contruct per view")
10CC "AdoScript" CREATE_OUTPUT_WIN winid: (sDebugWINID) title:"Performance Debug"
11DEBUG_PRINTER debugmessage: ("###############################################")
12DEBUG_PRINTER debugmessage: ("New performance test started") 
13# make sure that a model is loaded before starting
14CC "Modeling" GET_ACT_MODEL
15DEBUG_PRINTER debugmessage: ("modelid: " + STR modelid)
16IF (modelid = -1) {
17  DEBUG_PRINTER debugmessage: ("No test model open .... EXITING")
18  EXIT
19}
20SET nTestModelID: (modelid)
21 # get model info
22CC "Core" GET_MODEL_INFO modelid: (nTestModelID)
23DEBUG_PRINTER debugmessage: ("modeltype: " + modeltype) 
24SETL sTestModelType: (modeltype)
25# get all view modes
26CC "Core" GET_ALL_MODES_OF_MODELTYPE modeltype: (sTestModelType) sep:"|"
27DEBUG_PRINTER debugmessage: ("available_view_modes: " + modenames) 
28SETL lViewModes: (modenames)
29# interate through modes
30FOR sModeName in: (lViewModes) sep:"|" {
31  CC "Modeling" SET_VIEW_MODE mode-name: (sModeName)
32  CC "Core" GET_ALL_CLASSES_OF_MODE modeltype: (sTestModelType) modename: (sModeName)
33  DEBUG_PRINTER debugmessage: ("available_classes: " + classids) 
34  SETG lClassIDs: (classids)
35  # iterate through all classids
36  FOR sClassID in: (lClassIDs) {
37    # get the class name and check whether a relation
38    CC "Core" GET_CLASS_NAME classid: (VAL sClassID)
39    # if relation, skip
40    IF (isrel != 1) {
41      FOR varName from:1 to: (nNumberOfObjects) {
42        SETL sNewObjName: (classname + "-" +STR nCounter)
43        CC "Core" CREATE_OBJ modelid: (nTestModelID) classid: (VAL sClassID) objname: (sNewObjName)
44        DEBUG_PRINTER debugmessage: ("create object: " + sNewObjName) 
45        CC "Modeling" SET_OBJ_POS objid: (objid) x: (CM xPos) y: (CM yPos)
46        DEBUG_PRINTER debugmessage: ("position object: " + sNewObjName) 
47        ################# SECURE TROPOS SPECIFIC CODE TO IMMIDATE THE EVENT CODE - START #################
48        CC "Core" SET_ATTR_VAL objid: (objid) attrname: ("_View") val: (sModeName)
49        DEBUG_PRINTER debugmessage: ("SECURETROPOS_SPECIFIC - set view mode in object: " + sNewObjName) 
50        ################# SECURE TROPOS SPECIFIC CODE TO IMMIDATE THE EVENT CODE - END #################
51        SETG xPos: (xPos + 2)
52        SETG nCounter: (nCounter + 1)
53      }
54    }
55    SETG xPos: (2)
56    SETG yPos: (yPos + 2)
57  }
58  SETG yPos: (2)
59  DEBUG_PRINTER debugmessage: (".... SWITCHING VIEW MODE ....") 
60
61}
62CC "AdoScript" EDITBOX text: (logMessages) title:"Logged information" oktext:"Close" fileeditor
63
64DEBUG_PRINTER debugmessage: ("###############################################") 
65
66
67
68#*************************************************************************************#
69#                                                                                     #
70  PROCEDURE DEBUG_PRINTER debugmessage:string
71                                                                               #
72#*************************************************************************************#
73
74{
75   CC "Application" GET_DATE_TIME date-format:"DD.MM.YYYY" time-format:"HH:MM:SS"
76   CC "AdoScript" OUT winid: (sDebugWINID) text: (time + ": " + debugmessage + "\n")
77   SETG logMessages: (logMessages + time + ": " + debugmessage + "\n")
78}
79#*************************************************************************************#
Attachments: NumberOfObjects.asc (3.6k)

Event Logging
Answer
4/9/13 5:52 AM as a reply to Anonymous.
As a means for event logging the CREATE_OUTPUT_WIN command of the AdoScript message port can be used to a) open a new dockable window and b) continously log the event streams that are captured. This visualisation could potentially highlight performance issues in the event implementation.

In the following the steps are explained to set up event logging, including code snipplets for the setup and the actual listening.

1. Add the event log window and procedure to the "AppInitialized" event in the Library attribute "External coupling"
 1#All configuration and implementations that need to be triggered during startup
 2ON_EVENT "AppInitialized" {
 3  # create the dockable window for the output stream
 4  CC "AdoScript" CREATE_OUTPUT_WIN winid:"EVENTLOG" title:"Event Logging"
 5 
 6  # establish a global procedure as a helper implementation for timestamped logging
 7  PROCEDURE global EVENT_LOG msgType:string message:string {
 8    CC "Application" GET_DATE_TIME date-format:"dd/mm/yyyy" time-format:"hh:mm:ss"
 9    SET currentDateTime: ((date) + " " + (time))
10    CC "AdoScript" OUT winid:"EVENTLOG" text: ("[" + (msgType) + "@" + currentDateTime + "]: " + (message) + "\n")
11  }
12  # Initial event log message for the "AppInitialized" event
13  EVENT_LOG msgType:"EVENT_LOG" message: ("AppInitialized")
14  # Perform other things for the event
15}


2. Add event logger messages to the events. This should be done before anything else is performed for the event, to limit the dependency on other implementations
 1ON_EVENT "BeforeCreateRelationInstance" {
 2  # Log event plus all parameters set for the event
 3  EVENT_LOG msgType:"EVENT_LOG message: ("BeforeCreateRelationInstance with parameters frominstid : " + STR frominstid + " toinstid : " + STR toinstid + " relationclassid : " + STR relationclassid + " componentid " + STR componentid)
 4  # Perform other things for the event
 5}
 6
 7ON_EVENT "SetAttributeValue" {
 8  # Log event plus all parameters set for the event
 9  EVENT_LOG msgType:"EVENT_LOG" message: ("SetAttributeValue with parameters instid : " + STR instid + " attrid : " + STR attrid + " modelid : " + STR modelid + " attrtypeid : " + STR attrtypeid + " oldval : " + oldval)
10  # Perform other things for the event
11}


This can be done for each event available in ADOxx. Details on the events available and their parameters are available in the online help. Please use "SetAttributeValue" carefully, since it is trigger in any kind of interaction that results in an update of an attribute on instance and model level (moving of objects, drawing, etc.). The attached screenshot shows the result of the above.
Attachment

Attachments: EventLog_Screen.PNG (107.1k)

Event "SetAttributeValue" - Special Consideration
Answer
4/9/13 7:29 AM as a reply to Anonymous.
Specific considerations are necessary when implementing an AdoScript that is triggered by the "SetAttributeValue" event. The event is triggered by any kind of update/modification on attribute values (by the user or platform) when modifying the model and instances. This is especially of interest in the case of move events, where the event is triggered for any kind of position update and also redraw functions (creation/build up of model).

To implement an AdoScript for the event make sure that you:
- know exactly the cases the AdoScript is implemented for (validation against the attribute ID and its type) to prevent unncessary processing
- make sure that user interaction scripting is targeted to the specific cases (in case of a script during move of objects and relations, the event is continously triggered and the scope is lost)
- for performance considerations, make sure that the script loading is done in effective way, reading and executing AdoScripts on the event potentally results in an unstable and/or time-consuming implementation of your method. It is recommended to pre-load script using the PROCEDURE mechanism and just trigger the respective procedure for each case.
- run type checking (attributeID first and then all other checks) in the ON_EVENT definition, this makes sure that scripts that are not necessary are not loaded just for the checking purpose

The event definition can be found below.
Event name: "SetAttributeValue"
Parameters:
instid : integer (ID of the changed instance)
attrid : integer (Attribute ID)
modelid : integer (ID of the model containing the changed instance.
attrtypeid : integer (Attribute type code)
0 INTEGER
1 DOUBLE
2 STRING
3 DISTRIBUTION
4 TIME
5 ENUMERATION
6 ENUMERATIONLIST
7 CORE_LONGSTRING
8 PROGRAMCALL
9 INTERREF
10 EXPRESSION
11 RECORD
12 ATTRPROFREF
13 DATE
14 DATETIME
15 CLOB
oldval : string (The original value (as string))
This is the Core internal value (not UI value).
For attributes of type RECORD this is always an empty string.
The new value can be determined via the "Core" MessagePort.
Exit value
N/A

EXAMPLE Implementation:

 1ON_EVENT "SetAttributeValue" {
 2  EVENT_LOG msgType:"EVENT_LOG" message: ("SetAttributeValue with parameters instid : " + STR instid + " attrid : " + STR attrid + " modelid : " + STR modelid + " attrtypeid : " + STR attrtypeid + " oldval : " + oldval)
 3  # CASE A: Validate against AttrID and ClassID - first validation against AttrID, the right-hand part is preloaded in "AppInitialized"
 4  IF (attrid = nPreLoadedAttrIDACase) {
 5    # ClassID is not part of the event, in case of this attribute ID, get it and only run for specific classes
 6    CC "Core" GET_CLASS_ID objid: (instid)
 7    SET nClassID: (classid)
 8    # Validation against PreloadedClassID, done "AppInitialized" event
 9    IF (nClassID = nPreloadedClassIDACase) {
10      # perform action for Case A
11      ...
12    }
13  }
14  # CASE B: Validate against AttrID only
15  IF (attrid = nPreloadedAttrIDBCase){
16    # perform action for Case B
17    ...
18  }
19}