{"id":15578488,"url":"https://github.com/carno-php/coroutine","last_synced_at":"2025-08-31T16:40:55.256Z","repository":{"id":62499774,"uuid":"144932582","full_name":"carno-php/coroutine","owner":"carno-php","description":"Native coroutine with yield for php7","archived":false,"fork":false,"pushed_at":"2019-07-30T02:16:19.000Z","size":20,"stargazers_count":7,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-08T02:01:26.488Z","etag":null,"topics":["async","coroutine","native","php7","yield"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/carno-php.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-16T03:35:57.000Z","updated_at":"2023-02-07T13:15:21.000Z","dependencies_parsed_at":"2022-11-02T12:01:27.222Z","dependency_job_id":null,"html_url":"https://github.com/carno-php/coroutine","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/carno-php/coroutine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carno-php%2Fcoroutine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carno-php%2Fcoroutine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carno-php%2Fcoroutine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carno-php%2Fcoroutine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/carno-php","download_url":"https://codeload.github.com/carno-php/coroutine/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carno-php%2Fcoroutine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273010885,"owners_count":25030367,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-31T02:00:09.071Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","coroutine","native","php7","yield"],"created_at":"2024-10-02T19:10:51.087Z","updated_at":"2025-08-31T16:40:55.232Z","avatar_url":"https://github.com/carno-php.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Coroutine - component of carno-php\n\n# Installation\n\n```bash\ncomposer require carno-php/coroutine\n```\n\n# Concepts\n\n\u003e [Cooperative multitasking using coroutines (in PHP!)](https://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html)\n\n### yield values\n\n#### Generator\n\nWhen yield a function and it's returned a generator (yield in function),\njob will make a roll and have a chance to execute other jobs,\nsome functions like ```defer``` depends on this feature\n\n#### Promised\n\nYield a ```Promise``` will make coroutine sleep when pending, and wakeup when promise resolves or rejects,\ngeneral used with async IO\n\n#### Syscall\n\n```Syscall``` can make user in coroutine to get job's properties or interact with job,\nsuch as get job's id or ctx\n\n# Functions\n\n\u003e namespace in ```Carno\\Coroutine```\n\n#### go\n\nNew coroutine without results but throws exception if error\n\n```php\nfunction go(mixed $program, Context $ctx = null) : void\n```\n\n**usages**\n\n```php\n// use closure\ngo(function () {\n    yield 'something';\n    return 'done';\n});\n\n// with exceptions\ntry {\n    go(function () {\n        throw new Exception('test');\n    });\n} catch (Throwable $e) {\n    echo 'got exception :: ', $e-\u003egetMessage(), PHP_EOL;\n}\n```\n\n#### co\n\nSimilar with ```go``` but returns ```closure``` and you can execute it later\n\n```php\nfunction co(mixed $program, Context $ctx = null) : Closure\n```\n\n**usages**\n\n```php\n$func = co(function (string $input) {\n    yield 'something';\n    echo $input;\n});\n$func('vars');\n```\n\n#### async\n\nBase of commands ```go``` and ```co```, it returns a promise that sync with coroutine's result\n\n\u003e Returned promise will resolving when coroutine finish or rejecting when coroutine throws exception\n\n```php\nfunction async(mixed $program, Context $ctx = null, mixed ...$args) : Promised\n```\n\n**usages**\n\n```php\nasync(function () {\n    yield msleep(500);\n})-\u003ethen(function () {\n    echo 'you will see me after 500ms', PHP_EOL;\n});\n```\n\n#### await\n\nA delegate for works with async IO event, supports timeout\n\n```php\nfunction await(Closure $dial, Closure $awake,\n    int $timeout = 60000, string $error = TimeoutException::class, string $message = '') : Promised\n```\n\n**usages**\n\n```php\n$async = function ($callback) {\n    $callback(111, 222);\n};\nyield await(function (Closure $awake) use ($async) {\n    $async($awake);\n}, function (int $a, int $b) {\n    echo 'a = ', $a, ' b = ', $b, PHP_EOL;\n});\n```\n\n#### timeout\n\nCreate a promise that throws exception after N milliseconds if no one rejects it in time, useful with ```race```\n\n```php\nfunction timeout(int $ms, string $ec = TimeoutException::class, string $em = '') : Promised\n```\n\n**usages**\n\n```php\nyield race(timeout(rand(5, 10)), timeout(rand(5, 10), CustomException::class, 'custom message'));\n```\n\n#### msleep\n\nCreate a promise that resolves after N milliseconds\n\n```php\nfunction msleep(int $ms, Closure $do = null) : Promised\n```\n\n**usages**\n\n```php\n// make sleep\nyield msleep(200);\n// do something when wake\necho 'you will see hello -\u003e ', yield msleep(300, function () {\n    return 'hello';\n}), PHP_EOL;\n```\n\n#### ctx\n\nGet job's ctx in coroutine\n\n**usages**\n\n```php\ngo(function () {\n    echo 'hello ', (yield ctx())-\u003eget('hello'), PHP_EOL;\n}, (new Context)-\u003eset('hello', 'world'));\n```\n\n#### defer\n\n\u003e A defer statement defers the execution of a function until the surrounding function returns.\n\n**usages**\n\n```php\nyield (function () {\n    yield defer(function ($stage) {\n        // $stage is returned value or last yield value or throwable if exception\n        echo 'in defer', PHP_EOL;\n    });\n    echo 'in end', PHP_EOL;\n})();\n```\n\n#### race\n\nSame effect as promise's ```race``` but accepts ```Promised``` ```Generator``` and ```Context```\n\n**usages**\n\n```php\nyield race((function () {\n    echo 'hello ', (yield ctx())-\u003eget('hello'), PHP_EOL;\n})(), timeout(500), (new Context)-\u003eset('hello', 'world'));\n```\n\n#### all\n\nSame syntax with ```race```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarno-php%2Fcoroutine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarno-php%2Fcoroutine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarno-php%2Fcoroutine/lists"}