JS Quickstart Explained
Introduction
This tutorial will utilize the same example found in Quickstart and include thorough explanations.
Prerequisites
Yagna service is installed and running with the try_golem
app-key configured.
Setting up the project
Create a project folder, initialize a Node.js project, and install the @golem-sdk/task-executor
library.
mkdir golem-example
cd golem-example
npm init
npm i @golem-sdk/task-executor
JS script structure
The basic structure of the script:
import { TaskExecutor } from '@golem-sdk/task-executor'
;(async () => {
//... Function body in here
})()
Here we do two things:
- import TaskExecutor from @golem-sdk/task-executor and
- create IIAFE (Immediately Invoked Async Function Expression). It has an async function declaration because TaskExecutor provides async methods.
Utilizing Task Executor instance
Inside the function body, there will be a sequence of 3 steps, that constitute the simplest Task Executor lifecycle. Task Executor is a primary object provided by our Task API.
import { TaskExecutor } from '@golem-sdk/task-executor'
;(async () => {
// 1. Create Task Executor Instance
const executor = await TaskExecutor.create({
package: '529f7fdaf1cf46ce3126eb6bbcd3b213c314fe8fe884914f5d1106d4',
yagnaOptions: { apiKey: 'try_golem' },
})
try {
// 2. Run the task
const result =
await executor.run(/*taskToRunOnProvider to be provided here */)
console.log('Task result:', result)
} catch (err) {
console.error('An error occurred:', err)
} finally {
// 3. Finish Task Executor
await executor.shutdown()
}
console.log('Task result:', taskResult)
})()
In (1) we create a TaskExecutor Instance using a factory method. In this example, we use the minimal set of parameters: namely the hash indicating the image with Node.js installed - the image we will deploy on the provider and api-key value - a key that will give us access to yagna
REST API. yagna
is a service that connects us to the network. We use api-key that was generated in the process of Yagna installation
const executor = await TaskExecutor.create({
package: '529f7fdaf1cf46ce3126eb6bbcd3b213c314fe8fe884914f5d1106d4',
yagnaOptions: { apiKey: 'try_golem' },
})
Next (2) we run the task. Here we use a run method that accepts a task function as its argument. We will define the task function in a moment. We store the result of the executor.run()
in the result
variable.
There are other methods that allow you to execute tasks. They are briefly presented in Task API Guide and explained in examples section.
const result = await executor.run(taskToRunOnProvider)
Finally (3) we gracefully finish task executor:
await executor.shutdown()
Defining task function
Let’s see how the task is defined and replace the taskToRunOnProvider
placeholder we used in the previous step.
The task is defined as a function that implements the Worker interface. This function will get its parameter workerContext
from the executor. It is an object that lets you run your commands in the scope of one task on one provider.
const taskToRunOnProvider = async (ctx) => // task is defined here;
Our task in this example is simple and consists of a single command: namely node -v
. We will use the async method run()
of workerContext ctx
. The output of this method is a Promise
of a result
object, once it is resolved it contains the output of the command we run, available as a stdout
property.
const taskToRunOnProvider = async (ctx) => (await ctx.run('node -v')).stdout
The output of the task function is passed to executor.run()
and assigned to taskResult. Finally, we print it to the console.
import { TaskExecutor, pinoPrettyLogger } from "@golem-sdk/task-executor";
(async () => {
const executor = await TaskExecutor.create({
package: "golem/node:20-alpine",
logger: pinoPrettyLogger(),
yagnaOptions: { apiKey: "try_golem" },
});
try {
const result = await executor.run(async (ctx) => (await ctx.run("node -v")).stdout);
console.log("Task result:", result);
} catch (err) {
console.error("An error occurred:", err);
} finally {
await executor.shutdown();
}
})();
Summary
We had created the simplest requestor script, that ran a single command on a remote computer. To achieve it we had:
- imported @golem-sdk/task-executor lib
- utilized Immediately Invoked Async Function Expression
- created Task Executor
- defined a task as a function that runs our command
- finally read the command result from the result object and provide it to the user
In this example, we ran a simple command (node -v) in a shell on the remote computer. You can run other executable programs in more interesting scenarios. See other examples for more advanced use cases.