The ESE class provides a set of static methods that are valuable for introspection, finding tasks, controlling jobs and other functionality.

Methods


Examples


Example 1

The ESE class makes it easy to find a task by its full name:

Task = ESE.FindTask('localhost', 9191, 'querytask')

and to match on any task with the string 'catalog' in its name:

Task = ESE.FindTask('localhost', 9191, 'catalog', /REGEX)

This is useful if the URI to a task is not known.

Example 2

One of the most important features of the ESE class is to be able to effectively suspend program flow while waiting for asynchronous jobs to finish. In this example, the join method is used to wait for the results from several jobs before their results can be merged and IDL execution can continue. See Custom IDL Tasks on how to create the addition task. Copy the custom task to your IDL installation lib directory for it to be available on the server.

Task = ESE.GetTask('http://localhost:9191/ese/services/IDL/addition')
 
n = 10
jobs = objarr(n)
FOR i = 0, n - 1 do begin
  jobs[i] = Task.Run(a = 1, b = i, /ASYNCHRONOUS)
ENDFOR
 
status = ESE.Join(jobs)
 
IF (min(status)) THEN BEGIN
  PRINT, 'Jobs ran successfully.'
ENDIF ELSE BEGIN
  PRINT, 'Uh oh...'
ENDELSE

Example 3

The ESE API provides is the ability to program with just IDL variables, avoiding JSON strings. For example, you can access input and output parameters as IDL variables:

Server = ESE.GetServer('localhost', 9191)
 
Task = Server.FindTask('addition')
Task.a = 9
 
Job = Task.Run(b = 6)
 
PRINT, Job.c

The parameters a and b are set to the values 9 and 6.The last line prints the value of c. Behind the scenes, the ESE API is converting between IDL values and JSON, which is needed for transport to and from the ESE server.

The default types are handled automatically, but custom types can also be handled. For example, if Task.a was an object of type PlanetClass, custom serialization and deserialization routines could be specified to convert back and forth between IDL variables and JSON strings with the following:

ESE.SetSerializer, 'PlanetClass', 'serializePlanet'
ESE.SetDeserializer, 'PlanetClass', 'deserializePlanet'

Now, whenever the ESE API needs to transport a variable to the ESE server, it can convert objects of type PlanetClass to JSON and back again.

Note: The datatype (such as PlanetClass) must be used as the parameter's type in the task's description. See ESE::SetSerializer and ESE::SetDeserializer for details on how to write the conversion functions.

Properties


ASYNCHRONOUS (Get)

A constant for 'asynchronous'.

SYNCHRONOUS (Get)

A constant for 'synchronous'.

JOBCANCELLED (Get)

A constant for 'JobCancelled'.

JOBCANCELLING (Get)

A constant for 'JobCancelling'.

JOBEXECUTING (Get)

A constant for 'JobExecuting'.

JOBFAILED (Get)

A constant for 'JobFailed'.

JOBQUEUED (Get)

A constant for 'JobQueued'.

JOBSUBMITTED (Get)

A constant for 'JobSubmitted'.

JOBSUCCEEDED (Get)

A constant for 'JobSucceeded'.

JOBTIMEDOUT (Get)

A constant for 'JobStatusTimedOut'.

ESE::FindTask


This static method searches the specified server for the named task and returns an ESETask that represents it. It provides convenience versus ESE::GetTask, where the full URI has to be known.

Example


Find all tasks on 'localhost' that have the string 'catalog' in them:

Task = ESE.FindTask('localhost', 'catalog', /REGEX)

Note: A default port of 9191 is used.

Syntax


Task = ESE.FindTask(Host [, Port ], TaskName [, /REGEX])

Return Value


If just one task matches the given name, then a scalar ESETask object is returned. If more than one task is found, then an array of ESETask objects is returned. If no matching tasks exist on the server, then !null is returned. All searches are case insensitive. If the host is invalid or there is a communications error then an error is thrown.

Arguments


Host

The name or IP address of the server.

Port

The port that ESE is listening on. The default value is 9191.

TaskName

The name of the task. If the REGEX keyword is set then TaskName is the regular expression to match on. Matching is case-insensitive regardless of whether REGEX is set.

Keywords


REGEX

Set this keyword to use TaskName as a regular expression.

ESE::GetDeserializer


This static method returns the name of the function that performs the JSON to IDL conversion for a given data type.

