7.2.261-stable
std > runtime > Source
@permission("public", "default, associated with anonymous users");
@permission("admin", "allows to administrate anything on the server");
@permission("api", "allows access to exposed functions and webroot files");
@permission("debug", "allows access to low-level graph manipulation functions");
@permission("files", "allows access to files under /files/* or webroot according to ACL");
@role("public", "public");
@role("admin", "public", "admin", "api", "debug", "files");
@role("user", "public", "api", "files");
/// Unit of access control, attached to functions
private type Permission {
name: String;
description: String;
@expose
@permission("admin")
static native fn all(): Array<Permission>;
}
/// Aggregation of permissions to be associated to a user
private type Role {
name: String;
permissions: Array<String>;
@expose
@permission("admin")
static native fn all(): Array<Role>;
}
/// Unit of computation executed in parallel awaited by a parent Task
type Job<T> {
function: core::function;
arguments: Array<any?>?;
native fn result(): T;
}
/// The strategy applies to merge node updates from job to task or task to the main graph.
enum MergeStrategy {
/// All or nothing. Every node update must be free of conflicts with concurrent changes; otherwise, an exception is thrown.
/// This should be considered the default mode, as it offers the strongest guarantee of consistency.
strict;
/// Partial strategy making merge not crash on concurrent conflicts.
///All node updates are applied and conflicts are resolved using the previously inserted values in a graph.
first_wins;
/// Partial strategy making merge not crash on concurrent conflicts.
/// All node updates are applied and conflicts are resolved by overriding previously inserted values by current ones.
last_wins;
}
native fn await(jobs: Array<Job>, strategy: MergeStrategy);
/// log levels used in log files
enum LogLevel {
error;
warn;
info;
perf;
trace;
}
/// log structure useful for parsing
@volatile
type Log {
level: LogLevel;
time: time;
user_id: int?;
id: int?;
id2: int?;
src: function?;
data: any?;
}
@volatile
type LogDataUsage {
read_bytes: int;
read_hits: int;
read_wasted: int;
write_bytes: int;
write_hits: int;
cache_bytes: int;
cache_hits: int;
}
@volatile
type RuntimeInfo {
version: String;
program_version: String?;
arch: String;
timezone: TimeZone;
license: License;
io_threads: int;
bg_threads: int;
fg_threads: int;
mem_total: int;
mem_worker: int;
disk_data_bytes: int;
}
type Runtime {
@expose
@permission("debug")
static native fn info(): RuntimeInfo;
@expose
@reserved
@permission("api")
static native fn abi();
@expose
@permission("api")
static native fn openapi(): any;
@expose
@permission("debug")
static native fn root(): any;
/// Puts the current thread to sleep for at least the given duration
static native fn sleep(d: duration);
/// Perform full backup even if incremental delta are present in backup directory
static native fn backup_full();
/// Perform incremental backup based on delta present in backup directory
static native fn backup_delta();
/// Trigger a defrag process
static native fn defrag();
}
// type ChildProcess {
// pid: int;
// }
type System {
/// Executes the given command as a subprocess.
/// Returns the content of stdout.
/// If an error occurs the exception will contain the content of stderr.
static native fn exec(path: String, params: Array<String>): String;
/// Spawns the given command as a subprocess and yields its pid.
///
/// Contrary to `System::exec` this method does not actively wait for the process to finish.
// static native fn spawn(path: String, params: Array<String>): ChildProcess;
/// get local configured TimeZone
static native fn tz(): TimeZone;
static native fn getEnv(key: String): String?;
}
enum TaskStatus {
empty;
waiting;
running;
await;
cancelled;
error;
ended;
ended_with_errors;
}
type Task {
user_id: int;
task_id: int;
mod: String?;
type: String?;
fun: String?;
creation: time;
start: time?;
duration: duration?;
status: TaskStatus;
progress: float?;
/// set globally the progress for parent task, accepted value are between 0 and 1.
static native fn progress(progress: float);
static native fn parentId(): int;
static native fn id(): int;
@expose
@reserved
static native fn running(): Array<Task>;
@expose
@reserved
static native fn history(offset: int, max: int): Array<Task>;
@expose
@reserved
static native fn cancel(task_id: int): bool;
@expose
@reserved
static native fn is_running(task_id: int): bool;
}
type SecurityFields {
email: String?;
name: String?;
first_name: String?;
last_name: String?;
roles: Map<String, String>?;
groups: Map<String, String>?;
@expose
@permission("admin")
static native fn set(f: SecurityFields);
@expose
@permission("admin")
static native fn get(): SecurityFields?;
}
type SecurityPolicy {
entities: Array<SecurityEntity>?;
credentials: Map<String, UserCredential>?;
fields: SecurityFields?;
keys: Map<String, String>?;
keys_last_refresh: time?;
}
abstract type SecurityEntity {
id: int;
name: String;
activated: bool;
@expose
@reserved
@permission("admin")
static native fn all(): Array<SecurityEntity>;
@expose
@permission("admin")
static native fn set(entity: SecurityEntity): int?;
}
type UserGroup extends SecurityEntity {}
enum UserGroupPolicyType {
read;
write;
execute;
}
type UserGroupPolicy {
group_id: int;
type: UserGroupPolicyType;
}
type OpenIDConnect {
url: String;
clientId: String;
/// get current configuration to enable OpenID connect capability
@reserved
@expose
@permission("public")
static native fn config(): OpenIDConnect?;
}
type User extends SecurityEntity {
full_name: String?;
email: String?;
role: String?;
groups: Array<UserGroupPolicy>?;
groups_flags: int?;
external: bool;
/// If the given `credentials` are valid, returns a session `token`.
///
/// If `use_cookie` is `true`, the HTTP Response Headers will contain
/// a `Set-Cookie: greycat=<TOKEN> (...)`
///
/// This token can then be used by HTTP clients:
/// - as a bearer: `Authorization: <TOKEN>` _(note that 'bearer' is not specified)_
/// - as a cookie: `Cookie: greycat=<TOKEN>`
@expose
@reserved
@permission("public")
static native fn login(credentials: String, use_cookie: bool): String;
/// If the given JWT `token` is valid (signed with the public key provided), returns a Greycat session `token`.
///
/// If `use_cookie` is `true`, the HTTP Response Headers will contain
/// a `Set-Cookie: greycat=<TOKEN> (...)`
///
/// This token can then be used by HTTP clients:
/// - as a bearer: `Authorization: <TOKEN>` _(note that 'bearer' is not specified)_
/// - as a cookie: `Cookie: greycat=<TOKEN>`
@expose
@reserved
@permission("public")
static native fn tokenLogin(token: String, use_cookie: bool): String;
/// logout cookie
@expose
@reserved
@permission("public")
static native fn logout();
/// renew cookie
@expose
@reserved
@permission("api")
static native fn renew(use_cookie: bool): String;
/// Returns the currently logged-in user id.
@expose
@reserved
@permission("public")
static native fn current(): int;
/// Returns the currently logged-in user.
@expose
@reserved
@permission("public")
static native fn me(): User;
/// Returns the list of permissions of the currently logged-in user.
@expose
@reserved
@permission("public")
static native fn permissions(): Array<String>;
/// Returns `true` if the current connected user has the permission associated to the name passed as parameter, false otherwise.
static native fn hasPermission(permission: String): bool;
@expose
@permission("admin")
/// Updates the password of the user `name`. If the user does not exist, `false` is returned.
static native fn setPassword(name: String, pass: String): bool;
static native fn getByName(name: String): User?;
static native fn get(id: int): User?;
/// Validates the password of the user `name`, if the user does not exist or the password does not match, `false` is returned.
static native fn checkPassword(name: String, pass: String): bool;
}
private type UserCredential {
offset: int;
pass: String?;
}
enum LicenseType {
community;
enterprise;
testing;
}
type License {
/// Associated username
name: String?;
/// Start of license validity
start: time;
/// End of license validity
end: time;
/// Associated company name
company: String?;
/// Maximum allowed memory in MB
max_memory: int;
extra_1: int?;
extra_2: int?;
/// type of license
type: LicenseType?;
}
/// Checkpoint frame variable, named by program origin name if any
private type Variable {
name: String?;
value: any?;
}
/// Checkpoint stack frame, representing nested function call
private type Frame {
module: String?;
type: String?;
function: String?;
src: String?;
line: int;
column: int;
scope: Array<Variable>;
}
/// Checkpoint snapshots, containing frames themselves containing variables
private type Debug {
id: int;
frames: Array<Frame>;
root: any;
@expose
@permission("debug")
@reserved
native static fn all(): Array<int>;
@expose
@permission("debug")
@reserved
native static fn get(id: int): Debug;
@expose
@permission("debug")
@reserved
native static fn resume(id: int);
}
/// A global manager of periodic tasks.
///
/// The scheduler maintains a registry of functions and their associated periodic execution rules.
/// Each function can only have one scheduled task at a time - adding a new task with the same
/// function will replace any existing task.
type Scheduler {
/// Schedules a function to be executed as a task periodically.
///
/// If a task with the same `function` already exists, it will be replaced with the new
/// configuration. The scheduler uses function pointer equality for task identification.
///
/// Examples:
/// ```gcl
/// // Schedule a backup every day at 2 AM
/// Scheduler::add(
/// backup_database,
/// DailyPeriodicity { hour: 2 },
/// null,
/// );
///
/// // Schedule health checks every 5 minutes, starting in 1 hour
/// Scheduler::add(
/// health_check,
/// FixedPeriodicity { every: 5min },
/// PeriodicOptions {
/// start: time::now() + 1hour,
/// max_duration: 30s
/// }
/// );
/// ```
@expose
@permission("admin")
static native fn add(function: function, periodicity: Periodicity, options: PeriodicOptions?);
/// Returns the current list of all scheduled tasks.
///
/// The returned array includes both active and inactive tasks.
/// Use `PeriodicTask.is_active` to check individual task status.
@expose
@permission("admin")
static native fn list(): Array<PeriodicTask>;
/// Looks for a task that matches the given `function`.
///
/// Returns `null` if no matching task is found.
/// Uses function pointer equality for matching.
@expose
@permission("admin")
static native fn find(function: function): PeriodicTask?;
/// Tries to find a task that matches `function` and activates it.
///
/// Activating a task means it will be eligible for execution according to its periodicity.
/// If the task was previously deactivated, it will resume from its next scheduled time.
///
/// Returns `true` if a matching task was found and activated, `false` otherwise.
@expose
@permission("admin")
static native fn activate(function: function): bool;
/// Tries to find a task that matches `function` and deactivates it.
///
/// Deactivating a task prevents it from being executed, but keeps the task configuration
/// in the scheduler. The task can be reactivated later with `activate()`.
///
/// Returns `true` if a matching task was found and deactivated, `false` otherwise.
@expose
@permission("admin")
static native fn deactivate(function: function): bool;
// /// Removes a task completely from the scheduler.
// ///
// /// Unlike `deactivate()`, this permanently removes the task configuration.
// /// The function will no longer be scheduled for execution.
// ///
// /// Returns `true` if a matching task was found and removed, `false` otherwise.
// @expose
// @permission("admin")
// static native fn remove(function: function): bool;
}
/// Represents a scheduled periodic task in the system.
type PeriodicTask {
/// The function that will be executed
function: function;
/// The periodicity configuration for this task
periodicity: Periodicity;
/// Current options applied to this task
options: PeriodicOptions;
/// Whether the task is currently active
is_active: bool;
/// Next scheduled execution time
next_execution: time;
/// Total number of times this task has been executed
execution_count: int;
}
/// Configuration options for periodic tasks.
type PeriodicOptions {
/// Whether or not the task can be executed.
/// Defaults to `true` if not specified.
activated: bool?;
/// Will start the task lifecycle at that time.
///
/// By default `time::now()` is used.
/// If set to a future time, the first execution will be delayed accordingly.
start: time?;
/// The maximum duration a task should take before being forcefully cancelled.
///
/// By default this is `null` meaning the task can run endlessly.
///
/// *Note that the timer starts as soon as a task is queued for execution.*
/// *Note: a negative duration will be replaced by `null`*
max_duration: duration?;
}
/// Base type for all periodicity definitions.
///
/// Cannot be instantiated directly - use one of the concrete implementations.
abstract type Periodicity {}
/// Defines tasks that repeat at fixed intervals.
///
/// Examples:
/// - Every 30 minutes: `FixedPeriodicity { every: 30min }`
/// - Every 2 hours: `FixedPeriodicity { every: 2hour }`
/// - Every day: `FixedPeriodicity { every: 24hour }`
type FixedPeriodicity extends Periodicity {
/// The fixed interval between task executions
every: duration;
}
/// Defines tasks daily execution parameters with specific time targeting.
/// All time fields default to 0 if not specified, resulting in midnight execution.
///
/// Examples:
/// - Run at 2:30 PM: `DailyPeriodicity { hour: 14, minute: 30 }`
/// - Run at midnight: `DailyPeriodicity {}` (all defaults)
/// - Run at 9 AM Europe/Luxembourg: `DailyPeriodicity { hour: 9, timezone: TimeZone::"Europe/Luxembourg" }`
type DailyPeriodicity extends Periodicity {
/// Hour of execution (0-23). Defaults to midnight if not specified
hour: int?;
/// Minute of execution (0-59). Defaults to 0 if not specified
minute: int?;
/// Second of execution (0-59). Defaults to 0 if not specified
second: int?;
/// Timezone for time calculation. Uses the host timezone if not specified
timezone: TimeZone?;
}
/// Defines tasks that run on specific days of the week.
///
/// Examples:
/// - Every Monday and Friday at 9 AM:
/// ```gcl
/// WeeklyPeriodicity {
/// days: [DayOfWeek::Mon, DayOfWeek::Fri],
/// dayly: DailyPeriodicity { hour: 9 }
/// }
/// ```
/// - Every weekday at default time:
/// ```gcl
/// WeeklyPeriodicity {
/// days: [DayOfWeek::Mon, DayOfWeek::Tue, DayOfWeek::Wed, DayOfWeek::Thu, DayOfWeek::Fri]
/// }
/// ```
type WeeklyPeriodicity extends Periodicity {
/// Array of weekdays when the task should run
days: Array<DayOfWeek>;
/// Optional daily periodicity. Defaults to midnight if not provided.
daily: DailyPeriodicity?;
}
/// Defines tasks that run monthly on specific days.
///
/// Examples:
/// - 15th of every month at 2 PM:
/// ```gcl
/// MonthlyPeriodicity {
/// days: [15],
/// daily: DailyPeriodicity { hour: 14 }
/// }
/// ```
/// - Every first day and last day of the month at midnight:
/// ```gcl
/// MonthlyPeriodicity {
/// days: [1, -1]
/// }
/// ```
/// - Three days a month at 9:30 PM:
/// ```gcl
/// MonthlyPeriodicity {
/// days: [1, 15, -1],
/// daily: DailyPeriodicity { hour: 9, minute: 30 }
/// }
/// ```
type MonthlyPeriodicity extends Periodicity {
/// Array of days in the month when the task should run.
/// Positive values (1-31) count from start of month.
/// Negative values (-1 to -31) count from end of month (-1 = last day).
/// Invalid days for shorter months are skipped (e.g., day 31 in February).
days: Array<int>;
/// Optional daily timing specification. Defaults to midnight if not provided.
daily: DailyPeriodicity?;
}
/// Defines tasks that run on specific calendar dates each year.
///
/// Examples:
/// - New Year's Day and Christmas:
/// ```gcl
/// YearlyPeriodicity {
/// dates: [
/// DateTuple { day: 1, month: Jan },
/// DateTuple { day: 25, month: Dec }
/// ]
/// }
/// ```
/// - Quarterly reports (1st of each quarter):
/// ```gcl
/// YearlyPeriodicity {
/// dates: [
/// DateTuple { day: 1, month: Jan },
/// DateTuple { day: 1, month: Apr },
/// DateTuple { day: 1, month: Jul },
/// DateTuple { day: 1, month: Oct }
/// ]
/// }
/// ```
type YearlyPeriodicity extends Periodicity {
/// Array of specific dates (day + month) when the task should run
dates: Array<DateTuple>;
/// Timezone for date calculation. Uses the host timezone if not specified
timezone: TimeZone?;
}
enum DayOfWeek {
Mon(0),
Tue(1),
Wed(2),
Thu(3),
Fri(4),
Sat(5),
Sun(6);
}
enum Month {
Jan(0),
Feb(1),
Mar(2),
Apr(3),
May(4),
Jun(5),
Jul(6),
Aug(7),
Sep(8),
Oct(9),
Nov(10),
Dec(11);
}
/// Represents a specific date within a year.
/// The day field must be valid for the specified month (e.g., February 30th is invalid).
/// Leap year handling is automatic for February dates.
type DateTuple {
/// Day of the month (1-31). Must be valid for the specified month
day: int;
/// Month of the year
month: Month;
}