Myna. Thread

Executes code in a separate thread

Summary
Myna. ThreadExecutes code in a separate thread
Functions
ThreadConstructor function for Thread class
Properties
javaThreada local instance of java.lang.Thread
releaseOnJoinshould this thread’s memory be released when join or joinAll is called? 
deleteOnJoinshould this thread’s metadata be deleted when join or joinAll is called? 
captureOutputshould this thread capture generated content and return value from the subThread? 
mynaThreada reference to the running MynaThread instance.
Functions
joinPauses the current thread until this thread exits, and then returns thread function result
releaseSubThreadreleases this Thread’s subThread so that its memory can be recovered
isRunningreturns true if this thread is still running
getContentreturns content generated by this thread
getReturnValuereturns the value returned by the thread function.
stopstops this thread.
killkills this thread.
joinAllStatic function that calls join on all threads spawned from the current thread, and returns an array of their return values
getThreadArrayStatic function that returns an array of all the threads spawned in the current thread
Myna. ThreadGroupmanages a collection of threads
Functions
ThreadGroupConstructor function for ThreadGroup class
getThreadArrayreturns an array of all the threads spawned by this group
getThreadArrayjoin all the threads in this group.
spawncalls ThreadGroup.add using this this group’s defaults and returns the generated thread.
getRunningThreads()returns an array of the threads in this ThreadGroup that are still running
addcreates a thread, adds it to this group, and returns the generated thread

Functions

Thread

Myna.Thread=function(f,
args,
priority)

Constructor function for Thread class

Parameters

ffunction to execute
argsOptional, default [] array of arguments to pass to the function;
priorityOptional, default 0 This integer represents how often this thread should be scheduled as a percentage of normal priority.  For example, priority 20 would be 20% more likely to run than normal requests during a given time slice.  Priority -10 would be 10% LESS likely than normal requests to run during a given time slice

Detail

Executes f in a separate thread.  This can be used to take advantage of multiple processors be splitting a long running task into multiple functions running in parallel, or to execute non-interactive code in the background.

Each Thread runs in a separate Myna request with it’s own global ($) variables.  Because the script path is copied from the parent thread, $application will be created the same as the parent thread and $application.onRequestStart() .onError() etc. will be fired at the appropriate times.  This means that you should never call Myna.Thread from an application.sjs file, or your code will create an infinite thread spawning loop, and will error out after 5 levels.

You can pass variables from the current thread into Myna.Thread and the sub-thread will have access to them even after the parent thread exits

The parent thread can access the return value from f via Myna.Thread.getReturnValue or from Myna.Thread.join

The parent thread can access the generated output of f via Myna.Thread.getContent

Warning

Threads can themselves call Threads to a maximum depth of 5 levels.  This prevents infinite Thread spawning.

Memory Tip

if you do not need access to the subThread’s output, you can dramatically decrease memory usage by setting Thread.mynaThread to null

Performance Tip

If you are running Myna.Thread in a loop, you can limit the number of concurrent Threads by making periodic calls to Myna.Thread.joinAll.  See examples below

Returns

Reference to Thread instance

Examples

// ----- send an email in the background with  a very low priority ---------
var t= new Myna.Thread(function(data){
new Myna.Mail({
to:data.toAddress,
from:data.fromAddress,
...
}).send()
},[$req.data],-90)


// ----- run all your queries at once --------------------------------------
new Myna.Thread(function(){
return new Myna.Query({
ds:"some ds",
sql:"..."
}).data
}])

new Myna.Thread(function(){
return new Myna.Query({
ds:"some other ds",
sql:"..."
}).data
})

// a destructuring assignment takes each row from the array returned from
// joinAll and assigns them to the variables in the assignment array
var [ qryData1, qryData2] = Myna.Thread.joinAll();


// ----- break up a memory intensive task into ----------------------------
// ----- a set number of concurrent threads ----------------------------
qry.data.forEach(function(row,index,array){
var t=new Myna.Thread(function(){
... bunch of work ...
},[])

//this frees each thread's memory when that thread is joined
t.releaseOnJoin=true;

//this stops after every three spawns or the end of the loop to
//wait for running threads to finish
if ((index+1)%3 == 0 || index == array.length-1) Myna.Thread.joinAll();
})

Properties

javaThread

a local instance of java.lang.Thread

releaseOnJoin

should this thread’s memory be released when join or joinAll is called?  (Default: false)

Setting this to true will cause the subThread to be released when join or joinAll is called.  If captureOutput is also true, then output is cached before releasing the the subThread

deleteOnJoin

should this thread’s metadata be deleted when join or joinAll is called?  (Default: false)

Setting this to true will cause the subThread’s metadata to be deleted when join or joinAll is called.  This makes any return value or captured output unavailable.

This is a good choice for maximum memory efficiency

captureOutput

should this thread capture generated content and return value from the subThread?  (Default: true)

Setting this to false will set mynaThread to null.  Setting this value to true has no effect

mynaThread

a reference to the running MynaThread instance.

Setting this to null will prevent access to subThread output (see <Thread.getContent> and <Thread.getReturnValue>) but will also allow the subThread’s memory to be garbage collected immediately on completion

Functions

join

Myna.Thread.prototype.join=function(timeout,
throwOnTimeout)

Pauses the current thread until this thread exits, and then returns thread function result

Returns

return value of thread function

Parameters

timeoutOptional, default 300000 (30 seconds) time in milliseconds to wait for the thread to finish.  If the thread has not finished before the timeout control is returned to the current thread.  A timeout of 0 disables the timeout
throwOnTimeoutOptional, default true If the thread has not finished before the timeout, throw an Error.

releaseSubThread

Myna.Thread.prototype.releaseSubThread=function()

releases this Thread’s subThread so that its memory can be recovered

Detail

This function sets Thread.mynaThread to null.  If Thread.captureOutput is true, this function will first cache the subThread’s return value and generated content.  If you call this function a second time after setting Thread.captureOutput to false, then any cached values will be cleared

isRunning

Myna.Thread.prototype.isRunning=function()

returns true if this thread is still running

getContent

Myna.Thread.prototype.getContent=function()

returns content generated by this thread

Don’t expect to see anything while isRunning returns true

getReturnValue

Myna.Thread.prototype.getReturnValue=function()

returns the value returned by the thread function.

Don’t expect to see anything while isRunning returns true

stop

Myna.Thread.prototype.stop=function()

stops this thread.

kill

Myna.Thread.prototype.kill=function()

kills this thread.

joinAll

Myna.Thread.joinAll = function(timeout,
throwOnTimeout,
killOnTimeout)

Static function that calls join on all threads spawned from the current thread, and returns an array of their return values

Parameters

timeoutOptional, default 300000 (30 seconds) time in milliseconds to wait for all threads to finish.  If all threads are not finished before the timeout control is returned to the current thread A timeout of 0 disables the timeout
throwOnTimeoutOptional, default true If all threads are not finished before the timeout, throw an Error.
killOnTimeoutOptional, default true If true, threads running past the timeout will be first stopped, then killed.  Example:
(10).times(function(i){
new Myna.Thread(function(i){
return i;
},[i])
})
Myna.printDump(Myna.Thread.joinAll())

getThreadArray

Myna.Thread.getThreadArray = function()

Static function that returns an array of all the threads spawned in the current thread

Myna. ThreadGroup

manages a collection of threads

Summary
Functions
ThreadGroupConstructor function for ThreadGroup class
getThreadArrayreturns an array of all the threads spawned by this group
getThreadArrayjoin all the threads in this group.
spawncalls ThreadGroup.add using this this group’s defaults and returns the generated thread.
getRunningThreads()returns an array of the threads in this ThreadGroup that are still running
addcreates a thread, adds it to this group, and returns the generated thread

Functions

ThreadGroup

Myna.ThreadGroup=function(options)

Constructor function for ThreadGroup class

Parameters

optionsoptions object, see below

Options

priorityOptional, default 0 default priority for each thread
argsOptional, default [] default array of arguments to pass to the threads created in this group
releaseOnJoinOptional, default false default value for Thread.releaseOnJoin for each thread in this group
deleteOnJoinOptional, default false default value for Thread.deleteOnJoin for each thread in this group
captureOutputOptional, default true default value for Thread.captureOutput for each thread in this group
fnOptional, default null default function to be used for each thread in this group
joinEveryOptional, default 0 if a positive number, this thread group will join all running threads after this many spawns/adds.  This allows you you put a limit on the number of threads running at a time.

Examples

