Task
Introduction
GreyCat comes with a concept of asynchronous tasks built-in. The mental model for the tasks is close to what other languages have:
- Java’s
Future
- JavaScript’s
Promise
They essentially are a handle to a potentially not-yet-done computation. Allowing you to poll for readiness, or cancel it mid-way. Tasks are well-suited for long calculations using the graph or involving network requests.
Writing a task
From a language perspective, tasks are like functions but they are declared with the task
keyword rather than the fn
keyword:
task long_computation() {
// this is a task
}
fn short_computation() {
// this is a function
}
Tasks are like functions, therefore they can be called the same way.
fn main() {
// calling a task like a function
long_computation();
}
When calling a task
like a fn
, the execution is synchronous, just like functions.
Asynchronous tasks
In order to execute tasks asynchronously, we need to use the runtime
module and spawn them:
use runtime;
task long_computation(max: int) {
var count = 0;
for (var i = 0; i < max; i++) {
count++;
}
return count;
}
fn main() {
// We spawn the task by giving the function pointer and the arguments
Task::spawn(project::long_computation, [1_000_000]);
}
An asynchronously run task writes its result in gcdata/files/<user_id>/tasks/<task_id>/result.gcb
.
Where <user_id>
is the currently authenticated user, and <task_id>
is the newly created task id (task ids are shared accross all users).
Alongside the result.gcb
exist several other files:
arguments.gcb
: serialized arguments given at the task creationinfo.gcb
: the task info (eg. progress, status, start time, end time)log.txt
: the logs inherent to the taskresult.gcb
: the serialized value returned by the task
Exposing a task
When exposing a task, the Explorer will be able to run it on-demand provided that the currently logged-in user has the right permissions.
@expose
task long_computation(max: int) {
var count = 0;
for (var i = 0; i < max; i++) {
count++;
}
return count;
}