### Local Development Setup with npm Source: https://github.com/true-async/true-async.github.io/blob/main/README.md Install dependencies and serve the documentation site locally using npm. Ensure Node.js version 22 or higher is installed. ```bash # Prerequisites: Node.js 22+ node -v # Install dependencies npm install # Serve locally with hot reload npm run dev # Open http://localhost:5173 ``` -------------------------------- ### Enable Non-Interactive Installation Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/quickstart.md This example shows how to pass environment variables to the installation script for non-interactive setup. This is useful for automated deployments or scripting. ```bash curl -fsSL .../build-linux.sh | NO_INTERACTIVE=true bash ``` -------------------------------- ### Start HTTP Server with Static and HTTP Handlers Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-server.md An example demonstrating how to configure and start an HTTP server. It includes setting up listeners, worker processes, static file handling with precompressed assets, and a custom HTTP handler for JSON responses. ```php use TrueAsync\HttpServer; use TrueAsync\HttpServerConfig; use TrueAsync\StaticHandler; $server = new HttpServer( (new HttpServerConfig()) ->addListener('0.0.0.0', 8080) ->setWorkers(4) ); $server->addStaticHandler( (new StaticHandler('/assets/', __DIR__ . '/public')) ->enablePrecompressed('br', 'gzip') ); $server->addHttpHandler(function ($req, $res) { $res->json(['ok' => true, 'path' => $req->getPath()]); }); $server->start(); ``` -------------------------------- ### Minimal HTTP Server Example Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/quickstart.md A basic PHP script to start an HTTP server that responds with 'Hello, World!' on port 8080. ```php addListener('0.0.0.0', 8080) ); $server->addHttpHandler(function ($request, $response) { $response ->setStatusCode(200) ->setHeader('Content-Type', 'text/plain') ->setBody('Hello, World!'); }); $server->start(); // blocks until stop() ``` -------------------------------- ### Basic HTTP Server Setup Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/index.md This snippet demonstrates how to initialize and start a basic TrueAsync HTTP server. It configures the server to listen on a specific address and port, sets the number of worker threads, and defines a simple handler for 'Hello, World!' responses. ```php use TrueAsync\HttpServer; use TrueAsync\HttpServerConfig; $server = new HttpServer( (new HttpServerConfig()) ->addListener('0.0.0.0', 8080) ->setWorkers(4) ); $server->addHttpHandler(function ($request, $response) { $response->setStatusCode(200)->setBody('Hello, World!'); }); $server->start(); ``` -------------------------------- ### Static Handler Configuration Example Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/static-handler.md Example demonstrating the configuration of a StaticHandler instance with various settings and its addition to an HttpServer. ```php use TrueAsync\StaticHandler; use TrueAsync\StaticOnMissing; use TrueAsync\StaticDotfiles; $static = (new StaticHandler('/static/', '/var/www/public')) ->setIndexFiles('index.html', 'index.htm') ->enablePrecompressed('br', 'gzip') ->setOnMissing(StaticOnMissing::NEXT) ->setDotfilePolicy(StaticDotfiles::DENY) ->setCacheControl('public, max-age=31536000, immutable') ->setEtagEnabled(true) ->setOpenFileCache(maxEntries: 1024, ttlSeconds: 60) ->setHeader('Strict-Transport-Security', 'max-age=63072000') ->hide('*.bak', '*.tmp', 'private/**'); $server->addStaticHandler($static); ``` -------------------------------- ### Basic Multi-worker Server Setup Source: https://github.com/true-async/true-async.github.io/blob/main/uk/docs/server/workers.md This snippet demonstrates how to initialize an `HttpServer` with multiple worker threads. Each worker will have its own event loop and connection pools. The server starts and blocks until all workers complete. ```php use TrueAsync\HttpServer; use TrueAsync\HttpServerConfig; $server = new HttpServer( (new HttpServerConfig()) ->addListener('0.0.0.0', 8080) ->setWorkers(4) ); $server->addHttpHandler(function ($req, $res) { $res->json(['pid' => getmypid(), 'tid' => /* TID */]); }); $server->start(); // блокує, поки всі воркери не завершаться ``` -------------------------------- ### Build and Install OpenSSL from Source Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/quickstart.md This section details how to build and install a specific version of OpenSSL (3.5) from source, which is required for HTTP/3 support. It configures the installation to a custom prefix and installs the libraries. ```bash # OpenSSL 3.5 with QUIC git clone --branch openssl-3.5 https://github.com/openssl/openssl cd openssl && ./Configure --prefix=/usr/local && make -j$(nproc) && sudo make install sudo ldconfig ``` -------------------------------- ### Examples Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/send-file-options.md Illustrative examples of how to use SendFileOptions with HttpResponse::sendFile(). ```APIDOC ## Examples ### Inline PDF ```php use TrueAsync\SendFileOptions; $res->sendFile('/var/storage/q1-report.pdf', new SendFileOptions( contentType: 'application/pdf', cacheControl: 'private, max-age=300', )); ``` ### Download with a user-friendly name ```php use TrueAsync\SendFileOptions; use TrueAsync\SendFileDisposition; $res->sendFile('/var/storage/abc123.bin', new SendFileOptions( disposition: SendFileDisposition::ATTACHMENT, downloadName: 'Q1 Report 2026.pdf', contentType: 'application/pdf', )); ``` ### One-shot temp file ```php $tmp = '/tmp/export-' . bin2hex(random_bytes(8)) . '.csv'; generateExport($tmp); $res->sendFile($tmp, new SendFileOptions( disposition: SendFileDisposition::ATTACHMENT, downloadName: 'export.csv', contentType: 'text/csv; charset=utf-8', deleteAfterSend: true, )); ``` ### Without conditional GET (always 200) ```php $res->sendFile('/var/storage/live.mp4', new SendFileOptions( conditional: false, acceptRanges: true, cacheControl: 'no-store', )); ``` ### Without precompressed sidecars (compress on the fly in the engine) ```php $res->sendFile('/var/storage/big.json', new SendFileOptions( precompressed: false, )); ``` ``` -------------------------------- ### Install TrueAsync Server on Linux Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/quickstart.md This script downloads the TrueAsync PHP sources, builds the server extension, and installs everything into the user's home directory. It's a convenient way to set up the server on Linux systems. ```bash # Linux (Ubuntu / Debian) curl -fsSL https://raw.githubusercontent.com/true-async/releases/master/installer/build-linux.sh | bash ``` -------------------------------- ### Attempting to acquire a resource Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/pool/try-acquire.md This example demonstrates how to use tryAcquire to get a database connection from a pool. If no connection is available, it prints a message indicating that all connections are busy. The acquired connection is used to query the number of orders, and then it's released back to the pool. ```php new PDO('mysql:host=localhost;dbname=app', 'user', 'pass'), max: 5 ); $conn = $pool->tryAcquire(); if ($conn === null) { echo "All connections are busy, try again later\n"; } else { try { $result = $conn->query('SELECT COUNT(*) FROM orders'); echo "Orders: " . $result->fetchColumn() . "\n"; } finally { $pool->release($conn); } } ``` -------------------------------- ### Run Minimal Server Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/quickstart.md Execute the PHP script to start the minimal HTTP server. ```bash php hello.php ``` -------------------------------- ### Install TrueAsync Server on macOS Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/quickstart.md This script downloads and builds TrueAsync PHP with the server extension on macOS, installing it into the user's home directory. It requires Homebrew to be installed. ```bash # macOS (Apple Silicon / Intel; requires Homebrew) curl -fsSL https://raw.githubusercontent.com/true-async/releases/master/installer/build-macos.sh | bash ``` -------------------------------- ### Setting cookies and redirecting Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/frankenphp/response.md Example demonstrating how to set cookies and perform a redirect. ```APIDOC ## Setting cookies and redirecting Example demonstrating how to set cookies and perform a redirect. ```php getCookies(); if (!isset($cookies['session'])) { $response->addHeader('Set-Cookie', 'session=abc123; Path=/; HttpOnly'); $response->addHeader('Set-Cookie', 'theme=dark; Path=/'); $response->redirect('/welcome'); $response->end(); return; } $response->setStatus(200); $response->setHeader('Content-Type', 'text/plain'); $response->write('Welcome back!'); $response->end(); }); ``` ``` -------------------------------- ### Coroutine Example Source: https://github.com/true-async/true-async.github.io/blob/main/en/interactive/learning-map.html Illustrates how to use coroutines with awaitable functions. ```PHP await($t); ``` -------------------------------- ### Starting the HTTP Server Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-server.md Starts the server and blocks the calling thread. It either runs the event loop on the calling thread or spawns a thread pool for multiple workers. ```php public HttpServer::start(): bool ``` -------------------------------- ### Configure and Build for Development Source: https://github.com/true-async/true-async.github.io/blob/main/en/contributing.md Set up your development environment by configuring and building the project with asynchronous and debug options enabled. This is recommended for development work. ```bash ./buildconf ./configure --enable-async --enable-debug make -j$(nproc) ``` -------------------------------- ### Get HTTP Method Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-request.md Retrieves the HTTP method of the request. Examples include "GET", "POST", "PUT", and "DELETE". ```php public HttpRequest::getMethod(): string ``` -------------------------------- ### Practical Example: HTTP GET Request with Future Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/components/future.md Demonstrates creating a Future for an asynchronous HTTP GET request using file_get_contents. Handles potential errors during the request and maps the JSON response. ```php complete($response); } catch (\Throwable $e) { $state->error($e); } }); return $future; } // Usage $userFuture = httpGet('https://api.example.com/user/1') ->map(fn($json) => json_decode($json, true)) ->catch(fn($e) => ['error' => $e->getMessage()]); $result = $userFuture->await(); ?> ``` -------------------------------- ### Getting Server Configuration Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-server.md Retrieves the configuration object passed to the constructor. The config is locked after the server starts. ```php public HttpServer::getConfig(): HttpServerConfig ``` -------------------------------- ### Request race with await_any_or_fail() Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/await-any-or-fail.md This example demonstrates how to use await_any_or_fail() to get the result from the fastest responding mirror among several. ```php ``` -------------------------------- ### Sizing Pool to CPU Cores Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/thread-pool/get-worker-count.md This example shows how to dynamically determine the number of available CPU cores and use that to initialize a ThreadPool. It then submits tasks and retrieves the worker count. Ensure the 'nproc' command is available or provide a fallback. ```php getWorkerCount(), " workers\n"; $futures = []; for ($i = 0; $i < $cores * 2; $i++) { $futures[] = $pool->submit(fn() => 'done'); } foreach ($futures as $f) { await($f); } $pool->close(); }); ``` -------------------------------- ### Set and Get Log Severity Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-server-config.md Configure the logger severity level. The default is OFF. Severity is fixed at server start and cannot be changed at runtime. ```php public HttpServerConfig::setLogSeverity( TrueAsync\LogSeverity $level ): static public HttpServerConfig::getLogSeverity(): TrueAsync\LogSeverity ``` -------------------------------- ### Diagnosing a stuck coroutine Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/get-suspend-location.md Use Coroutine::getSuspendLocation to identify where a coroutine is suspended. This example spawns a coroutine that gets stuck and then retrieves its suspension location. ```php isSuspended()) { echo "Coroutine #{$coro->getId()} waiting at: {$coro->getSuspendLocation()}\n"; } } ``` -------------------------------- ### Get Coroutine Suspension File and Line Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/get-suspend-file-and-line.md Retrieves the file and line number where a coroutine was suspended. This example demonstrates how to spawn a coroutine, suspend it, and then retrieve its suspension location. ```php getSuspendFileAndLine(); echo "Suspended at: $file:$line\n"; // /app/script.php:7 ``` -------------------------------- ### Build true-async Server Extension (Windows) Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/quickstart.md Build the extension on Windows using the PHP SDK. Ensure static libraries for dependencies are available. ```cmd REM from a Visual Studio x64 Native Tools prompt phpsdk_buildtree phpdev git clone https://github.com/true-async/php-src.git cd php-src git clone https://github.com/true-async/server ext\true_async_server buildconf.bat configure.bat ^ --disable-all ^ --enable-cli ^ --enable-async=shared ^ --enable-http-server=shared ^ --with-openssl=shared nmake ``` -------------------------------- ### Trace for a completed coroutine returns null Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/get-trace.md This example shows that Coroutine::getTrace returns null for a coroutine before it starts and after it has completed execution. This is useful for checking the state of a coroutine. ```php "test"); // Before start -- null var_dump($coroutine->getTrace()); // NULL await($coroutine); // After completion -- null var_dump($coroutine->getTrace()); // NULL ``` -------------------------------- ### Environment diagnostics Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/available-parallelism.md This example shows how to use available_parallelism() for environment diagnostics, printing the number of CPUs the process can utilize. The output varies based on containerization and system limits. ```php getMethod(); $path = parse_url($request->getUri(), PHP_URL_PATH); if ($method === 'GET' && $path === '/health') { $response->setStatus(200); $response->write('OK'); $response->end(); return; } $response->setStatus(404); $response->write('Not Found'); $response->end(); }); ``` -------------------------------- ### Get the stack of a suspended coroutine Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/get-trace.md This example demonstrates how to retrieve and display the call stack of a coroutine that has been spawned and has suspended execution. It iterates through the trace frames, printing file, line, and function information. ```php getTrace(); if ($trace !== null) { foreach ($trace as $frame) { echo ($frame['file'] ?? '?') . ':' . ($frame['line'] ?? '?'); echo ' ' . ($frame['function'] ?? '') . "\n"; } } ``` -------------------------------- ### Logging channel load Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/channel/count.md This example shows how to log the current load of a channel's buffer as a percentage of its capacity. It continuously checks the buffer fill level and logs the usage every second. ```php isClosed()) { $usage = $tasks->count() / $tasks->capacity() * 100; echo "Buffer is " . round($usage) . "% full\n"; delay(1000); } }); ``` -------------------------------- ### Get Awaiting Coroutine Info Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/future/get-awaiting-info.md Use this method to retrieve an array containing debug information about coroutines that are currently awaiting the completion of this Future. This is helpful for diagnosing deadlocks and understanding coroutine dependencies. Ensure coroutines have had time to start awaiting before calling this method. ```php await(); }); \Async\async(function() use ($future) { $future->await(); }); // Give coroutines time to start waiting \Async\delay(10); $info = $future->getAwaitingInfo(); var_dump($info); // Array with information about awaiting coroutines $state->complete("done"); ``` -------------------------------- ### Setting values with string keys Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/context/set.md Demonstrates setting multiple values using string keys and method chaining. Retrieves values using find() to verify. ```php set('request_id', 'req-001') ->set('user_id', 42) ->set('locale', 'ru_RU'); echo current_context()->find('request_id') . "\n"; // "req-001" echo current_context()->find('user_id') . "\n"; // 42 ``` -------------------------------- ### Configuring Multiple Listeners Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/configuration.md Demonstrates setting up multiple listeners for different protocols and ports, including HTTP/1.1, HTTP/2, and HTTP/3 (QUIC) on the same or different ports. This allows for flexible network service configurations. ```php $config ->addListener('0.0.0.0', 80) // H1 + H2c ->addListener('0.0.0.0', 443, tls: true) // H1 + H2 over TLS ->addHttp3Listener('0.0.0.0', 443); // H3 / QUIC on the same port ``` -------------------------------- ### Get a required value from context Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/context/get.md This snippet demonstrates how to set a value in the current context and then retrieve it using `get()`. Use `get()` when the existence of the value is a prerequisite for further operations. ```php set('db_connection', $pdo); spawn(function() { // Get a value that must exist $db = current_context()->get('db_connection'); $db->query('SELECT 1'); }); ``` -------------------------------- ### Basic Usage of TaskSet::joinAll Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/task-set/join-all.md Demonstrates spawning multiple tasks with keys, closing the set, joining all tasks, and accessing their results. Shows that the TaskSet count becomes 0 after joinAll. ```php spawnWithKey('a', fn() => 10); $set->spawnWithKey('b', fn() => 20); $set->spawnWithKey('c', fn() => 30); $set->close(); $results = $set->joinAll()->await(); var_dump($results['a']); // int(10) var_dump($results['b']); // int(20) var_dump($results['c']); // int(30) echo $set->count() . "\n"; // 0 }); ``` -------------------------------- ### Animation Control: Start Source: https://github.com/true-async/true-async.github.io/blob/main/en/interactive/pdo-pool-demo.html Starts the animation playback, enabling the pause button and disabling the step button. ```javascript function startAnimation() { if (currentStepIndex >= steps.length - 1 && !loopCheckbox.checked) reset(); isPlaying = true; playBtn.innerHTML = '⏸ Pause'; stepBtn.disabled = true; animationId = setTimeout(animate, parseInt(speedSelect.value)); } ``` -------------------------------- ### Create a Pool with Advanced Options Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/components/pool.md Shows how to configure a pool with custom factory, destructor, health checks, and lifecycle callbacks for resource management. ```php $pool = new Pool( factory: fn() => createResource(), // How to create a resource destructor: fn($r) => $r->close(), // How to destroy a resource healthcheck: fn($r) => $r->ping(), // Is the resource alive? beforeAcquire: fn($r) => $r->isValid(), // Check before giving out beforeRelease: fn($r) => !$r->isBroken(), // Check before returning min: 2, // Pre-create 2 resources max: 10, // Maximum 10 resources healthcheckInterval: 30000, // Check every 30 sec ); ``` -------------------------------- ### Get Future Completion Location Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/future/get-completed-location.md Demonstrates how to get the completion location of a Future after it has completed. This is useful for logging and debugging. ```php complete("result"); echo $future->getCompletedLocation(); // /app/script.php:9 ``` -------------------------------- ### joinAll() - Parallel Loading with Auto-Cleanup Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/components/task-set.md Example of using joinAll() to load multiple resources in parallel. All tasks are automatically cleaned up after joinAll() completes. ```php $set = new Async\TaskSet(); $set->spawnWithKey('user', fn() => $db->query('SELECT * FROM users WHERE id = ?', [$id])); $set->spawnWithKey('orders', fn() => $db->query('SELECT * FROM orders WHERE user_id = ?', [$id])); $set->spawnWithKey('reviews', fn() => $api->get("/users/{$id}/reviews")); $set->close(); $data = $set->joinAll()->await(); // $set->count() === 0, all entries removed return new UserProfile($data['user'], $data['orders'], $data['reviews']); ``` -------------------------------- ### Basic Server Configuration Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/configuration.md Initializes HttpServerConfig with common settings including listeners, TLS, worker count, timeouts, body size limits, compression, and logging. This is a foundational example for setting up the server. ```php use TrueAsync\HttpServer; use TrueAsync\HttpServerConfig; use TrueAsync\LogSeverity; $config = (new HttpServerConfig()) ->addListener('0.0.0.0', 8080) ->addListener('0.0.0.0', 8443, tls: true) ->addHttp3Listener('0.0.0.0', 8443) ->setCertificate('/etc/tls/server.crt') ->setPrivateKey('/etc/tls/server.key') ->setWorkers(4) ->setKeepAliveTimeout(60) ->setMaxBodySize(50 * 1024 * 1024) ->setCompressionEnabled(true) ->setLogSeverity(LogSeverity::INFO) ->setLogStream(STDERR); $server = new HttpServer($config); ``` -------------------------------- ### Coroutine::isStarted Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/is-started.md Checks whether the coroutine has been started by the scheduler. A coroutine is considered started after the scheduler begins its execution. ```APIDOC ## Coroutine::isStarted ### Description Checks whether the coroutine has been started by the scheduler. A coroutine is considered started after the scheduler begins its execution. ### Method ```php public Coroutine::isStarted(): bool ``` ### Return Value `bool` -- `true` if the coroutine has been started. ### Examples #### Example #1 Checking before and after start ```php isStarted()); // bool(false) -- still in queue suspend(); // let the scheduler start the coroutine var_dump($coroutine->isStarted()); // bool(true) await($coroutine); var_dump($coroutine->isStarted()); // bool(true) -- still true after completion ``` ``` -------------------------------- ### Get Coroutine ID Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/current-coroutine.md Demonstrates how to get the ID of the currently executing coroutine using current_coroutine(). Requires the Async\spawn function. ```php getId() . "\n"; }); ?> ``` -------------------------------- ### Basic spawn() Usage Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/spawn.md Demonstrates launching a function in a new coroutine and awaiting its result. Ensure Async functions are imported. ```php ``` -------------------------------- ### Pool with Hooks Example Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/pool/construct.md Illustrates creating a Pool for RedisClient connections with custom hooks for preparing resources before acquisition and for conditional release. It configures the maximum pool size. ```php new RedisClient('127.0.0.1', 6379), destructor: fn(RedisClient $r) => $r->close(), beforeAcquire: function(RedisClient $r): void { $r->select(0); // reset to default database }, beforeRelease: function(RedisClient $r): bool { // If the connection is broken — destroy the resource return $r->isConnected(); }, max: 5 ); ``` -------------------------------- ### Coroutine Cancellation Before Start Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/cancel.md Illustrates cancelling a coroutine before the scheduler has a chance to start its execution. The subsequent await will catch an AsyncCancellation exception. ```php cancel(); try { await($coroutine); } catch (\Async\AsyncCancellation $e) { echo "Coroutine cancelled before start\n"; } ``` -------------------------------- ### Configuring Thread Environment with Bootloader Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/components/threads.md Use a bootloader function to set up the thread's environment before the main task runs. This is essential for loading classes or dependencies. ```php $thread = spawn_thread( task: function() { $config = new Config('prod'); // Config must exist in the thread return $config->name; }, bootloader: function() { // Executed in the receiving thread BEFORE the main closure require_once __DIR__ . '/src/autoload.php'; }, ); ``` -------------------------------- ### Get First Successful Result Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/task-set/join-any.md Demonstrates how to use joinAny to get the result of the first successful task. Failed tasks remain in the set. ```php spawn(fn() => throw new \RuntimeException("fail 1")); $set->spawn(fn() => throw new \RuntimeException("fail 2")); $set->spawn(fn() => "success!"); $result = $set->joinAny()->await(); echo $result . "\n"; // "success!" echo $set->count() . "\n"; // 2 (failed tasks remain) }); ``` -------------------------------- ### Konfiguration des Bootloaders für Worker-Initialisierung Source: https://github.com/true-async/true-async.github.io/blob/main/de/docs/server/workers.md Setzt einen Bootloader-Closure, der einmalig in jedem Worker vor dem Task-Loop ausgeführt wird. Dies ist nützlich für Autoloading, Connection-Pool-Warmup oder Vorabkompilierung. ```php $config ->setWorkers(4) ->setBootloader(function () { // läuft in jedem Worker einmal vor dem Task-Loop require __DIR__ . '/vendor/autoload.php'; // Connection-Pool-Warmup Database::initPool(min: 4, max: 16); // Vorabkompilierung kritischer Routen Router::compile(); }); ``` -------------------------------- ### Check Coroutine Start Status Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/is-started.md Demonstrates checking the start status of a coroutine before and after it has been initiated by the scheduler. The status remains true even after completion. ```php isStarted()); // bool(false) -- still in queue suspend(); // let the scheduler start the coroutine var_dump($coroutine->isStarted()); // bool(true) await($coroutine); var_dump($coroutine->isStarted()); // bool(true) -- still true after completion ``` -------------------------------- ### Cancelling a Coroutine That Hasn't Started Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/components/cancellation.md Shows the behavior when cancel() is called on a coroutine that has been spawned but has not yet begun execution. The coroutine will never start. ```php $coroutine = spawn(function() { echo "Won't execute\n"; }); $coroutine->cancel(); ``` -------------------------------- ### Manual Delta Computation with Async\CpuSnapshot Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/cpu-snapshot.md This example demonstrates how to manually compute the CPU usage delta between two CpuSnapshot instances taken a second apart. It calculates the wall-clock time, user mode CPU time, and kernel mode CPU time, then determines the average number of cores utilized by the process. ```php wallNs - $prev->wallNs; $user = $now->processUserNs - $prev->processUserNs; $sys = $now->processSystemNs - $prev->processSystemNs; // How many cores user + kernel time occupied over the interval. $processCores = ($user + $sys) / $wall; printf( "Process used on average %.3f cores over the last second\n", $processCores ); }); ``` -------------------------------- ### Using with an object key Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/context/get-local.md Shows how to use an object as a key with set() and retrieve it using getLocal(). ```php set($key, ['user' => 'admin', 'role' => 'superuser']); $session = current_context()->getLocal($key); echo "User: " . $session['user'] . "\n"; // "User: admin" }); ``` -------------------------------- ### Get Coroutine Creation Location Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/get-spawn-location.md Demonstrates how to get the creation location of a spawned coroutine. The output will show the file and line number where the coroutine was initiated. ```php "test"); echo "Created at: " . $coroutine->getSpawnLocation() . "\n"; // Output: "Created at: /app/script.php:5" ``` -------------------------------- ### Initialize HttpServerConfig Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-server-config.md Constructs a new HttpServerConfig. Can be used as a shortcut for a single listener setup or with no arguments to configure listeners later using addListener(). ```php public HttpServerConfig::__construct(?string $host = null, int $port = 8080) ``` -------------------------------- ### Get Exception from Coroutine with Error Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/coroutine/get-exception.md Shows how to get an exception from a coroutine that terminated with an error. This is useful for debugging and handling runtime failures within asynchronous operations. ```php getException(); var_dump($exception instanceof RuntimeException); // bool(true) var_dump($exception->getMessage()); // string(10) "test error" ``` -------------------------------- ### HttpServer::start Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-server.md Starts the server and blocks the calling thread until stop() or a fatal error. Returns true on a normal shutdown. Throws HttpServerException on start errors. ```APIDOC ## HttpServer::start ### Description Starts the HTTP server. This method blocks the calling thread until the server is stopped or a fatal error occurs. ### Method start ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Returns - **bool** - `true` on a normal shutdown, `false` otherwise. ``` -------------------------------- ### HTTP Response Example Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-response.md Demonstrates various HttpResponse methods including setting headers, sending Server-Sent Events (SSE), sending files with options, and sending JSON responses within an HTTP handler. ```php use TrueAsync\HttpResponse; use TrueAsync\SendFileOptions; use TrueAsync\SendFileDisposition; $server->addHttpHandler(function ($req, HttpResponse $res) { // SSE if ($req->getPath() === '/events') { $res ->setStatusCode(200) ->setHeader('Content-Type', 'text/event-stream') ->setHeader('Cache-Control', 'no-store') ->setNoCompression(); foreach (loadEvents() as $event) { $res->send("data: " . json_encode($event) . "\n\n"); } return; } // sendFile if ($req->getPath() === '/report.pdf') { $res->sendFile('/var/reports/q1.pdf', new SendFileOptions( disposition: SendFileDisposition::ATTACHMENT, downloadName: 'Q1-Report.pdf', )); return; } // JSON $res->json(['ok' => true]); }); ``` -------------------------------- ### Worker Initialization with Bootloader Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/workers.md Set up a bootloader closure that runs once in each worker thread before it starts processing tasks. This is useful for heavy initialization like autoloading, warming up connection pools, or pre-compiling routes. ```php $config ->setWorkers(4) ->setBootloader(function () { // runs once in each worker before the task loop require __DIR__ . '/vendor/autoload.php'; // warm up the connection pool Database::initPool(min: 4, max: 16); // pre-compile critical routes Router::compile(); }); ``` -------------------------------- ### Install Build Dependencies on Linux Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/quickstart.md This command installs essential build tools and development libraries required for compiling TrueAsync PHP and its extensions on Debian-based Linux systems. ```bash sudo apt-get install -y \ build-essential autoconf bison re2c pkg-config \ libcmocka-dev # for --enable-tests ``` -------------------------------- ### HTTP Handler Example Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/server/http-request.md An example of an HTTP handler function that processes an incoming HttpRequest and sends an HttpResponse. It logs request details and handles JSON POST requests. ```php $server->addHttpHandler(function (HttpRequest $req, HttpResponse $res) { error_log(sprintf( "[%s] %s %s (HTTP/%s, body=%s, traceid=%s)", $req->getMethod(), $req->getPath(), $req->getQuery() ? json_encode($req->getQuery()) : '-', $req->getHttpVersion(), $req->getContentLength() ?? 'n/a', $req->getTraceId() ?? '-' )); if ($req->getMethod() === 'POST' && $req->getContentType() === 'application/json') { $body = json_decode($req->getBody(), true); // ... } $res->json(['ok' => true]); }); ``` -------------------------------- ### Named tasks with TaskSet::spawnWithKey Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/task-set/spawn-with-key.md This example demonstrates how to add tasks to a TaskSet using spawnWithKey, assigning unique keys to each task. The results can then be accessed using these keys after joining all tasks. ```php spawnWithKey('user', fn() => fetchUser($id)); $set->spawnWithKey('orders', fn() => fetchOrders($id)); $set->close(); $data = $set->joinAll()->await(); echo $data['user']['name']; echo count($data['orders']); }); ``` -------------------------------- ### Redis Connection Pool Example Source: https://github.com/true-async/true-async.github.io/blob/main/de/docs/components/pool.md Sets up a Redis connection pool and uses 100 coroutines to concurrently acquire connections, perform operations, and release them. ```php use Async\Pool; use function Async\spawn; use function Async\await; $redis = new Pool( factory: function() { $conn = new Redis(); $conn->connect('127.0.0.1', 6379); return $conn; }, destructor: fn($conn) => $conn->close(), healthcheck: fn($conn) => $conn->ping(), min: 2, max: 20, healthcheckInterval: 15000, ); // 100 Koroutinen lesen gleichzeitig aus Redis über 20 Verbindungen $coroutines = []; for ($i = 0; $i < 100; $i++) { $coroutines[] = spawn(function() use ($redis, $i) { $conn = $redis->acquire(timeout: 3000); try { return $conn->get("key:$i"); } finally { $redis->release($conn); } }); } $results = array_map(fn($c) => await($c), $coroutines); $redis->close(); ``` -------------------------------- ### Check buffer fullness Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/channel/is-full.md Demonstrates how to check if a channel's buffer is full or has space. This example initializes a channel with a capacity of 2 and checks its fullness before and after sending messages. ```php isFull() ? "full" : "has space"; // "has space" $channel->send('a'); $channel->send('b'); echo $channel->isFull() ? "full" : "has space"; // "full" ``` -------------------------------- ### Redis Connection Pool Example Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/components/pool.md An example of using the Pool component to manage Redis connections. It demonstrates creating a pool, acquiring connections, performing operations, and releasing connections. ```php use Async\Pool; use function Async\spawn; use function Async\await; $redis = new Pool( factory: function() { $conn = new Redis(); $conn->connect('127.0.0.1', 6379); return $conn; }, destructor: fn($conn) => $conn->close(), healthcheck: fn($conn) => $conn->ping(), min: 2, max: 20, healthcheckInterval: 15000, ); // 100 coroutines concurrently read from Redis through 20 connections $coroutines = []; for ($i = 0; $i < 100; $i++) { $coroutines[] = spawn(function() use ($redis, $i) { $conn = $redis->acquire(timeout: 3000); try { return $conn->get("key:$i"); } finally { $redis->release($conn); } }); } $results = array_map(fn($c) => await($c), $coroutines); $redis->close(); ``` -------------------------------- ### ThreadChannel Basic Usage and Methods Source: https://github.com/true-async/true-async.github.io/blob/main/de/docs/components/thread-channels.md Demonstrates the basic operations of a ThreadChannel, including setting capacity, checking emptiness and fullness, sending and receiving messages, and closing the channel. This example shows the state changes of the channel throughout its lifecycle. ```php capacity(), "\n"; echo "empty: ", ($ch->isEmpty() ? "yes" : "no"), "\n"; $ch->send('a'); $ch->send('b'); echo "count after 2 sends: ", count($ch), "\n"; echo "full: ", ($ch->isFull() ? "yes" : "no"), "\n"; $ch->send('c'); echo "full after 3: ", ($ch->isFull() ? "yes" : "no"), "\n"; $got = []; while (!$ch->isEmpty()) { $got[] = $ch->recv(); } echo "drained: ", implode(',', $got), "\n"; $ch->close(); echo "closed: ", ($ch->isClosed() ? "yes" : "no"), "\n"; }); ``` ```text capacity: 3 empty: yes count after 2 sends: 2 full: no full after 3: yes drained: a,b,c closed: yes ``` -------------------------------- ### Coroutine Refcount Management Source: https://github.com/true-async/true-async.github.io/blob/main/en/architecture/fibers.md The fiber explicitly retains its coroutine, incrementing the reference count upon creation and start. The reference count is released in the fiber's destructor if the coroutine is finished or not started. ```c if (ZEND_COROUTINE_IS_FINISHED(coroutine) || !ZEND_COROUTINE_IS_STARTED(coroutine)) { ZEND_ASYNC_EVENT_RELEASE(&coroutine->event); } ``` -------------------------------- ### Basic Multi-worker Server Setup Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/server/workers.md Configure an HTTP server to use multiple worker threads for handling requests. This setup utilizes the built-in thread pool and listens on a specified address and port. ```php use TrueAsync\HttpServer; use TrueAsync\HttpServerConfig; $server = new HttpServer( (new HttpServerConfig()) ->addListener('0.0.0.0', 8080) ->setWorkers(4) ); $server->addHttpHandler(function ($req, $res) { $res->json(['pid' => getmypid(), 'tid' => /* TID */]); }); $server->start(); // blocks until all workers finish ``` -------------------------------- ### PDO Connection Pool Example Source: https://github.com/true-async/true-async.github.io/blob/main/en/docs/reference/pool/construct.md Demonstrates creating a Pool for PDO connections, including factory, destructor, health check, and pool size configurations. Resources are acquired, used, and released. ```php PDO::ERRMODE_EXCEPTION, ]); }, destructor: function(PDO $pdo): void { // PDO is closed automatically when removed }, healthcheck: function(PDO $pdo): bool { try { $pdo->query('SELECT 1'); return true; } catch (\Throwable) { return false; } }, min: 2, max: 20, healthcheckInterval: 30000 // check every 30 seconds ); $conn = $pool->acquire(); $result = $conn->query('SELECT * FROM users'); $pool->release($conn); ```