Using the pooling support methods
xfNetLink .NET enables you to access pooling support methods defined by the COM+ API. There are five pooling support methods—Initialize, Activate, Deactivate, CanBePooled, and Cleanup —which are called automatically at specific times during the lifetime of the pooled object. This enables you to specify that certain actions be performed at certain times during the object’s creation and use.
To use the pooling support methods
1. | Write Synergy routines that perform the desired tasks. You can have several routines of the same type, if necessary (e.g., you might want different initialize routines for a customer object and an order object). The Synergy routines can be named anything you like. |
2. | Add the routines to the SMC by attributing the Synergy code, running dbl2xml, and then importing the XML file. (Or by entering data using the MDU.) Because these methods are called automatically, the method name must be one of the following: Initialize, Activate, Deactivate, CanBePooled, Cleanup. |
If you are attributing your code, you may need to use the name property of the xfMethod attribute to specify the correct pooling support method name; else, the method name will default from the Synergy routine name. If you have more than one routine of the same type (e.g., two initialize routines), you will need to use the id property of the xfMethod attribute to specify a unique method ID (because the method ID defaults from the method name). You can find more information about the name and id properties in xfMethod attribute. |
3. | Include the Synergy routines when you build your ELB. |
4. | Generate classes and build the assembly as you normally would, being sure to include the interface that contains the pooling support methods. Select the “Support pooling” check box in the Component Information dialog box in Workbench. (Or, if you are building the assembly from the command line, specify the -p option when you run the batch file.) |
The methods are listed below in the order in which they are called during the object’s lifetime.
Initialize()
status = Initialize()
status – a ^VAL value that indicates whether the initialization was a success. Returns 0 for success or 1 for failure.
If the return value is 1, the object is destroyed, an error is logged in the client-side log (if logging is turned on) and the Windows event log, and no other objects in the pool are created. When this happens, the pool will have been started, but there will be no objects in it. To recover from this state, you must stop the pool, fix the problem with the Initialize() method, rebuild the ELB, and then restart the pool.
Initialize() is called when the object is created. Use this method to prepare the environment by opening files, initializing global data, and so forth. Because Initialize() is called when the object is created, this method gets called only once per object, even if the object is reused. Compare with Activate().
Activate()
Activate()
Activate() is called when the object is requested by a client. This method can be used for code that should be executed when the object is actually used.
Both Activate() and Initialize() can be used for similar purposes—preparing the environment before using the object. The primary difference between them is that Activate() is called every time the object is allocated to a client, whereas Initialize() is called only once when the object is created.
Deactivate()
Deactivate()
Deactivate() is called when an object is released by the client. It can be used to reset the environment to a known state before an object is returned to the pool. Note that because objects can be reused, this method may be called multiple times. Compare with Cleanup().
status = CanBePooled()
status – a ^VAL value that indicates whether the object should be discarded or reused. Returns 0 if the object should be discarded; returns 1 if the object should be returned to the pool for reuse.
The CanBePooled() method is called after Deactivate(), and can be used to determine at runtime if an object can be re-used. For example, if Deactivate() encountered an error, CanBePooled() could indicate that the object should be discarded. Or, Deactivate() could be written to check how much effort is required to clean up an object before returning it to the pool. If the effort is excessive, and it would be more efficient to discard the object and create a new one, CanBePooled() would return 0.
CanBePooled() overrides the pool return setting in the application configuration file (see pool return in the Class Settings table).
Cleanup()
Cleanup() is called by the object’s disconnect() method. If the object’s connection is shared, it is called after the final disconnect(). It can be used to do the final object cleanup, such as closing files. This method is called only when objects are going to be discarded (i.e., pool return is set to false or CanBePooled() returns 0). If the object is going to be reused, use the Deactivate() method to perform cleanup-type activities.
The Cleanup() method is also called when socket communication with the client is unexpectedly lost. When the pool is created, the Cleanup() method is automatically registered with the XFPL_REGCLEANUP routine on the server. (This routine must be in your SMC; see XFPL_REGCLEANUP for more information.) Then, if there is a fatal error that causes xfServerPlus to lose socket communication with the client, xfServerPlus calls the Cleanup() routine before shutting down.
Although Cleanup() and Deactivate() can be used for similar purposes, there are two fundamental differences between them:
- Cleanup() is called only for objects that will be discarded, while Deactivate() is called both for objects that will be discarded and for those that will be reused.
- Cleanup() is automatically registered so that xfServerPlus can call it when socket communication is unexpectedly lost.