An Automation server exposes properties and methods that can be set and called from other Automation-capable applications.
All you need to do to create an Automation server is :
An Automation server can be deployed locally or remotely, exposing business functionality through methods that can be called and properties that can be set.
This is an example of a Pool Manager implemented in a custom Automation server. A client can send jobs to this Pool Manager, which can be located on a remote computer, and have it handle the job processing. This allows you to continue working because the resources of the pool manager handle all the work. The jobs in this sample are dummy simulation jobs.
To open the project for the pool manager sample
MODIFY PROJECT (HOME(2) + 'servers\poolmgr\pool')
To run the pool manager sample
The first code to execute when you run the Pool form is the Init event, which creates a poolmgr object:
* Pool Init
SET PROC TO jobmgr.prg
THIS.oPoolMgr = CreateObject('Pool.Poolmgr')
When the oPoolMgr object is created, an array is dimensioned to keep track of jobs and a timer object, based on the PoolTimer class, is created to check for new or completed jobs.
When the user chooses the Print, Fax, or Excel Chart buttons on the pool form, the AddJob method of the form is called. AddJob performs the following:
PARAMETER cJobType
LOCAL oNewJobRef
IF ALEN(THIS.aJobs)>1 OR TYPE('THIS.aJobs[1]') = 'O'
DIMENSION THIS.aJobs[ALEN(THIS.aJobs)+1]
ENDIF
oNewJobRef = CreateObject(m.cJobType,THIS)
THIS.oPoolMgr.NewJob(m.oNewJobRef)
The NewJob method of the PoolMgr object redimensions the two dimensional PoolMgr job array and stores a reference to the job object in the first element of the new row and 0 to the second element, indicating that this is a new job.
PARAMETER oNewJob
IF TYPE('oNewJob') # 'O' OR ISNULL(m.oNewJob)
RETURN .F.
ENDIF
IF ALEN(THIS.aJobObjs,1) > 1 ;
OR ISNULL(THIS.aJobObjs[1])
DIMENSION THIS.aJobObjs[ALEN(THIS.aJobObjs,1)+1,2]
ENDIF
THIS.aJobObjs[ALEN(THIS.aJobObjs,1),1] = oNewJob
THIS.aJobObjs[ALEN(THIS.aJobObjs,1),2] = 0
Every three seconds, the PoolTimer timer event code is executed. This code loops through the job array. If the second element is 0, indicating a new job, then a new PrintJob, FaxJob, or GraphJob object (subclasses of Job in Poolmgr.prg) is created to manage the job. For example, the following line creates an object based on PrintJob and stores a reference to it in the timer’s aJobs array:
THIS.aJobs[ALEN(THIS.aJobs)] = CREATEOBJECT('Pool.PrintJob')
The second element in the array for that row is then set to 1 to indicate that the job has been started and the SetupJob method of the new object is called. A reference to the job object is passed to the SetupJob method:
THIS.aJobs[ALEN(THIS.aJobs)].SetupJob(THIS.Parent.aJobObjs[m.i,1])
The Job class is defined in Poolmgr.prg:
DEFINE CLASS Job AS FORM
When an object based on the Job class, or any of its subclasses, is created, the StartJob method of the object is called.
PROCEDURE SetupJob
PARAMETER oJob
THIS.oJob = m.oJob
THIS.Caption = THIS.oJob.Jobtype
THIS.Visible = .T.
ENDPROC
The PrintJob class, for example, is a subclass of Job. If the object created is based on PrintJob, the StartJob method does the default processing of the parent class StartJob method, setting the caption of the form and displaying a label. Then the INKEY( ) function is called to set a timeout of 10 seconds. In a functional implementation of this sample, instead of the INKEY( ) function, you would include code at this point to process the print job.
DEFINE CLASS PrintJob AS Job OLEPublic
PROCEDURE StartJob
DoDefault()
=INKEY(10)
THIS.EndJob()
ENDPROC
ENDDEFINE
The EndJob method of the object calls the JobDone method of the original job object and releases the PrintJob, FaxJob, or GraphJob object.
PROCEDURE EndJob
THIS.lbl1.caption = 'Ending job...'
THIS.oJob.JobDone()
THIS.oJob = .null.
THIS.Visible = .F.
THISFORM.Release
ENDPROC
Code in the JobDone method of the original job object notifies the form that the job has been completed by calling the JobDone method of the form.
PROCEDURE jobdone
IF TYPE('THIS.oFormRef')='O'
THIS.oFormRef.JobDone(THIS.JobType)
ENDIF
ENDPROC
Finally, the JobDone method of the form displays the status of the job in the list box on the form:
PARAMETER cJob
THIS.lstJobs.AddItem(m.cJob+' job is complete.')
The job object (based on the PrintJob, FaxJob, or GraphJob class defined in JOBMGR.prg) is: