# Process Initializers

> Code which runs when a sandbox process of your account starts, before any API - subscribe to MQTT or Redis, warm a cache, prepare a client - with the same g as a custom API.

Source: https://docs.apimaker.dev/v4/docs/features/process-initializers.html

A process initializer runs when a sandbox process of your account starts, before it serves any of your code. It is the place for work which must exist in every process : a subscription to a message broker, a client kept for the life of the process, a warm cache.

| | |
|---|---|
| Page | `APIs & Logic → Initializers` : name, order, timeout in minutes, active, and the code. |
| Runs | In every sandbox process, when it starts ; the active initializers in the order given, one after the other. |
| Code | The function `main` of any [language](https://docs.apimaker.dev/v4/docs/languages/index.html), with the same `g` as a custom API. |
| Test | **Test API** runs it on the API testing page. |

**TypeScript**

**Keep the rates in the memory of the process**

```typescript
import * as T from 'types';

async function main(g: T.IAMGlobal) {
    // Read once per process : every request this process serves finds them in g.shared.
    const rates = await g.sys.db.getAll({ instance: 'mysql_8', database: 'shop', collection: 'rates' });
    g.shared.rates = rates;
    g.logger.log(`${rates.length} rates loaded`);
}
module.exports = main;
```

**Python**

**Keep the rates in the memory of the process**

```python
from am import G


async def main(g: G):
    # Read once per process : every request this process serves finds them in g.shared.
    rates = await g.sys.db.get_all('mysql_8', 'shop', 'rates')
    g.shared['rates'] = rates
    g.logger.log(len(rates), 'rates loaded')
```

**PHP**

**Keep the rates in the memory of the process**

```php
<?php
function main(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');
    return null;
}
```

**C#**

**Keep the rates in the memory of the process**

```csharp
file static class Api
{
    public static async Task<object?> Main(G g)
    {
        // Read once per process : every request this process serves finds them in g.Shared.
        var rates = await g.Sys.Db.GetAll(new GetAll("mysql_8", "shop", "rates"));
        g.Shared["rates"] = rates;
        g.Logger.Log(rates.Count, "rates loaded");
        return null;
    }
}
```

**Go**

**Keep the rates in the memory of the process**

```go
package code

import "apimaker/am"

func Main(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"})
	if err != nil {
		return nil, err
	}
	g.Shared.Set("rates", rates)
	g.Logger.Log(len(rates), "rates loaded")
	return nil, nil
}
```

**Rust**

**Keep the rates in the memory of the process**

```rust
use am::{Errors, G, GetAll, Value, json};

pub fn main(g: &mut G) -> Result<Value, Errors> {
    // Read once per process : every request this process serves finds them in g.shared.
    let rates = 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)
}
```

**Java**

**Keep the rates in the memory of the process**

```java
import am.G;
import am.GetAll;
import am.JsonObject;
import java.util.List;

class Api {
    static Object main(G g) {
        // Read once per process : every request this process serves finds them in g.shared.
        List<JsonObject> rates = g.sys.db.getAll(new GetAll("mysql_8", "shop", "rates"));
        g.shared.put("rates", rates);
        g.logger.log(rates.size(), "rates loaded");
        return null;
    }
}
```

**Kotlin**

**Keep the rates in the memory of the process**

```kotlin
import am.G
import am.GetAll

fun main(g: G): Any? {
    // Read once per process : every request this process serves finds them in g.shared.
    val rates = g.sys.db.getAll(GetAll("mysql_8", "shop", "rates"))
    g.shared["rates"] = rates
    g.logger.log(rates.size, "rates loaded")
    return null
}
```

- 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](https://docs.apimaker.dev/v4/docs/settings/sandboxSettings.html#packages) 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.
- The number of sandbox processes is set on the [Sandbox Settings](https://docs.apimaker.dev/v4/docs/settings/sandboxSettings.html) page : each one 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.

## Related

- [Sandbox settings](https://docs.apimaker.dev/v4/docs/settings/sandboxSettings.html) · [The global object g](https://docs.apimaker.dev/v4/docs/pre-defined-terms/global-object-g.html) · [Schedulers](https://docs.apimaker.dev/v4/docs/apis-all/schedulers/user-created-schedulers-api.html)
