Tuesday, May 19, 2009

Creating and managing ColdFusion threads

Creating and managing ColdFusion threads

From : http://livedocs.adobe.com/

You use the cfthread tag and the Sleep function to create and manage ColdFusion threads. You manage a thread by doing the following actions:

  • Start the thread running.
  • Temporarily suspend the thread's processing. This action is useful if one thread must wait for another thread to do processing, but both threads must continue processing without joining.
  • End a thread. You typically end a running thread if there is an error, or if it is still processing after a long time.
  • Have the page or a thread wait until one or more other threads have completed processing before proceeding with its processing, called joining the threads. You typically join threads when one thread requires the results from another thread. For example, if a page uses multiple threads to get several news feeds for display, it joins all the feed threads before it displays the results.

Each thread runs the code inside a cfthread tag body and normally exits when the tag body code completes processing.

Starting a thread

You start a thread by using a cfthread tag with an action attribute value of run. CFML code within the cfthread tag body executes on a separate thread while the page request thread continues processing. Only the page thread can create other threads. A thread that you create with a cfthread tag cannot create a child thread, so you cannot have multiple nested threads.

Optionally, when you start the thread, you can specify a priority level of high, normal (the default), or low to specify the relative amount of time that the processor should devote to the thread. Page-level code always runs at normal priority, so you can give your threads more or less processing time than the page.

For more information on using thread attributes, see The Attributes scope and thread attributes.

Suspending a thread

In some cases, one thread must wait until a second thread completes some operations, but should not wait until the second thread completes all processing, so you cannot just join the threads. For example, one thread might do initialization that is required by multiple threads, and then it might continue with additional processing. The other threads could suspend themselves until initialization is complete.

The Sleep function and cfthread tag with a sleep action attribute provide two equivalent mechanisms for doing such synchronization. They suspend the thread processing for a specified period of time. A code loop could test a condition variable and sleep for a period before retesting the condition. When the condition is true (or a value is reached, or some other test is valid), the program exits the loop and the thread continues processing.

The following example shows how one thread could use a sleep function to wait for a second thread to perform some actions.


--- ThreadA loops to simulate an activity that might take time. ---







--- ThreadB loops, waiting until threadA finishes looping 40000 times.
the loop code sleeps 1/2 second each time. ---


