Document Properties
KbidX28817
Last Modified11-Apr-2019
Added to KB12-Oct-2018
Public AccessEveryone
StatusOnline
Doc TypeSupport Articles
Product
  • ICM 7.6
  • ICM 7.7
  • ICM 7.8
  • ICM 7.9
  • ICM 7.10

Support Article - Using Instance Variables in Custom Pipelets

1 Introduction

This document replaces the outdated article with the ID 9765R and the same title.

Using pipelet instance variables can have undesired effects when combined with multithreading, as session specific information (like user names) may be displayed in other sessions, thus causing serious threats to data security. This document provides information on using pipelet instance variables and local variables.

2 Background

Whenever the pipeline processor loads a pipeline to process a request, one pipelet instance is created for each pipelet in the pipeline.

A pipeline can contain two or more items of a specific pipelet. Upon loading the pipeline, one instance for each of the identical pipelets is created. This allows a variety of simultaneous configurations (i.e., init parameters) for a specific pipelet. For example: If you place the pipelet A twice in your pipeline, you will be able to have two independent pipelet A configurations.

When programming pipelets, keep in mind that they have to work in a multithreaded environment. Every storefront request that executes a pipeline results in a new thread. The total number of threads is limited since the execution threads are pooled in a thread pool. In a production environment with heavy storefront traffic, a pipeline is very likely to be executed simultaneously by a large number of threads (especially if pagecaching is not used). Consequently, a potentially large number of concurrent threads may need to execute the pipelet you want to develop. So create your pipelets in a multithread-safe manner.

3 Instance Variables and Local Variables in Pipelets

3.1 Pipelet Instance Variables

Pipelet instance variables (i.e., attributes of your pipelet class) are visible in the scope of the whole pipelet class. As there is only one pipelet instance for each pipelet, a pipelet instance variable has only one instance too. All (request) threads that execute the pipelet therefore share into a single instance of an instance variable. If you decide to use a pipelet instance variable, you have to synchronize access to the variable to ensure data consistency.

None of the standard enfinity pipelets uses instance variables for another reason than for storing read-only configuration values (that are initialized in the pipelet's init() method).

3.2 Local Variables

Local variables are declared in the scope of your methods. Intershop highly recommends using local variables for all data that needs to be modified within your pipelet. Local variables ensure that each (request) thread has its own variable on the Virtual Machine stack. Moreover, you do not need to synchronize access to these variables (since they are not global and shared).

4 Code Samples

The following snippets of a sample pipelet show two approaches to retrieve and afterwards store the last name of a buyer for a buyer profile.

The first incorrect approach stores the last name's value in a pipelet instance variable:

public class WillNotWork extends Pipelet
{
  // a pipelet instance variable 
  private String name;

  // the execute method, called by multiple threads concurrently
  public int execute(PipelineDictionary dict)
  {
    // get the name of the buyer from its profile and store it in an instance variable
    Buyer buyer = (Buyer)dict.get("Buyer");
    name = buyer.getProfile().getDataSheet().getLastName();
  
    // do something fancy here
    
    buyer.getProfile().getDataSheet().setLastName(name);
    return PIPELET_NEXT;
  }
}

When executed through concurrent storefront requests (multiple threads), this pipelet will randomly change last names for the profiles of buyers browsing the storefront.

Note

Since this approach operates perfectly with one thread, this serious mistake may remain undetected throughout the whole development cycle. However, as soon as the installation goes public and is exposed to massive storefront requests, the mistake is bound to cause considerable troubles.


The second correct approach uses a local variable instead of an instance variable:

public class WillWork extends Pipelet
{
  // the execute method, called by multiple threads concurrently
  public int execute(PipelineDictionary dict)
  {
    // get the name of the buyer from its profile and store it in an instance variable
    Buyer buyer = (Buyer)dict.get("Buyer");
    String name = buyer.getProfile().getDataSheet().getLastName();

    // do something fancy here

    buyer.getProfile().getDataSheet().setLastName(name);
    return PIPELET_NEXT;
  }
}

Since this choice guarantees that every thread has its specific version of the variable, the pipelet does not mix up values of different threads anymore.


Disclaimer

The information provided in the Knowledge Base may not be applicable to all systems and situations. Intershop Communications will not be liable to any party for any direct or indirect damages resulting from the use of the Customer Support section of the Intershop Corporate Web site, including, without limitation, any lost profits, business interruption, loss of programs or other data on your information handling system.

Customer Support
Knowledge Base
Product Resources
Support Tickets