Example


Get the deserializer function for the Double class:

functionName = ESE.GetDeserializer('Double')

Syntax


FunctionName = ESE.GetDeserializer(Type)

Return Value


Returns the name of the function that does the JSON to IDL conversion. If the data type name or corresponding function do not exist, then !null is returned.

Arguments


Type

The name of an ESE data type.

Keywords


None.

ESE::GetSerializer


This static method returns the name of the function that does the IDL to JSON conversion for a given data type.

Example


Get the serializer function for the Double class:

functionName = ESE.GetSerializer('Double')

Syntax


FunctionName = ESE.GetSerializer(Type)

Return Value


Returns the name of the function that does the IDL to JSON conversion. If the data type name or corresponding function do not exist, then !null is returned.

Arguments


Type

The name of an ESE data type.

Keywords


None.

ESE::GetServer


This static method returns an ESEServer object.

Example


Get the ESE server running on the machine 'localhost' at port 9191:

Server = ESE.GetServer('localhost', 9191)

Syntax


Result = ESE.GetServer( Host [, Port ] )

Return Value


This method returns an ESEServer object. If host and port do not map to a valid ESE server, then !null is returned.

Arguments


Host

The name or IP address of the server.

Port

The port that ESE is listening on. The default value is 9191.

Keywords


None.

ESE::GetTask


This static method returns an ESETask object.

Example


Get the task at a given URI:

Task = ESE.GetTask('http://localhost:9191/ese/services/IDL/querytask')

Syntax


Task = ESE.GetTask(URI)

Return Value


This method returns an ESETask object. If the URI does not address a valid task, then !NULL is returned.

Arguments


URI

The full URI to an ESE task. It can be discovered through introspecting via ESECatalog and ESEFolder objects. It can also be discovered by using ESE::FindTask, to get the URI for future use with GetTask.

Keywords


None.

ESE::Join


The static join method synchronizes execution between the current IDL session and ESE jobs. It is used to block further execution until all jobs have completed. It waits and "joins" a set of threads of execution back into the original thread, which can then continue. See Custom IDL Tasks on how to create the addition task. Copy the custom task to your IDL installation lib directory for it to be available on the server.

Examples


This example demonstrates running tasks in parallel. The join blocks until all jobs are finished and then returns. The return value from join can be used to see which jobs succeeded and which failed.

Task = ESE.FindTask('localhost', 9191, 'addition')
 
n = 10
jobs = objarr(n)
FOR i = 0, n - 1 do begin
  jobs[i] = Task.Run(a = 1, b = i, /ASYNCHRONOUS)
ENDFOR
 
status = ESE.Join(jobs)
 
IF (min(status)) THEN BEGIN
  PRINT, 'Jobs ran successfully.'
ENDIF ELSE BEGIN
  PRINT, 'Uh oh...'
ENDELSE

Syntax


Status = ESE.Join(Jobs [, TIMEOUT = value] [, CALLBACK = value] [, /IGNORE_FAILURES] [, USER_DATA = value]] [, REQUESTS_PER_SECOND = value])

Return Value


The return value is an array of integers that represents the success or failure of the corresponding job in the Jobs array. A value of 1 indicates that the job succeeded (ESE.jobSucceeded). A value of 0 indicates that the job failed for some reason (ESE.jobFailed, ESE.jobCancelled, etc.). Failed jobs can be examined in detail by looking at ESEJob properties.

Arguments


Jobs

A scalar or array of ESEJob objects to join on.

Keywords


TIMEOUT

Specifies the number of seconds to wait before ending the join early. The default is "infinity."

CALLBACK

Specifies the name of an IDL function to be invoked every time a watched job changes status or progress (ESEJob.info() status and progress). The signature of the callback function is:

FUNCTION CallbackName, Job [, UserData]

The Job argument is the ESEJob object whose status or progress changed. The UserData argument is whatever user data value was passed in by the call to ESE::Join. The return value indicates what value should go into the join's status array (values of [0,1]). Using this technique, the callback can indicate that a successful job actually failed because it recognizes the return value as out-of-range, for example. If the IGNORE_FAILURES keyword is not set, then a return value of 0 will end the join.Using callback with lengthy operations will slow the join.

IGNORE_FAILURES

