Skip to content

FrankenPHP async model (async HTTP client, async database queries, async other IO operations) #1117

Closed
@Aielen

Description

Hello! I have a question regarding FrankenPHP async model. How does it work?

For example; I have a worker mode enabled with 4 workers, so I have 4 processes that handle incoming HTTP requests. Now, let's say each request needs to execute a heavy database query that takes 100 seconds. We have 4 incoming HTTP requests. What happens? Is the application totally blocked and cannot handle any further incoming HTTP requests because of workers exhaustion? Do I need to wait 100 seconds to be able to process more HTTP requests?

I am asking for a feature (or maybe it is already here? If yes, maybe it should be advertised more, because I could not find any information regarding this in the docs) - async IO processing.

We can look at C# async / await for reference;

https://learn.microsoft.com/en-us/ef/core/miscellaneous/async

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/best-practices?view=aspnetcore-8.0

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/best-practices?view=aspnetcore-8.0#avoid-synchronous-read-or-write-on-httprequesthttpresponse-body

https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-8.0&tabs=visual-studio#routing-and-url-paths

[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

The main idea is to introduce an option in FrankenPHP to perform async operations.
When an async operation is performed (i.e.; a database query, an HTTP call to an external service, etc.) the worker process should be released and should be able to pick another task.

With this feature enabled, the above example would change significantly, because workers wouldn't be blocked by the IO operation any longer (a database query - the worker wouldn't wait until the database returned data [100 seconds of the blocked worker]), and would be ready to handle incoming HTTP requests. When database records are available, the process will continue the execution from the point of the last async operation (the database query here) and finish the execution. So the outcome will be; instead of handling only 4 requests simultaneously, we can now handle many more requests, because all the work is on the database side, not on the PHP (CPU) side.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions