====== Using Worker Threads With Konduktiva ======
**Overview: ** Sometimes running too many actions in the same nodejs thread can cause Konduktiva sequencing to be delayed because of the heavy load on the system and the single threaded nature of nodejs. To avoid this issue, we can create other threads and run heavy actions there. Reading the [[https://nodejs.org/api/worker_threads.html#worker-threads|documentation about nodejs workers]] for about 5 minutes or enough to understand the basic function of nodejs workers is recommended.
**Things To Note:** This tutorial assumes you have already installed Konduktiva successfully using the [[https://github.com/renickbell/konduktiva|Konduktiva installation]] instructions and have read through and understood the [[:first_steps|first steps tutorial]]. The tutorial also assumes 2 things. One, Konduktiva has been assigned to the //K// variable. Two, user created a Musical Environment using the //setUpMusicalEnvironment// function using //K.defaultConfigurationObject// as the first argument and //'exampleMidiPlayer'// as the third argument then, assigned the output to the //e// variable.
const K = require('konduktiva')
let e = K.setUpMusicalEnvironment(K.defaultConfigurationObject,4,'exampleMidiPlayer', K.exampleMusicalEnvironmentsExtraConfig)
===== giveWorkerWork =====
To create a worker and make it run code use the function //giveWorkerWork//. The actions you want the worker thread to run should be in form of a string. That string should include all other functions and dependencies the worker thread might need to perform those actions.
Functions have been created to allow the user to easily create and use worker threads in nodejs. These functions have been included with Konduktiva (main thread on github for now). To explain how the function works, this imagine this situation.
I want the worker thread to use this function called simpleAddition and I want the worker thread to call this function passing the number //4// as an argument and return the result to the main thread:
function simpleAddition (a){
return a + 2 + 4
}
let additionForWorkerThread = simpleAddition.toString() + '; returnToParent(simpleAddition(4))'
let additionResult = await K.giveWorkerWork(additionForWorkerThread)
==== Explanation ====
At the moment, the //giveWorkerWork// function can only take information in form of a string. So all dependencies, information or, any other code the worker needs has to be converted to a string. It has to be converted in a way that the code content is visible in the string. Functions such as the //[[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString|toString]]// method is recommended for functions. The //[[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify|JSON.stringify()]]// is recommended for arrays, objects and numbers. Sometimes, simply writing the code then wrapping it in [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals|backticks]] //``// will be the most convenient. Another method could be giving the worker thread instructions on how to get information like using require, await import or, using fs.readFileSync and using the [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval|eval command]] (which is also a part of what makes this code work). Semicolaons "//;//" are used to signify line breaks in the code(string).
**IMPORTANT**: The information that you want the worker thread to be return must be passed to the //returnToParent// function (only available to the worker thread). After this function is called by the worker thread, the main thread(you original nodejs thread) will be unable to receive more information from that worker thread but the worker thread will be allowed to finish running all the code provided to it before automatically exiting(unless an error has occurred in which case the worker thread will be terminated).
The worker thread can be prompted to close itself before all the code runs by using the //[[https://nodejs.org/api/worker_threads.html#event-exit|proccess.exit()]]// command in the code(in string form) provided when the worker is created:
process.exit()
//await// is needed because the //giveWorkerWork// function returns a promise. A promise is returned because it needs to wait for the worker thread to complete it's task.
Here is another example which shows the worker thread using require to load a library:
let requireTest = 'let A = require("array-toolkit"); returnToParent(A.zip.toString())'
let testResult = await K.giveWorkerWork(requireTest)
Here is an example of adding the information given by workers to the musical environment. In this example, I will user workers to create a QuantizedMap for filterMap. The contents will be the same as chromatic.
let QWorkerCode = `let {QuantizedMap} = require('konduktiva'); let A = require("array-toolkit"); returnToParent(new QuantizedMap(10, A.buildArray(12, x => {return x}), A.buildArray(10, x => {return x})))`
let QResults = await K.giveWorkerWork(QWorkerCode)
e.modeFilters.sameAsChromatic = new K.QuantizedMap(QResults.keyspan, QResults.keys, QResults.values)