Set this keyword to continue waiting for jobs even if job failures are detected. Failures occur due to job failure, cancellation and time-out. The default is to not continue (a value of 0). Note that the callback can also indicate failure via its return value.

USER_DATA

Specifies user data to be supplied to the callback. This keyword only makes sense to be used in conjunction with the CALLBACK keyword.

REQUESTS_PER_SECOND

Specifies how frequently the join should query the server. The goal is to not swamp the server with requests for status. Specify time as an integer or floating-point number. The default is one request per second, which is suitable for most situations. With each request, all jobs have their status queried, so a value of 1 means that the join will not wait more than one second longer than is necessary before noticing job status and progress changes.

ESE::SetDeserializer


This static method pairs a data type with a function that performs "JSON to IDL" conversion. The conversion function is used internally by the ESE API. For example, after a task is run, the value can be retrieved by "myObject = Job.answer". The conversion function translates JSON to an IDL variable. When a data type is already associated with a function, the new function replaces the existing one.

The deserializer mapping is stored by the ESE class for use anywhere the API is used; deserializers need only be set just once in a program.

Examples


Set the deserializer for the custom BoundingBox class:

ESE.SetDeserializer, 'BoundingBox', 'boundingBoxDeserializer'

with the deserializer function:

FUNCTION boundingBoxDeserializer, json, value, status_message = message
  COMPILE_OPT idl2
  ON_ERROR, 2
 
  CATCH, errorStatus
  IF (errorStatus ne 0) THEN BEGIN
     CATCH, /CANCEL
     MESSAGE, /RESET
     RETURN, !false
  ENDIF
   
  temp = json_parse(json, /toarray)
   
  IF(N_ELEMENTS(temp) ne 4) then return, !false
   
  VALUE = temp
   
  RETURN, !true
 
END

Syntax


ESE.SetDeserializer, Type, Function

Arguments


Type

The name of an ESE data type. Typically, the type will be custom but built-in types can be specified, causing the corresponding default deserializer to be replaced.

Function

The name of the deserialization function the ESE API will invoke whenever conversion is required. The deserialization function must have the following signature:

FUNCTION FunctionName, JSON-String, IDLVariable, STATUS_MESSAGE = value

The return value should be !true or !false to indicated the validity of the input variable. The IDLVariable parameter is an optional output parameter to the caller, and is not needed for validation. The optional STATUS_MESSAGE output keyword can provide the caller with a status string.

Keywords


None.

ESE::SetSerializer


This static method pairs a data type with a function that performs "IDL to JSON" conversion. The conversion function is used internally by the ESE API. For example, in "Task.run( a = myObject )" the IDL variable "myObject" will need to be converted to JSON for transport, and the specified function will do the conversion. When a data type is already associated with a function, the new function replaces the existing one.

The serializer mapping is stored by the ESE class for use anywhere the API is used; serializers need only be set just once in a program.

Examples


Set the serializer for the custom BoundingBox class:

ESE.SetSerializer, 'BoundingBox', 'boundingBoxSerializer'

with the serializer function:

FUNCTION boundingBoxSerializer, value, json, status_message = message
  COMPILE_OPT idl2
  ON_ERROR, 2
   
  CATCH, errorStatus
  IF (errorStatus ne 0) THEN BEGIN
     CATCH, /CANCEL
     MESSAGE, /RESET
     RETURN, !false
  ENDIF
   
  IF (~ISA(value, /NUMBER)) THEN RETURN, !false
  IF (N_ELEMENTS(value) ne 4) THEN RETURN, !false
   
  json = json_serialize(value)
   
  RETURN, !true
   
END

Note: The serializer can do bounds checking and other validation, if desired.

Syntax


ESE.SetSerializer, Type, Function

Arguments


Type

The name of an ESE data type. Typically the type will be custom but built-in types can be specified, causing the corresponding default serializer to be replaced.

Function

The name of the serialization function the ESE API will invoke whenever conversion is required. The serialization function must have the following signature:

FUNCTION FunctionName, IDLVariable, JSON-String, STATUS_MESSAGE = Value

The return value should be !true or !false to indicated the validity of the input variable. The JSON-String parameter is an optional output parameter to the caller, and is not needed for validation. The optional STATUS_MESSAGE output keyword can provide the caller with an informative message string.

Keywords


None.

Version History


IDL 8.4.1 Introduced

See Also


ESEJob, ESEServer, ESETask