skip to main content
OpenEdge Development: ADM and SmartObjects
Developing Your Application's Business Logic : Managing SmartDataObjects in distributed mode
 
Managing SmartDataObjects in distributed mode
This section describes how to manage SmartDataObjects in a distributed mode, using AppServer.
As described in the “Running SmartDataObjects in a distributed environment” section, you can compile a SmartDataObject into database‑aware and non‑database‑aware versions, with sections that contain database references compiled in or out depending on whether the SmartDataObject version will be run client/server, on a client that talks to an AppServer, or on an AppServer.
A SmartDataObject client proxy contains the code needed to connect to an AppServer Broker, to run the complete SmartDataObject on that AppServer, and to send requests through that connection to retrieve and update database records from the database through the AppServer. To enable a SmartDataObject for this use, follow the steps below, either before saving the master for a new SmartDataObject from the AppBuilder or when editing the master for an existing SmartDataObject. The procedure connects to an AppServer Broker, to run the complete SmartDataObject on that AppServer and send requests through that connection to retrieve and update database records from the database through the AppServer.
To connect to an AppServer Broker:
1. Select the Procedure settings button from the AppBuilder toolbar.
The Procedure Settings dialog box appears.
2. Check the AppServer Aware toggle box.
3. In the Partition fill-in field, enter the Application Service name that this SmartDataObject is to be associated with. (The Partition field appears only if you are working with a SmartDataObject master.)
This runs all instances of that SmartDataObject on the AppServer. To change this for a single instance, use the SmartDataObject’s Partition instance property. For example, you might do either of the following:
*Set the procedure properties in the SmartDataObject so all instances except one run on the AppServer. Then set the instance property for that instance to none (that is, it runs locally).
*Leave the procedure property unset in the SmartDataObject so all instances except one run locally, and set the instance property for that instance to run on the AppServer.
If the AppServer is not known earlier or is variable, you can use the Partition instance property to set it when you assemble the application.
SmartDataObject deployment files
The ADM support files are shipped only with the Windows versions of the product. This is because you normally develop SmartObjects only with the AppBuilder, which generates a great deal of code for SmartObjects. Because the include files and super procedures that form the ADM become in effect a part of the final application, it is essential you use the same version of those files to build and run your application on all platforms. As a result, you must port needed super procedures to each deployment platform along with the application code. To test SmartDataObjects on an AppServer on which the Progress software is not installed, you must put these files into an adm2 directory on that machine relative to its PROPATH.
You need the following super procedures to run standard SmartDataObjects on an AppServer, either from a Progress client, from WebSpeed®, or from a non‑Progress client such as Java:
*smart.r
*query.r
*data.r
To facilitate testing distributed applications on a single Windows NT workstation (where you can run both a Progress client and a Progress AppServer session), these three super procedures reside in both the tty directory and the gui directory.
You must move all SmartDataObjects to be run on an AppServer to that machine. Usually you do not need to recompile the super procedures or SmartDataObjects on the target machine, unless it is a platform to which Progress .r code is not portable. However, if it is necessary or desirable to recompile the SmartObject super procedures or the application’s SmartObjects on the target machine, you also must move the following source files, as well as the custom subdirectory and its contents, to that machine, in a src\adm2 directory relative to the PROPATH:
*smart.i
*query.i
*data.i
*smrtprop.i
*qryprop.i
*dataprop.i
*smrtprto.i
*qryprto.i
*dataprto.i
*smart.p
*query.p
*data.p
When you run a SmartDataObject on an AppServer, the supporting super procedures smart.r, query.r, and data.r are started automatically, just as on the client, and are left running in support of any SmartDataObjects that are run for the duration of that AppServer session. All the super procedures run stateless, without maintaining any data specific to an individual client, thus the same AppServer process can service several clients in succession, even when each client expects to have exclusive use of that AppServer for the duration of its connection. As a result, your application incurs the overhead of starting super procedures once per AppServer session. (You can even run these procedures persistently as part of the session startup.)
Service choices and SmartDataObject execution
A SmartDataObject that is part of a client‑side application runs on the client if either of the following is true:
*No Application Service is defined for the SmartDataObject.
*The SmartDataObject is AppServer‑aware but its Configuration option is set to Local in the PRO*Tools Application Partition Deployment utility.
A SmartDataObject that runs only on the client has its own database connection and accesses the database through that connection.
However, if the SmartDataObject is AppServer‑aware and the Application Service on an AppServer host machine is set to an actual service, the client SmartDataObject’s initializeObject procedure establishes a connection to that AppServer, then runs a copy of itself (that is, a file with the same filename) on the AppServer. (If the client is running the client‑only SmartDataObject, with the _cl suffix, that suffix is ignored when locating the matching SmartDataObject on the AppServer.) The SmartDataObject on the AppServer opens its database query as part of its own initialization. For more information, see OpenEdge Development: Open Client Introduction and Programming.
When the client‑side SmartDataObject runs its openQuery function, the sendRows procedure executes. How this procedure executes depends on whether the application is running in client/server mode or AppServer mode. In client/server mode, when the client uses its own database connection, sendRows retrieves rows from the database and populates the RowObject temp-table, which is then accessed by other objects on the client.
In AppServer mode, however, the sendRows procedure runs clientSendRows. This in turn runs serverSendRows in the AppServer SmartDataObject, which returns the RowObject temp-table to the client. The client‑side SmartDataObject uses the temp-table until it is finished with it. It can then either simply exit or execute the closeQuery function, which disconnects it from the AppServer. The same procedures are used to update one or more rows in the table or to add or delete rows as in client/server mode. When the Commit function is run on the client side, it in turn runs serverCommit in the AppServer SmartDataObject, passing a temp-table containing all modified, deleted, or added rows. The serverCommit procedure writes the records back to the database as described in the SmartDataObject description or, if the update fails, returns any errors to the client.
When a 4GL client running a client‑side SmartDataObject connects to the same object on an AppServer, the support code for those procedures contains all of the code needed to get updates back to the server. (The support code is located in data.i, which is compiled into each SmartDataObject, and the super procedure data.p.) You can use the same calls from a non‑Progress client (for example, a Java client using a proxy built by ProxyGen). However, in this case, if the client process performs any update operations, it is its responsibility to return to the AppServer SmartDataObject an update temp-table that contains those changes. The update temp-table (called RowObjUpd in the 4GL code) must be of the same form as the RowObject temp-table that is passed to the client with the original rows. See the “SmartDataObject query and update operations” section for specifications of this temp-table.
Special considerations apply when you access a SmartDataObject from a Java application. For details, see the “Java applications and SmartDataObjects” section.
AppServer session operating modes and SmartDataObjects
In a distributed application, a SmartDataObject inherits its operating mode—state‑aware, stateless, or state‑reset—from the AppServer it uses to access its database. (This is the default behavior; you need not configure the SmartDataObject specially for this to happen.) These three modes operate as follows:
*In state‑aware mode, a SmartDataObject connects to an AppServer session and binds it for the entire length of the SmartDataObject’s client connection. At the end of the connection, the context (state) of the AppServer session remains and can be used by the next connection to that session. In this mode, it is unnecessary for a new connection to the AppServer session to re‑establish context; however, it might be difficult to design a system in which each user can benefit from the context left by the previous user.
*In stateless mode, a SmartDataObject connects to an AppServer session but binds it only briefly to do the following:
*Re‑establish the context of the AppServer session at the end of its last request
*Make a request
*Save the context for the next request
Between requests, nothing is bound. In this mode, each individual AppServer request might take slightly longer, but many clients can share fewer AppServer sessions with minimal performance degradation.
*In state‑reset mode, the AppServer session’s state is reset to the initial state after each connection. This mode is particularly useful for applications that do not use SmartDataObjects.
In some cases, you might want a SmartDataObject to run in a state‑aware mode even though the AppServer is running in stateless mode. For example, a SmartDataObject might have a query that is so complex that the overhead of re‑establishing it at every use degrades performance. To request state‑aware mode explicitly, you set the Force to Stateful Operating Mode instance property in the SmartDataObject’s instance properties dialog box. This property causes the SmartDataObject to run in state‑aware mode even though AppServer session is running in stateless mode. See the “SmartDataObject instance properties” section.
Note: A SmartDataObject executes exactly the same regardless of its operating mode.