You are on page 1of 7

BOPF Performance Guideline

Content

Content
1. Scope
o 1.1. In Scope
o 1.2. Out of Scope
2. Overview
3. Configuration
o 3.1. Property Handling
3.1.1. Property Change Notifications
3.1.2. Property Determination
o 3.2. Read Nodes
o 3.3. Write Nodes
o 3.4. Loadable Node Groups
o 3.4. Field Mapping Reuse Component
o 3.6. Group Names of data includes
4. Implementation
o 4.1. Mass Data Processing
o 4.2. Data References
o 4.3. Message Object Handling
o 4.4. Typed Buffer Implementation
o 4.5. Types Data Access Implementation

1. Scope
1.1. In Scope
The purpose of this guideline is to provide BOPF users with some basic
rules to help them increase the performance of their objects. This
guideline is valid for AP and BS BOPF.

1.2. Out of Scope


It is impossible to define rules on how to obtain the optimal performance
of a system. Depending on the actual use case, there might be several
options

2. Overview Unable to render embedded


object: File (logo_byd.png) not found.
The Business Object Processing Framework (BOPF) represents a generic
implementation of most the ESA Service Provider interfaces. In order to
offer a generic implementation it uses its own set of metadata. The BOPF
is the tool that bridges the gap between the ESA Repository and the

business logic by using an engineering approach. Since it is widely used,


its performance improvement is vital to reaching the overall performance
goals of the Application Platform. The following two approaches can be
identified:

All of the internal BOPF metadata influences the runtime because it


controls which parts of the framework are active and which checks
are performed during runtime.
The application implementation can have a major impact on the
overall performance.

3. Configuration
3.1. Property Handling
The Property Handling from the Service Provider (or Service Manager in
BS-BOPF) point of view consists of two parts. The Service Provider can
notify about property changes out of every Core Service that provides a
Change Handler (e.g. Modify). If the Service Consumer wants to retrieve
the currently valid properties the Core Service RETRIEVE_PROPERTIES is
called. Because not all consumers
are evaluating the properties the property determination should be done
only when the corresponding Core Service is called.
3.1.1. Property Change Notifications
To inform the consumer of property changes is done the same way like to
inform about data changes of node attributes. It is up to the Consumer to
read the changed data or properties in order to refresh for example read
buffers. In order to enable the BOPF to notify correctly about property
changes, the dependency between data changes and resulting property
changes has to be modeled in BOPF. Otherwise either too much or even to
less property changes are notified, which may lead to a wrong Service
Consumer behavior. Therefore Property Change Triggers should be
maintained in BOPF to ensure functional correctness
and improve the overall performance.
3.1.2. Property Determination
The determination of properties shall only be done within Determinations
configured at the execution time "before retrieve". The corresponding
Determination shall only change data of the BOPF Property Node
generated at each standard node. Note that it is not necessary to delete
all properties before creating new once. If the buffer detects an already
existing entry during
created it performs automatically an update of the corresponding entry.

3.2. Read Nodes

Read Nodes is a concept to pre-fetch data into a read buffer. Each action,
determination and validation can have every other node of the model as
read node. If the read node is not the same node the part of business
logic belongs to, an association needs to be assigned. The BOPF uses the
association to navigate to the node instances that have to be pre-fetched
into
the read buffer.
Note: The read nodes are not evaluated at runtime if they are marked as
modeled only. The following rules should be taken into account:

Do not define more than one non-loadable node as a read node


within a group of loadable nodes. Since all of the nodes in a loadable
node group are always loaded together in the read buffer it does not
make sense to define read nodes between them.
Do not define nodes which are not using a read buffer as read
nodes. If the buffer does not cache data that is not changed, the
definition of read nodes will result in additional database accesses.
Read nodes do not have any advantage if the application logic is
already using mass data accesses. That means if a determination
does not perform, for example, single RETRIEVE-calls but one
RETRIEVE call, then pre-fetch logic will not improve the
performance.

3.3. Write Nodes


Write nodes are similar to read nodes. All of the nodes that are defined as
write nodes will be locked before the business logic is called. The lock
mode is defined on every determination and action. If write nodes are not
defined, the framework will lock the corresponding node instance when
the first modification occurs.
Note: Write nodes are not evaluated at runtime if they are marked as
modeled only. If possible, only define lockable nodes as write nodes, even
if that specific node is not changed. For every node that cannot be locked
separately, the framework will navigate to the next lockable node and
check if a lock needs to be requested. This navigation is done for every
write node
before the execution of the determination and action respectively. Note
that Write Nodes should be used for actions if they are either S&AM
relevant or have extra action validations assigned. With that the
Framework ensures that the corresponding node instances are locked
before the check whether the action can be executed is performed. This
ensures furthermore that the buffer content is up to date and the check is
really done on the right data.

3.4. Loadable Node Groups


A loadable node and all its sub-nodes that are not transient and are not
loadable are defined as a loadable node group. The default is that every

