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
See Also
ESEJob, ESEServer, ESETask