0% found this document useful (0 votes)
19 views6 pages

Scripting Performance Best Practices

The document provides best practices for writing scripts in Maximo to ensure optimal performance. It recommends choosing efficient launch points and events, avoiding costly initialization from list tabs, managing dependencies between scripts, properly handling transactions, optimizing MboSet usage, and only logging if logging is enabled.

Uploaded by

Mahesh Varma
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views6 pages

Scripting Performance Best Practices

The document provides best practices for writing scripts in Maximo to ensure optimal performance. It recommends choosing efficient launch points and events, avoiding costly initialization from list tabs, managing dependencies between scripts, properly handling transactions, optimizing MboSet usage, and only logging if logging is enabled.

Uploaded by

Mahesh Varma
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Scripting Best Practices for Performance

Scripting allows users to extend maximo business logic using Python/JS or for that
matter any other JSR 223 compliant scripting language. All the script code gets
compiled to Java bytecode and are cached as part of Maximo runtime caches. So
when the script is invoked – it’s the cached bytecode that is executed by the JVM
using the JSR 223 bridge. Since the scripting code executes in the same thread as
other Maximo business logic (written in Java), a poorly written script code can
impact the performance of the system negatively. We have listed below a few
common mistakes that we have seen. In general we need to follow the Maximo
Performance guidelines as scripting in the end is equivalent to Maximo custom
code.

Choosing the right launch point and event


Launchpoints are script trigger points. Often choosing the right launch point can
help avoid certain performance issues in scripting. For example, in Maximo 75
release of scripting, there was no support for attribute value initialization. This led
many script developers to use the Object Launch point (OLP) Init event to initialize
the Mbo attribute values. Though functionally there was not problem with that
approach – it potentially can lead to performance issues when selecting a bunch
of Mbo’s (in list tab or APIs/MIF, Escalations). The OLP init event script gets
executed for every mbo that is selected in the MboSet – even though the
attribute whose value was getting initialized by the script was not even
used/shown. This can be avoided by changing the Object launch point to attribute
launch point – Initialize Value event. A sample script code for that is shown below
(thisvalue is the current attribute init value)

If priority is not None:


thisvalue=2*priority
The Mbo framework will invoke this script only when this attribute is referred to
by the code or the UI.

Another example of Launch point choice comes up in the Integration skipping


events use case. Often, we would use the user exit scripting to determine if we
need to skip an outbound integration message. However, at this point the system
has already entailed the cost of serializing the Mbo’s. Instead we should use the
Publish Channel Event Filter scripting which gets invoked right when the event is
triggered and way before any serialization of Mbos happen. A sample script below
shows the Event Filter scripting which works with the Mbo’s.
If [Link]().getString(“status”)==”APPR”:
evalresult=False
evalresult=True

Avoid costly Object init events if invoked from list tab


Often you may want to do costly Object init scripts only when the object is
initialized from the main tab (UI) and not from the list tab. This is because in such
cases the sample code below helps.

from [Link] import UIContext


if [Link]() is not None and
[Link]()==False:
…..costly initlization….
Watch out for conflicting launch point event scripts
Scripting framework would allow attaching multiple scripts to the same launch
point event. This poses a problem if the script code expects to execute in certain
order after or before certain other script in the same launch point event. Since
the Maximo event topic is an un-ordered map, the events get fired without a fixed
order. This can potentially cause issues if the order dependency is not managed
properly. One should evaluate the reason to attach multiple scripts for the same
launch point event – and evaluate if it makes more sense to combine them into
one script. The other option is to make sure there is no dependency between the
scripts.

Avoid calling save in middle of a transaction


This is a common coding pattern we see in scripts that can cause problems to
Maximo transactions and event firing.
Ideally when a maximo transaction is in progress, the script should try to be part
of that encompassing transaction. The mbos created/updated by a script are
automatically part of the encompassing transaction as long as those were created
from the script launch point mbo/related mbo. If we create a Mbo using the
[Link]().getMboSet(“…”) api would be outside the encompassing
transaction uness they are added explicitly to the encompassing transaction like
below

[Link]().add(<newly created a mboset>)

Calling [Link]() many times


We see a common programing mistake in the scripts where we are checking the
count of a MboSet multiple times. Note that the count() call ends up firing a sql
every time its called. So an optimal approach would be to invoke it once and store
the value in a var and reusing that var for subsequent code flow. An example is
shown below
Good code:
cnt = [Link]()
if cnt<=1:
[Link](“skipping this as count is “+cnt)