thread.sleepTimes=0;
thread.initialized=false;
while ((threadA.Status != "TERMINATED") && (threadA.j < initialized="true;">


Join the page thread to thread B. Don't join to thread A.---


--Display the thread information. -

current threadA index value: #threadA.j#

threadA status: #threadA.Status#

threadB status: #threadB.Status#

threadB sleepTimes: #threadB.sleepTimes#

Is threadB initialized: #threadB.initialized#


Ending a thread

If a thread never completes processing (is hung), it continues to occupy system resources, so it is good practice to have your application check for hung threads and end them. You should also consider ending threads that take excessive time to process and might significantly reduce the responsiveness of your application or server.

To end a thread, use the cfthread tag with an action attribute value of terminate, as the following code snippet shows.







Note: You can also have the ColdFusion Sever Monitor automatically check for and terminate hung threads.

Joining threads

You use the cfthread tag with an action attribute value of join to join two or more threads. You join threads when one thread depends on one or more other threads completing before it can do some processing. For example, a page can start multiple threads to do processing and join them before it processes the thread results. By default, the join action stops the current thread from doing further processing until all the specified threads complete processing.

You can use a timeout attribute to specify the number of milliseconds that the current thread waits for the thread or threads being joined to finish. If any thread does not finish by the specified time, the current thread proceeds without waiting for the remaining thread or threads to complete.

The following code, for example, joins three threads to the current thread (often, the main page thread). The current thread waits up to six seconds for the other threads to complete, and continues processing if one or more threads do not complete by then.



If the timeout attribute value is 0, the default value, the current thread continues waiting until all joining threads finish. In this case, if the current thread is the page thread, the page continues waiting until the threads are joined, even if you specify a page time-out. As a general rule, you should specify a timeout value to limit hung threads.

Thursday, May 14, 2009

Lightweight Directory Access Protocol, or LDAP

LDAP: An Introduction

LDAP is a protocol for accessing existing on-line directory services. It runs directly over TCP and can be used to access a standalone LDAP directory service or to access a directory service that is back-ended by X.500. A directory is like a database, but tends to contain more descriptive, attribute-based information. The information in a directory is generally read much more often than it is written. As a consequence, directories don't usually implement the complicated transaction or rollback schemes regular databases use for doing high-volume complex updates. Directory updates are typically simple all-or-nothing changes, if they are allowed at all. Directories are tuned to give quick-response to high-volume lookup or search operations.

What kind of information is stored in a directory? The LDAP directory service model is based on entries. An entry is a collection of attributes that has a name, called a distinguished name (DN). The DN is used to refer to the entry uniquely, like a Primary Key in a database. Each of the entry's attributes has a type and one or more values. The types are typically like "sn" for last name, "mail" for email address, or "telephonenumber" for telephone numbers.

In an LDAP, directory entries are arranged in a hierarchical tree-like structure that reflects geographic and/or organizational boundaries. Entries representing countries appear at the top of the tree. Below them are entries representing states or national organizations. Below them might be entries representing people, organizational units, printers, documents, or anything else. Figure 2 shows an example LDAP directory tree.

In addition, LDAP allows you to control which attributes are required and allowed in an entry through the use of a special attribute called objectclass. The values of the objectclass attribute determine the schema rules the entry must obey.




Figure 2: An Example LDAP Directory Tree.

An entry in LDAP is referenced by its distinguished name, which is constructed by taking the name of the entry itself (called the relative distinguished name, or RDN) and concatenating the names of its ancestor entries. For example, the entry for Puneet Kukreja in the example above has an RDN of "cn=Puneet Kukreja" and a DN of "cn=Puneet Kukreja, o=Monash University, c=AU". The full DN format is described in RFC 1779, "A String Representation of Distinguished Names" (see http://www.ietf.org/rfc/rfc1779.txt?number=1779).

The Build Process

Having gained an introductory background, we will start the process of building the Web service using the new ColdFusion MX technology and good old Web forms.

All of us are familiar with search because it is performed on every major Web site today and is an essential part of any corporate intranet. The input parameters from our search page will be submitted to the Web service that will run the search against an LDAP server.

Tools to Create a Web Service

The tools that will be used to build this Web service are:

  • Any text editor or HTML rendering tool to write our Web form
  • Macromedia, Inc.'s ColdFusion MX Server (Beta Edition) to host the Web service
  • Macromedia Dreamweaver MX Studio (Beta Edition) to write the Web service and the Web service client

Designing the Application

The Web form will submit the search request to the Web service, which will in turn contact the LDAP server to retrieve the search results. When we start to build this application, we will see how Web Services and ColdFusion Components fit together.

ColdFusion Web Service

Look at some sample code before we write our actual Web service in order to understand the basics.

 
  
 
 
  
          
 
  
                
 
  
                
 
  
          
 
  
 
 

The cfcomponent tag indicates the CFC, much like the HTML tag indicates the beginning and end of an HTML page.

The cffunction tag indicates the functionality of the component. There can be multiple cffunction tags in a single component. When we invoke the CFC from our ColdFusion page, any one of the functions can be called. This is especially useful if there are sets of related functionality that we want to move to a separate file for maintainability of code. The cffunction tag has five attributes. Dreamweaver MX inserts three attributes as a default:

  • Name - The name of the function needs to be unique in the CFC page so that it can be called from the function individually.
  • Access - This determines who can access the component method by client type. If we leave the access set to public, then any other CFML page on the ColdFusion server will be able to access the CFC. If we change the access to remote, then that enables the CFC to be called as a Web service.
  • Returntype - This attribute gives data type validation for returned values.

Client to Consume the Web Service

Once we have written the CFC it is very easy to call it.

For this article we will call it from a ColdFusion page; in the next article we will call this Web service from a .NET client. In the ColdFusion page where you want to call the CFC, use the cfinvoke tag. In the cfinvoke tag, we can call individual functions inside of the CFC and specify the name of the return variables that are returned from the CFC.

Here is a skeleton code for invoking the Web service. We will write a complete Web service and invoke it in Part 2. This is just to make us aware of what is happening and how the return code is structured.

 
  
        
         component="ComponentName"    
         returnvariable="returnResult"        
         >
 
  
                
 
  
       
 
  
      # returnResult#
 

This explains the basics of building a Web service in ColdFusion and also the client to consume it.

An Explanation of CFLDAP

The CFLDAP tag in ColdFusion helps to query the LDAP server.

Syntax

 
    PORT="port_number"
    USERNAME="name"
    PASSWORD="password"
    ACTION="action"
    NAME="name"
    TIMEOUT="seconds"
    MAXROWS="number"
    START="distinguished_name"
    SCOPE="scope"
    ATTRIBUTES="attribute, attribute"
    FILTER="filter"
    SORT="sort_order"
    DN="distinguished_name"
    STARTROW="row_number">
 

SERVER - Required. Host name ("ldap.server.name") or IP address ("111.111.000.000") of the LDAP server.

PORT - Optional. Port defaults to the standard LDAP port, 389.

USERNAME - Optional. If no username is specified, the LDAP connection will be anonymous.

PASSWORD - Optional. Password corresponds to username.

ACTION - Optional. Specifies the LDAP action. There are five possible values:

  • Query -- (Default) Returns LDAP entry information only. Requires NAME, START, and ATTRIBUTES attributes.
  • Add -- Adds LDAP entries to the LDAP server. Requires ATTRIBUTES.
  • Modify -- Modifies LDAP entries on an LDAP server with the exception of the distinguished name ("DN") attribute. Requires DN, ATTRIBUTES.
  • ModifyDN -- Modifies the distinguished name attribute for LDAP entries on an LDAP server. Requires DN, ATTRIBUTES.
  • Delete -- Deletes LDAP entries on an LDAP server. Requires DN.

NAME - Required for ACTION="Query". The name you assign to the LDAP query.

TIMEOUT - Optional. Specifies the maximum amount of time in seconds to wait for LDAP processing. Defaults to 60 seconds.

MAXROWS - Optional. Specifies the maximum number of entries for LDAP queries.

START - Required for ACTION="Query". Specifies the distinguished name of the entry to be used to start the search.

SCOPE - Optional. Specifies the scope of the search from the entry specified in the START attribute for ACTION="Query". There are three possible values:

  • OneLevel -- (Default) Searches all entries one level beneath the entry specified in the START attribute.
  • Base -- Searches only the entry specified in the START attribute.
  • Subtree -- Searches the entry specified in the START attribute as well all entries at all levels beneath it.

ATTRIBUTES - Required for ACTION="Query", Add, ModifyDN, and Modify. For queries, specifies the comma-separated list of attributes to be returned for queries. Can also be used to specify the list of update columns for ACTION="Add" or "Modify". When used with ACTION="Add" and Action="Modify", separate multiple attributes with a semicolon. When used with ACTION="ModifyDN", ColdFusion passes attributes to the LDAP server without performing any syntax checking.

FILTER - Optional. Specifies the search criteria for ACTION="Query". Attributes are referenced in the form: "(attribute operator value)". Example: "(sn=Kukreja)". Default is "objectclass=*".

SORT - Optional. Specifies the attribute to sort query results by. Enter Asc for an ascending sort and Desc for a descending sort.

DN - Required for ACTION="Add", Modify, ModifyDN, and Delete. Specifies the distinguished name for update actions. Example: "cn=Puneet Kukreja, o=Monash University, c=AU".