persistent node is loadable, meaning that all groups consist of exactly one
node, which means that the read buffer of each node is managed
separately. This is the best approach regarding memory consumption and
performance. The
only use case to change is if two or more nodes use the same database
table. All of the nodes that use the same database table and are linked
with compositions have to be in the same loadable node group.

3.4. Field Mapping Reuse Component Unable to render


embedded object: File (logo_byd.png) not found.
The usage of the generated mapping is almost twice as fast as the generic
field mapping that is provided by the BOPF. Therefore, it is recommended
to use the Field Mapping Reuse Component.

3.6. Group Names of data includes


DDIC Groups shall be used to get the best possible performance during
the access of data within the Buffer and Data Access Layer. With the
Group it is possible to use a MOVE with the group name instead of a
MOVE-CORRESPONDING. The following groups shall be created within the
Combined Structure of each node:

NODE_DATA for the include of the Data Structure


TRANSIENT_NODE_DATA for the Data Structure containing all
transient attributes The second one is optional because it is not
mandatory to have an own structure for the transient attributes of a
node. Note that it is recommended to generate the Combined
Structure. In this case the group names are added automatically.

4. Implementation
4.1. Mass Data Processing
The BOPF is completely enabled for mass data processing. To take
advantage of the mass data processing, all parts of an application have to
be implemented to support mass data processing. Therefore, the
application implementation only needs to work with mass calls. In theory,
the number of calls of each method is independent of the number of node
instances being processed.

Right: the call is done for all keys at once:


io_read->retrieve(
EXPORTING
iv_node = if_constant=>sc_node
it_key = it_key
IMPORTING
et_data = lt_node ).

LOOP AT lt_node INTO ls_node.


...
ENDLOOP.

Wrong: the retrieve is done separately for each key:


LOOP AT it_key INTO ls_key.
CLEAR lt_key.
APPEND ls_key TO lt_key.
io_read->retrieve(
EXPORTING
iv_node = if_constant=>sc_node
it_key = lt_key
IMPORTING
et_data = lt_node ).
READ TABLE lt_node INDEX 1 INTO ls_node.
CHECKsy-subrc.
...
ENDLOOP.

4.2. Data References


Data references are used for internal changes of object instances. If a
node instance is created or updated, a reference to the corresponding
structure is required. There are different approaches to get this reference.
Note: Both approaches differ by factors regarding performance. The
following code example illustrates that:

Right: the reference is set once and no data is copied:


io_read->retrieve(
EXPORTING
iv_node = if_constant=>sc_node
it_key = it_key
IMPORTING
et_data = lt_node ).
GET REFERENCE OF ls_node INTO ls_node_r.
LOOP AT lt_node INTO ls_node.
ls_node-attribute = new_value.
io_modify->update(
iv_node = if_constant=>sc_node
iv_key = ls_node-key
is_data = ls_node_r ).
ENDLOOP.

Wrong: each loop creates a new data reference


io_read->retrieve(
EXPORTING
iv_node = if_constant=>sc_node
it_key = it_key
IMPORTING

et_data = lt_node ).
LOOP AT lt_node INTO ls_node.
CREATE DATA ls_node_r.
ls_node-attribute = new_value.
MOVE-CORRESPONDING ls_node TO ls_node_r.
io_modify->update(
iv_node = if_constant=>sc_node
iv_key = ls_node-key
is_data = ls_node_r ).
ENDLOOP.

4.3. Message Object Handling


The BOPF uses a message object to transport messages through the call
stack. Note: This approach is different from ESA when a Message Handler
is used. More than one message object instance can exist at runtime.
Each instance stores messages dependently of other instances.

Right: no new message object is created:


METHOD method1.
DATA lo_message TYPE REF TO /BOPF/IF_FRW_MESSAGE.
CLEAR eo_message.
...
IF lo_message IS BOUND.
IF eo_message IS BOUND.
eo_message->add( lo_message ).
ELSE.
eo_message = lo_message.
ENDIF.
ENDIF.
...

Wrong: a message object is always created, even if the messages


are not created:
METHOD method1.
eo_message = /bopf/cl_frw_factory=>get_message( ).
...

Wrong: the message object reference is overwritten; message loss


is possible:
METHOD method1.
...
io_read->retrieve(
EXPORTING iv_node = if_constant=>sc_node
it_key = it_key
IMPORTING et_data = lt_node
eo_message = eo_message ).
...
io_read->retrieve(

EXPORTING iv_node = if_constant=>sc_node2


it_key = lt_key
IMPORTING et_data = lt_node2
eo_message = eo_message ).

4.4. Typed Buffer Implementation


Either the BOPF provided generic buffers or the typed generated buffers
shall be used. Currently there is no known use case that can only be
solved by implementing an own typed buffer. Therefore contact the BOPF
team before starting an own implementation.

4.5. Types Data Access Implementation


Either the BOPF provided generic data access classes
(/BOPF/CL_DAC_TABLE) or the typed generated data access classes shall
be used if applicable. Own implementations should only be used if the
required functionality is not covered by the provided data access classes.
Such a use case is for example to store one node into two data base
tables. It is recommend to contact the BOPF team before starting an own
implementation.

You might also like