// ----- send several emails in the background with  a very low priority ---------
var tg= new Myna.ThreadGroup({
priority:-90,
releaseOnJoin:true,
captureOutput:false,
fn:function(data){
new Myna.Mail({
to:data.toAddress,
from:data.fromAddress,
...
}).send()
}

})

qry.data.forEach(function(row){
tg.spawn(row);
})

// ----- run all your queries at once --------------------------------------
var queries= new Myna.ThreadGroup({
releaseOnJoin:true
})

qry.data.forEach(function(row){
tg.spawn(row);
})
tg.add(function(){
return new Myna.Query({
ds:"some ds",
sql:"..."
}).data
}])

tg.add(function(){
return new Myna.Query({
ds:"some other ds",
sql:"..."
}).data
})

// a destructuring assignment takes each row from the array returned from
// joinAll and assigns them to the variables in the assignment array
var [ qryData1, qryData2] = tg.join();


// ----- break up a memory intensive task into ----------------------------
// ----- a set number of concurrent threads ----------------------------
var workers= new Myna.ThreadGroup({
releaseOnJoin:true,
fn:function(row){
... bunch of work ...
},
joinEvery:3
})
qry.data.forEach(function(row,index,array){
workers.spawn(row);
})

var result = workers.join();

getThreadArray

Myna.ThreadGroup.prototype.getThreadArray=function()

returns an array of all the threads spawned by this group

getThreadArray

join all the threads in this group.

Takes the same parameters as Myna.Thread.joinAll

spawn

Myna.ThreadGroup.prototype.spawn=function()

calls ThreadGroup.add using this this group’s defaults and returns the generated thread.

<ThreadGroup.fn> must be defined.  Any arguments passed to this function will be passed to the generated thread

getRunningThreads()

Myna.ThreadGroup.prototype.getRunningThreads=function()

returns an array of the threads in this ThreadGroup that are still running

add

Myna.ThreadGroup.prototype.add=function(func,
args,
priority)

creates a thread, adds it to this group, and returns the generated thread

Parameters

funcOptional, default <ThreadGroup.fn> Function to execute in the the thread.  If null or not defined <ThreadGroup.fn> will be used
argsOptional, default <ThreadGroup.args> Array of arguments to pass to the function.  If null or not defined, <ThreadGroup.args> will be used
priorityOptional, default <ThreadGroup.priority> This integer represents how often this thread should be scheduled as a percentage of normal priority.  For example, priority 20 would be 20% more likely to run than normal requests during a given time slice.  Priority -10 would be 10% LESS likely than normal requests to run during a given time slice
Myna.Thread=function(f,
args,
priority)
Constructor function for Thread class
Myna.Thread.prototype.join=function(timeout,
throwOnTimeout)
Pauses the current thread until this thread exits, and then returns thread function result
Myna.Thread.joinAll = function(timeout,
throwOnTimeout,
killOnTimeout)
Static function that calls join on all threads spawned from the current thread, and returns an array of their return values
Myna.Thread.prototype.releaseSubThread=function()
releases this Thread’s subThread so that its memory can be recovered
Myna.Thread.prototype.isRunning=function()
returns true if this thread is still running
Myna.Thread.prototype.getContent=function()
returns content generated by this thread
Myna.Thread.prototype.getReturnValue=function()
returns the value returned by the thread function.
Myna.Thread.prototype.stop=function()
stops this thread.
Myna.Thread.prototype.kill=function()
kills this thread.
Myna.Thread.getThreadArray = function()
Static function that returns an array of all the threads spawned in the current thread
Myna.ThreadGroup=function(options)
Constructor function for ThreadGroup class
Myna.ThreadGroup.prototype.getThreadArray=function()
returns an array of all the threads spawned by this group
Myna.ThreadGroup.prototype.spawn=function()
calls ThreadGroup.add using this this group’s defaults and returns the generated thread.
Myna.ThreadGroup.prototype.add=function(func,
args,
priority)
creates a thread, adds it to this group, and returns the generated thread
Myna.ThreadGroup.prototype.getRunningThreads=function()
returns an array of the threads in this ThreadGroup that are still running
a reference to the running MynaThread instance.
should this thread capture generated content and return value from the subThread? 
should this thread’s memory be released when join or joinAll is called? 
should this thread’s metadata be deleted when join or joinAll is called?