Bad code:
If [Link]()<=1:
[Link](“skipping this as count is “+[Link]())

Closing the MboSet


Maximo Mbo framework would always release the MboSets created after a
transaction is complete. That is true as long as all the MboSet’s were created as a
related set to launch point mbo or any related Mbo to the launch point mbo. If
however the MboSet is created using the [Link]().getMboSet(..)
api, the script code is responsible for closing and clearing that MboSet up. We
suggest a try finally block to do that (a sample shown below)

try:
….
finally:
[Link]()
If this is not done, it tends to start building up and may result in OOM errors.

Check if logging in enabled before logging


We often see logging done inside the script without checking the log level. A
sample below shows how that can impact performance

[Link](“count of mbos “+[Link]())

Now this unfortunately would result in [Link]() getting called – even


though the script logging is diabled.

from [Link] import MXLoggerFactory


logger = [Link]("[Link]”);
debugEnabled = [Link]()

if debugEnabled:
[Link](“count of mbos “+[Link]())

Starting 7612, we will add a function in the “service” variable that will allow one
to check this easily like below

If [Link]():
[Link](“count of mbos “+[Link]())

Common questions

Powered by AI

Maximo scripting can significantly impact system performance because script code, like custom Maximo code, is compiled to Java bytecode and executed in the same thread as other Maximo logic. Poorly written scripts can cause issues such as excessive processing or memory use. Mitigation practices include choosing appropriate launch points, avoiding unnecessary object initialization events, managing script execution orders at launch points, and checking logging levels before executing log statements .

Costly initialization in Maximo scripting should be restricted to necessary UI contexts to prevent unnecessary resource usage. For example, costly operations should only be executed when initializing from the main tab of the UI, not from a list tab, which can be achieved by checking the current UI context using psdi.common.context.UIContext methods, and conditionally executing initialization based on these checks .

Logging in Maximo scripting is essential for debugging and monitoring but can negatively impact performance, particularly if logs are written without checking whether logging is enabled. When logging is disabled but log statements still execute attached computations, such as MboSet.count(), it wastes resources. Therefore, scripts should check the logging level before performing log operations, thereby preserving performance .

Recent updates, such as starting with Maximo version 7.6.1.2, introduced a function in the ‘service’ variable that facilitates checking if logging is enabled more easily within scripts. This enhancement aids in reducing performance impacts by preventing unnecessary log computations when logging is disabled, which reflects a shift towards more efficient scripting practices .

Selecting the correct launch point is critical because it determines the conditions under which a script is executed, thereby directly affecting performance. Using the Object Launch point (OLP) Init event for attribute initialization, for example, can lead to performance issues when applied unnecessarily to all members of an MboSet. Instead, using an Attribute Launch Point which initializes values only when needed, reduces unnecessary executions .

The Maximo Mbo framework automatically releases MboSets created as related sets to the launch point or related Mbo after a transaction is complete. However, if an MboSet is created using MXServer.getMXServer().getMboSet(), script authors are responsible for manually cleaning up these MboSets using a try-finally block to prevent memory leaks and eventual Out-Of-Memory (OOM) errors .

Platform developers should aim to reduce dependency conflicts by consolidating multiple scripts into a single script where feasible. If scripts must remain separate, developers should ensure no interdependencies in execution order to prevent issues due to the unordered nature of event firing in Maximo's event map. This approach prevents execution conflicts and ensures consistent script behavior .

Attaching multiple scripts to the same launch point can lead to complications due to the unordered firing of events. This can cause issues if the scripts have dependencies on each other or require execution in a specific order, as the lack of order can disrupt expected behaviors. It is advised to combine scripts where possible or ensure independence between them to avoid such conflicts .

Calling MboSet.count() multiple times in a script is inefficient because each call executes an SQL statement, which can degrade performance. This can be avoided by assigning the count to a variable once and reusing it in later code, thereby reducing redundant SQL executions and improving script efficiency .

Proper management of transactions in Maximo scripting is crucial because scripts should ideally be part of the encompassing Maximo transaction. Issues arise when scripts call save within a transaction, causing disruptions in event firing and transactional integrity. Additionally, creating MboSets using MXServer.getMboSet() outside of the normal transaction flows can lead to disjointed transactions unless explicitly added to the transaction. This can result in incomplete updates or inconsistencies .

You might also like