A process initializer is your code that runs when a runner of your sandbox starts, before that runner serves any request. A runner is one process of a sandbox. Use it for what every process needs : a subscription to a message broker, a client kept for the life of the process, a warm cache.
In short
It runs once in every runner : a sandbox has up to one runner per processor core.
The active initializers run one after the other, in their order.
Keep it light and safe to run twice.
Page
APIs & Logic → Initializers : name, order, timeout in minutes, active, and the code.
Runs
In every runner of a sandbox, when it starts. The active initializers run one after the other, in their order.
Code
The function main of any language, with the same g as a custom API.
import*asTfrom'types';asyncfunctionmain(g:T.IAMGlobal){// Read once per process : every request this process serves finds them in g.shared.constrates=awaitg.sys.db.getAll({instance:'mysql_8',database:'shop',collection:'rates'});g.shared.rates=rates;g.logger.log(`${rates.length} rates loaded`);}module.exports=main;
fromamimportGasyncdefmain(g:G):# Read once per process : every request this process serves finds them in g.shared.rates=awaitg.sys.db.get_all('mysql_8','shop','rates')g.shared['rates']=ratesg.logger.log(len(rates),'rates loaded')
<?phpfunctionmain(AmG$g){// Read once per process : every request this process serves finds them in $g->shared.$rates=$g->sys->db->getAll('mysql_8','shop','rates');$g->shared->rates=$rates;$g->logger->log(count($rates),'rates loaded');returnnull;}
filestaticclassApi{publicstaticasyncTask<object?>Main(Gg){// Read once per process : every request this process serves finds them in g.Shared.varrates=awaitg.Sys.Db.GetAll(newGetAll("mysql_8","shop","rates"));g.Shared["rates"]=rates;g.Logger.Log(rates.Count,"rates loaded");returnnull;}}
packagecodeimport"apimaker/am"funcMain(g*am.G)(any,error){// Read once per process : every request this process serves finds them in g.Shared.rates,err:=g.Sys.Db.GetAll(am.GetAll{Instance:"mysql_8",Database:"shop",Collection:"rates"})iferr!=nil{returnnil,err}g.Shared.Set("rates",rates)g.Logger.Log(len(rates),"rates loaded")returnnil,nil}
useam::{Errors,G,GetAll,Value,json};pubfnmain(g:&mutG)->Result<Value,Errors>{// Read once per process : every request this process serves finds them in g.shared.letrates=g.sys.db.get_all(GetAll::new("mysql_8","shop","rates"))?;g.logger.log(format!("{} rates loaded",rates.len()));g.shared.set("rates",json!(rates));Ok(Value::Null)}
importam.G;importam.GetAll;importam.JsonObject;importjava.util.List;classApi{staticObjectmain(Gg){// Read once per process : every request this process serves finds them in g.shared.List<JsonObject>rates=g.sys.db.getAll(newGetAll("mysql_8","shop","rates"));g.shared.put("rates",rates);g.logger.log(rates.size(),"rates loaded");returnnull;}}
importam.Gimportam.GetAllfunmain(g:G):Any?{// Read once per process : every request this process serves finds them in g.shared.valrates=g.sys.db.getAll(GetAll("mysql_8","shop","rates"))g.shared["rates"]=ratesg.logger.log(rates.size,"rates loaded")returnnull}
An initializer is also where what lives as long as the process starts : the client of a message queue which listens to a topic (MQTT, Kafka, RabbitMQ…), with the package of its language added on the Sandbox Settings page.
Other code runs on an action : an HTTP call, a schedule, an event. An initializer runs on its own, once per process, so keep it light and idempotent.
How many sandboxes run is set on the Sandbox Settings page. Each runner of each of them runs the initializers.
Timeout in minutes is how long each process waits for the initializer, every time it runs it (empty : sandboxReqTimeout of the configuration, 13 seconds). A process whose initializer did not end in time goes on to the next one, and then serves your code : keep what lasts as long as the process (a listener, a subscription) out of the promise the initializer returns.