Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Actor Standby documentation #1086

Merged
merged 11 commits into from
Jul 9, 2024
121 changes: 121 additions & 0 deletions sources/platform/actors/running/actor_standby.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
title: Actor Standby
description: Use the Actor as a real-time API server.
sidebar_position: 7.3
slug: /actors/running/standby
sidebar_label: Actor Standby
---

**Use Actors in lightweight mode as a blazingly fast API server.**

---

Traditional Actors are designed to run a single task and then stop. They're mostly intended for batch jobs, such as when you need to perform a large scrape or data processing task.
However, in some applications, waiting for an Actor to start is not an option. Actor Standby mode solves this problem by letting you have the Actor ready
in the background, waiting for the incoming HTTP requests. In a sense, the Actor behaves like a real-time web server or standard API server.

#### How do I know if Standby mode is enabled?

You will know that the Actor is enabled for Standby mode if you see the **Standby** tab on the Actor's detail page.
In the tab, you will find the hostname of the server, the description of the Actor's endpoints,
the parameters they accept, and what they return in the Actor README.

To use the Actor in Standby mode, you don't need to click a start button or not need to do anything else. Simply use the provided hostname and endpoint in your application,
hit the API endpoint and get results.

![Standby tab](./images/actor_standby/standby-tab.png)

#### Can I still run the Actor in normal mode

Yes, you can still modify the input and click the Start button to run the Actor in normal mode. However, note that the Standby Actor might
not support this mode; the run might fail or return empty results. The normal mode is always supported in Standby Beta, even for Actors that don't handle
it well. Please head to the Actor README to learn more about the capabilities of your chosen Actor.

#### Is there any scaling to accommodate the incoming requests

When you use the Actor in Standby mode, the system automatically scales the Actor to accommodate the incoming requests. Under the hood,
the system starts new Actor runs, which you will see in the Actor runs tab, with the origin set to Standby.

#### How do I customize Standby configuration

The Standby configuration currently consists of the following properties:

- **Max requests per run** - The maximum number of concurrent HTTP requests a single Standby Actor run can accept. If this limit is exceeded, the system starts a new Actor run to handle the request, which may take a few seconds.
- **Desired requests per run** - The number of concurrent HTTP requests a single Standby Actor run is configured to handle. If this limit is exceeded, the system preemptively starts a new Actor run to handle the additional requests.
- **Memory (MB)** - The amount of memory (RAM) allocated for the Actor in Standby mode, in megabytes. With more memory, the Actor can typically handle more requests in parallel, but this also increases the number of compute units consumed and the associated cost.
- **Idle timeout (seconds)** - If a Standby Actor run doesn’t receive any HTTP requests within this time, the system will terminate the run. When a new request arrives, the system might need to start a new Standby Actor run to handle it, which can take a few seconds. A higher idle timeout improves responsiveness but increases costs, as the Actor remains active for a longer period.
- **Build** - The Actor build that the runs of the Standby Actor will use. Can be either a build tag (e.g. `latest.`), or a build number (e.g. `0.1.2`).

jirimoravcik marked this conversation as resolved.
Show resolved Hide resolved
You can see these in the Standby tab of the Actor detail page. However, note that these properties are not configurable at the Actor level. If you wish to
use the Actor-level hostname, this will always use the default configuration. To override this configuration, just create a new Task from the Actor.
You can then head to the Standby tab of the created Task and modify the configuration as needed. Note that the task has a specific hostname, so make
sure to use that in your application if you wish to use the custom configuration.

#### Are the Standby runs billed differently

No, the Standby runs are billed in the same fashion as the normal runs.
However, running Actors in Standby mode might have unexpected costs, as the Actors run in the background and consume resources even when no requests are being sent until they are terminated after the idle timeout period.

#### Are the Standby runs shared among users

No, even if you use the Actor-level hostname with the default configuration, the background Actor runs for your requests are not shared with other users.

#### How can I develop Actors using Standby mode

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

You can head to the Settings tab of your Actor, enable Standby mode, and set the default configuration.
![Standby for creators](./images/actor_standby/standby-creators.png)
fnesveda marked this conversation as resolved.
Show resolved Hide resolved

Actors using Standby mode must run a HTTP server listening on a specific port. The user requests will then be proxied to the HTTP server.
You can get the port using the Actor configuration available in Apify SDK.

If you need to override the port, you can do it via `ACTOR_STANDBY_PORT` environment variable.
jirimoravcik marked this conversation as resolved.
Show resolved Hide resolved
See example below with a simple Actor using Standby mode.

<Tabs>
jirimoravcik marked this conversation as resolved.
Show resolved Hide resolved
<TabItem value="JavaScript" label="JavaScript">

```js
import http from 'http';
import { Actor } from 'apify';

await Actor.init();

const server = http.createServer(async (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello from Actor Standby!\n');
});

server.listen(Actor.config.get('standbyPort'));
```

</TabItem>
<TabItem value="Python" label="Python">

```python
from http.server import HTTPServer, SimpleHTTPRequestHandler
from apify import Actor, Configuration

class GetHandler(SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello from Actor Standby!')

async def main() -> None:
async with Actor:
with HTTPServer(("", Actor.config.standby_port), GetHandler) as http_server:
jirimoravcik marked this conversation as resolved.
Show resolved Hide resolved
http_server.serve_forever()
```

</TabItem>
</Tabs>

Please make sure to describe your Actors, their endpoints, and the schema for their
inputs and ouputs in your README.

#### Can I monetize my Actor in the Standby mode

No, Standby mode is in Beta, and monetization is not supported.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this needs to wait for public release 😅 Working on it, blocked by https://github.com/apify/apify-core/pull/16488

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current screenshots can be taken from
https://console-featstandbypublicrelease-a00865.apify.com/

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will look a bit different, currently in PR

jirimoravcik marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading