{"action":"created","comment":{"url":"https://api.github.com/repos/M6Web/Tornado/pulls/comments/221474339","pull_request_review_id":160128333,"id":221474339,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMTQ3NDMzOQ==","diff_hunk":"@@ -1,10 +1,239 @@\n-# 🌪 Tornado 🌪\n+# Tornado 🌪🐎\n [![Build Status](https://travis-ci.com/M6Web/Tornado.svg?branch=master)](https://travis-ci.com/M6Web/Tornado)\n \n \n A library for asynchronous programming in [Php](https://secure.php.net/).\n \n-*Tornado* provides several interfaces to write asynchronous programs using [generators](https://secure.php.net/manual/en/language.generators.php),\n-and adapters for [ReactPhp](https://reactphp.org/) and [Amp](https://amphp.org/).\n+*Tornado* is composed of several interfaces to write asynchronous programs using [generators](https://secure.php.net/manual/en/language.generators.php).\n+This library provides adapters for popular asynchronous frameworks ([ReactPhp](https://reactphp.org/), [Amp](https://amphp.org/))\n+and built-in adapters to understand how to write your own.\n \n-See some examples in [`examples`](https://github.com/M6Web/Tornado/tree/master/examples) directory.\n+\n+## Installation\n+\n+You can install it using [Composer](https://getcomposer.org/):\n+```bash\n+composer require m6web/tornado\n+```\n+\n+You will also have to install additional dependencies related to the adapter you choose for your [`EventLoop`](src/EventLoop.php)\n+you may check our suggestions using [Composer](https://getcomposer.org/):\n+```bash\n+composer suggests --by-package\n+```\n+\n+ℹ️ *Tornado* includes its own [`EventLoop`](src/EventLoop.php) adapter to ease quick testing, and to show how you could write\n+ your own [`EventLoop`](src/EventLoop.php) optimized for your use case, but keep in mind that ⚠️***Tornado* adapters are not\n+ yet production ready**⚠️.\n+\n+\n+\n+## How to use it\n+You can find ready-to-use examples in [`examples`](https://github.com/M6Web/Tornado/tree/master/examples) directory,\n+but here some detailed explanations about asynchronous programing, and *Tornado* principles.\n+\n+### Dealing with promises\n+The [`EventLoop`](src/EventLoop.php) is the engine in charge executing all asynchronous functions.\n+If one of those functions is *waiting* an asynchronous result (a [`Promise`](src/Promise.php))\n+the [`EventLoop`](src/EventLoop.php) is able to pause this function and to resume an other one ready to be executed.\n+\n+When you get a [`Promise`](src/Promise.php), the only way to retrieve its concrete value is to [`yield`](https://secure.php.net/manual/en/language.generators.syntax.php#control-structures.yield) it,\n+letting the [`EventLoop`](src/EventLoop.php) deal internally with \n+[Php Generators](https://secure.php.net/manual/en/language.generators.overview.php). \n+```php\n+<?php\n+\n+use M6Web\\Tornado\\HttpClient;\n+use Psr\\Http\\Message\\RequestInterface;\n+use Psr\\Http\\Message\\ResponseInterface;\n+\n+function getJsonResponse(HttpClient $httpClient, RequestInterface $request): \\Generator\n+{\n+    /** @var ResponseInterface $response */\n+    $response = yield $httpClient->sendRequest($request);\n+\n+    return json_decode((string) $response->getBody(), true);\n+}\n+```\n+⚠️ Remember that the return type can **NOT** be `array` here,\n+even if we expect that `json_decode` will return an `array`.\n+Since we are creating a [`Generator`](https://secure.php.net/manual/en/language.generators.overview.php),\n+the return type is by definition `\\Generator`.\n+ \n+### Asynchronous functions\n+As soon as your function needs to wait a [`Promise`](src/Promise.php), it becomes by definition an asynchronous function.\n+To execute it, you need to use [`EventLoop::async`](src/EventLoop.php) method.\n+The returned [`Promise`](src/Promise.php) will be resolved with the value returned by your function.\n+```php\n+<?php\n+\n+use M6Web\\Tornado\\EventLoop;\n+use M6Web\\Tornado\\HttpClient;\n+use Psr\\Http\\Message\\RequestInterface;\n+\n+function displayJsonResponse(EventLoop $eventLoop, HttpClient $httpClient, RequestInterface $request)\n+{\n+    /** @var array $jsonArray */\n+    $jsonArray = yield $eventLoop->async(getJsonResponse($httpClient, $request));\n+\n+    echo json_encode($jsonArray, JSON_PRETTY_PRINT).PHP_EOL;\n+}\n+```\n+\n+### Running the event loop\n+Now, you know that you have to create a generator to wait a [`Promise`](src/Promise.php),\n+and then call [`EventLoop::async`](src/EventLoop.php) to execute the generator and obtain a new [`Promise`](src/Promise.php)…\n+But how can we wait the **first** [`Promise`](src/Promise.php)?\n+Actually, there is a second way to wait a [`Promise`](src/Promise.php), a **synchronous** one:\n+the [`EventLoop::wait`](src/EventLoop.php) method.\n+It means that **you should use it only once**, to wait synchronously the resolution of a predefined goal.\n+Internally, this function will run a loop to handle all *events* until your goal is reached\n+(or an error occurred, see [dedicated chapter](#errors-management)).\n+```php\n+<?php\n+\n+use M6Web\\Tornado\\EventLoop;\n+use M6Web\\Tornado\\HttpClient;\n+use Psr\\Http\\Message\\RequestInterface;\n+\n+function mySynchronousAction(EventLoop $eventLoop, HttpClient $httpClient, RequestInterface $request)\n+{\n+    echo \"This text is displayed BEFORE Json response\\n\";\n+\n+    /** @var array $jsonArray */\n+    $jsonArray = $eventLoop->wait(getJsonResponse($httpClient, $request));\n+    var_dump($jsonArray);\n+\n+    echo \"This text is displayed AFTER Json response\\n\";\n+}\n+```\n+Like with the `yield` keyword,\n+the [`EventLoop::wait`](src/EventLoop.php) method will return the resolved value of the input [`Promise`](src/Promise.php),\n+but remember that you should use it only once during execution.\n+\n+### Concurrency\n+To reveal the true power of asynchronous programming, we have to introduce *concurrency* in our program.\n+If our goal is to send only one HTTP request and wait for it,\n+there is no gain to deal with an asynchronous request.\n+However, as soon as you have at least two goals to reach,\n+asynchronous functions will improve your performances thanks to concurrency.\n+To resolve several independent [`Promises`](src/Promise.php),\n+use [`EventLoop::promiseAll`](src/EventLoop.php) method to create a new [`Promise`](src/Promise.php)\n+that will be resolved when all others are resolved.\n+```php\n+<?php\n+\n+use M6Web\\Tornado\\EventLoop;\n+use M6Web\\Tornado\\HttpClient;\n+use Psr\\Http\\Message\\RequestInterface;\n+\n+function mySynchronousAction(EventLoop $eventLoop, HttpClient $httpClient, array $requests)\n+{\n+    $myPromises = [];\n+    /** @var RequestInterface $request */\n+    foreach ($requests as $request) {\n+        $myPromises[] = getJsonResponse($httpClient, $request);\n+    }\n+    \n+    $allJsonArrays = $eventLoop->wait(\n+        $eventLoop->promiseAll(...$myPromises)\n+    );\n+    \n+    var_dump($allJsonArrays);\n+}\n+```\n+\n+It's important to note that \n+it will be more efficient to use [`EventLoop::promiseAll`](src/EventLoop.php)\n+instead of waiting each input [`Promise`](src/Promise.php) consecutively,\n+because of concurrency.\n+Each time that you have several promises to resolve,\n+ask yourself if you could wait them concurrently, especially when you deal with `foreach` loops. \n+\n+### Resolving your own promises\n+By design, you cannot resolve a promise by yourself, you will need a [`Deferred`](src/Deferred.php).\n+It allows you to create a [`Promise`](src/Promise.php) and to resolve (or reject) it\n+while not exposing these advanced controls.\n+```php\n+<?php\n+\n+use M6Web\\Tornado\\Deferred;\n+use M6Web\\Tornado\\EventLoop;\n+use M6Web\\Tornado\\HttpClient;\n+use M6Web\\Tornado\\Promise;\n+use Psr\\Http\\Message\\RequestInterface;\n+use Psr\\Http\\Message\\ResponseInterface;\n+\n+function loopUntilStatus418(EventLoop $eventLoop, HttpClient $httpClient, RequestInterface $request, Deferred $deferred)\n+{\n+    do {\n+        yield $eventLoop->delay(1000 /*ms*/);\n+        /** @var ResponseInterface $response */\n+        $response = yield $httpClient->sendRequest($request);\n+    } while ($response->getStatusCode() !== 418);\n+\n+    $deferred->resolve($response->getBody());\n+}\n+\n+function get418Response(EventLoop $eventLoop, HttpClient $httpClient, RequestInterface $request): Promise\n+{\n+    $deferred = $eventLoop->deferred();\n+    $eventLoop->async(loopUntilStatus418($eventLoop, $httpClient, $request, $deferred));\n+    \n+    return $deferred->getPromise();\n+}\n+\n+function mySynchronousAction(EventLoop $eventLoop, HttpClient $httpClient, RequestInterface $request)\n+{\n+    /** @var ResponseInterface $response */\n+    $response = $eventLoop->wait(get418Response($eventLoop, $httpClient, $request));\n+\n+    echo (string)$response->getBody();\n+}\n+```\n+\n+### Errors management","path":"README.md","position":199,"original_position":199,"commit_id":"50d697bad23c50a37c3496d97d03d45846e74c5c","original_commit_id":"50d697bad23c50a37c3496d97d03d45846e74c5c","user":{"login":"lucascourot","id":938375,"node_id":"MDQ6VXNlcjkzODM3NQ==","avatar_url":"https://avatars0.githubusercontent.com/u/938375?v=4","gravatar_id":"","url":"https://api.github.com/users/lucascourot","html_url":"https://github.com/lucascourot","followers_url":"https://api.github.com/users/lucascourot/followers","following_url":"https://api.github.com/users/lucascourot/following{/other_user}","gists_url":"https://api.github.com/users/lucascourot/gists{/gist_id}","starred_url":"https://api.github.com/users/lucascourot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lucascourot/subscriptions","organizations_url":"https://api.github.com/users/lucascourot/orgs","repos_url":"https://api.github.com/users/lucascourot/repos","events_url":"https://api.github.com/users/lucascourot/events{/privacy}","received_events_url":"https://api.github.com/users/lucascourot/received_events","type":"User","site_admin":false},"body":"`Errors management` => `Error management` I think it would be more correct","created_at":"2018-09-30T21:37:39Z","updated_at":"2018-09-30T21:43:48Z","html_url":"https://github.com/M6Web/Tornado/pull/15#discussion_r221474339","pull_request_url":"https://api.github.com/repos/M6Web/Tornado/pulls/15","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/M6Web/Tornado/pulls/comments/221474339"},"html":{"href":"https://github.com/M6Web/Tornado/pull/15#discussion_r221474339"},"pull_request":{"href":"https://api.github.com/repos/M6Web/Tornado/pulls/15"}}},"pull_request":{"url":"https://api.github.com/repos/M6Web/Tornado/pulls/15","id":219221473,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE5MjIxNDcz","html_url":"https://github.com/M6Web/Tornado/pull/15","diff_url":"https://github.com/M6Web/Tornado/pull/15.diff","patch_url":"https://github.com/M6Web/Tornado/pull/15.patch","issue_url":"https://api.github.com/repos/M6Web/Tornado/issues/15","number":15,"state":"open","locked":false,"title":"Documentation","user":{"login":"b-viguier","id":5537799,"node_id":"MDQ6VXNlcjU1Mzc3OTk=","avatar_url":"https://avatars2.githubusercontent.com/u/5537799?v=4","gravatar_id":"","url":"https://api.github.com/users/b-viguier","html_url":"https://github.com/b-viguier","followers_url":"https://api.github.com/users/b-viguier/followers","following_url":"https://api.github.com/users/b-viguier/following{/other_user}","gists_url":"https://api.github.com/users/b-viguier/gists{/gist_id}","starred_url":"https://api.github.com/users/b-viguier/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/b-viguier/subscriptions","organizations_url":"https://api.github.com/users/b-viguier/orgs","repos_url":"https://api.github.com/users/b-viguier/repos","events_url":"https://api.github.com/users/b-viguier/events{/privacy}","received_events_url":"https://api.github.com/users/b-viguier/received_events","type":"User","site_admin":false},"body":"How to install it, and a *quick start* guide.\r\n\r\nFix #2 ","created_at":"2018-09-30T19:08:24Z","updated_at":"2018-09-30T21:43:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f11f41bdaee7d9c0cf83ca37950fa71307c48c22","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/M6Web/Tornado/pulls/15/commits","review_comments_url":"https://api.github.com/repos/M6Web/Tornado/pulls/15/comments","review_comment_url":"https://api.github.com/repos/M6Web/Tornado/pulls/comments{/number}","comments_url":"https://api.github.com/repos/M6Web/Tornado/issues/15/comments","statuses_url":"https://api.github.com/repos/M6Web/Tornado/statuses/50d697bad23c50a37c3496d97d03d45846e74c5c","head":{"label":"M6Web:feature/documentation","ref":"feature/documentation","sha":"50d697bad23c50a37c3496d97d03d45846e74c5c","user":{"login":"M6Web","id":1485147,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0ODUxNDc=","avatar_url":"https://avatars3.githubusercontent.com/u/1485147?v=4","gravatar_id":"","url":"https://api.github.com/users/M6Web","html_url":"https://github.com/M6Web","followers_url":"https://api.github.com/users/M6Web/followers","following_url":"https://api.github.com/users/M6Web/following{/other_user}","gists_url":"https://api.github.com/users/M6Web/gists{/gist_id}","starred_url":"https://api.github.com/users/M6Web/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/M6Web/subscriptions","organizations_url":"https://api.github.com/users/M6Web/orgs","repos_url":"https://api.github.com/users/M6Web/repos","events_url":"https://api.github.com/users/M6Web/events{/privacy}","received_events_url":"https://api.github.com/users/M6Web/received_events","type":"Organization","site_admin":false},"repo":{"id":145872131,"node_id":"MDEwOlJlcG9zaXRvcnkxNDU4NzIxMzE=","name":"Tornado","full_name":"M6Web/Tornado","private":false,"owner":{"login":"M6Web","id":1485147,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0ODUxNDc=","avatar_url":"https://avatars3.githubusercontent.com/u/1485147?v=4","gravatar_id":"","url":"https://api.github.com/users/M6Web","html_url":"https://github.com/M6Web","followers_url":"https://api.github.com/users/M6Web/followers","following_url":"https://api.github.com/users/M6Web/following{/other_user}","gists_url":"https://api.github.com/users/M6Web/gists{/gist_id}","starred_url":"https://api.github.com/users/M6Web/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/M6Web/subscriptions","organizations_url":"https://api.github.com/users/M6Web/orgs","repos_url":"https://api.github.com/users/M6Web/repos","events_url":"https://api.github.com/users/M6Web/events{/privacy}","received_events_url":"https://api.github.com/users/M6Web/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/M6Web/Tornado","description":"A library for asynchronous programming :tornado:","fork":false,"url":"https://api.github.com/repos/M6Web/Tornado","forks_url":"https://api.github.com/repos/M6Web/Tornado/forks","keys_url":"https://api.github.com/repos/M6Web/Tornado/keys{/key_id}","collaborators_url":"https://api.github.com/repos/M6Web/Tornado/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/M6Web/Tornado/teams","hooks_url":"https://api.github.com/repos/M6Web/Tornado/hooks","issue_events_url":"https://api.github.com/repos/M6Web/Tornado/issues/events{/number}","events_url":"https://api.github.com/repos/M6Web/Tornado/events","assignees_url":"https://api.github.com/repos/M6Web/Tornado/assignees{/user}","branches_url":"https://api.github.com/repos/M6Web/Tornado/branches{/branch}","tags_url":"https://api.github.com/repos/M6Web/Tornado/tags","blobs_url":"https://api.github.com/repos/M6Web/Tornado/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/M6Web/Tornado/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/M6Web/Tornado/git/refs{/sha}","trees_url":"https://api.github.com/repos/M6Web/Tornado/git/trees{/sha}","statuses_url":"https://api.github.com/repos/M6Web/Tornado/statuses/{sha}","languages_url":"https://api.github.com/repos/M6Web/Tornado/languages","stargazers_url":"https://api.github.com/repos/M6Web/Tornado/stargazers","contributors_url":"https://api.github.com/repos/M6Web/Tornado/contributors","subscribers_url":"https://api.github.com/repos/M6Web/Tornado/subscribers","subscription_url":"https://api.github.com/repos/M6Web/Tornado/subscription","commits_url":"https://api.github.com/repos/M6Web/Tornado/commits{/sha}","git_commits_url":"https://api.github.com/repos/M6Web/Tornado/git/commits{/sha}","comments_url":"https://api.github.com/repos/M6Web/Tornado/comments{/number}","issue_comment_url":"https://api.github.com/repos/M6Web/Tornado/issues/comments{/number}","contents_url":"https://api.github.com/repos/M6Web/Tornado/contents/{+path}","compare_url":"https://api.github.com/repos/M6Web/Tornado/compare/{base}...{head}","merges_url":"https://api.github.com/repos/M6Web/Tornado/merges","archive_url":"https://api.github.com/repos/M6Web/Tornado/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/M6Web/Tornado/downloads","issues_url":"https://api.github.com/repos/M6Web/Tornado/issues{/number}","pulls_url":"https://api.github.com/repos/M6Web/Tornado/pulls{/number}","milestones_url":"https://api.github.com/repos/M6Web/Tornado/milestones{/number}","notifications_url":"https://api.github.com/repos/M6Web/Tornado/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/M6Web/Tornado/labels{/name}","releases_url":"https://api.github.com/repos/M6Web/Tornado/releases{/id}","deployments_url":"https://api.github.com/repos/M6Web/Tornado/deployments","created_at":"2018-08-23T15:23:26Z","updated_at":"2018-09-28T08:15:18Z","pushed_at":"2018-09-30T19:08:25Z","git_url":"git://github.com/M6Web/Tornado.git","ssh_url":"git@github.com:M6Web/Tornado.git","clone_url":"https://github.com/M6Web/Tornado.git","svn_url":"https://github.com/M6Web/Tornado","homepage":null,"size":77,"stargazers_count":2,"watchers_count":2,"language":"PHP","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":5,"license":null,"forks":1,"open_issues":5,"watchers":2,"default_branch":"master"}},"base":{"label":"M6Web:master","ref":"master","sha":"83ea2ce3dce12b61c562b78b3ae32f67d21f12c5","user":{"login":"M6Web","id":1485147,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0ODUxNDc=","avatar_url":"https://avatars3.githubusercontent.com/u/1485147?v=4","gravatar_id":"","url":"https://api.github.com/users/M6Web","html_url":"https://github.com/M6Web","followers_url":"https://api.github.com/users/M6Web/followers","following_url":"https://api.github.com/users/M6Web/following{/other_user}","gists_url":"https://api.github.com/users/M6Web/gists{/gist_id}","starred_url":"https://api.github.com/users/M6Web/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/M6Web/subscriptions","organizations_url":"https://api.github.com/users/M6Web/orgs","repos_url":"https://api.github.com/users/M6Web/repos","events_url":"https://api.github.com/users/M6Web/events{/privacy}","received_events_url":"https://api.github.com/users/M6Web/received_events","type":"Organization","site_admin":false},"repo":{"id":145872131,"node_id":"MDEwOlJlcG9zaXRvcnkxNDU4NzIxMzE=","name":"Tornado","full_name":"M6Web/Tornado","private":false,"owner":{"login":"M6Web","id":1485147,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0ODUxNDc=","avatar_url":"https://avatars3.githubusercontent.com/u/1485147?v=4","gravatar_id":"","url":"https://api.github.com/users/M6Web","html_url":"https://github.com/M6Web","followers_url":"https://api.github.com/users/M6Web/followers","following_url":"https://api.github.com/users/M6Web/following{/other_user}","gists_url":"https://api.github.com/users/M6Web/gists{/gist_id}","starred_url":"https://api.github.com/users/M6Web/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/M6Web/subscriptions","organizations_url":"https://api.github.com/users/M6Web/orgs","repos_url":"https://api.github.com/users/M6Web/repos","events_url":"https://api.github.com/users/M6Web/events{/privacy}","received_events_url":"https://api.github.com/users/M6Web/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/M6Web/Tornado","description":"A library for asynchronous programming :tornado:","fork":false,"url":"https://api.github.com/repos/M6Web/Tornado","forks_url":"https://api.github.com/repos/M6Web/Tornado/forks","keys_url":"https://api.github.com/repos/M6Web/Tornado/keys{/key_id}","collaborators_url":"https://api.github.com/repos/M6Web/Tornado/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/M6Web/Tornado/teams","hooks_url":"https://api.github.com/repos/M6Web/Tornado/hooks","issue_events_url":"https://api.github.com/repos/M6Web/Tornado/issues/events{/number}","events_url":"https://api.github.com/repos/M6Web/Tornado/events","assignees_url":"https://api.github.com/repos/M6Web/Tornado/assignees{/user}","branches_url":"https://api.github.com/repos/M6Web/Tornado/branches{/branch}","tags_url":"https://api.github.com/repos/M6Web/Tornado/tags","blobs_url":"https://api.github.com/repos/M6Web/Tornado/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/M6Web/Tornado/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/M6Web/Tornado/git/refs{/sha}","trees_url":"https://api.github.com/repos/M6Web/Tornado/git/trees{/sha}","statuses_url":"https://api.github.com/repos/M6Web/Tornado/statuses/{sha}","languages_url":"https://api.github.com/repos/M6Web/Tornado/languages","stargazers_url":"https://api.github.com/repos/M6Web/Tornado/stargazers","contributors_url":"https://api.github.com/repos/M6Web/Tornado/contributors","subscribers_url":"https://api.github.com/repos/M6Web/Tornado/subscribers","subscription_url":"https://api.github.com/repos/M6Web/Tornado/subscription","commits_url":"https://api.github.com/repos/M6Web/Tornado/commits{/sha}","git_commits_url":"https://api.github.com/repos/M6Web/Tornado/git/commits{/sha}","comments_url":"https://api.github.com/repos/M6Web/Tornado/comments{/number}","issue_comment_url":"https://api.github.com/repos/M6Web/Tornado/issues/comments{/number}","contents_url":"https://api.github.com/repos/M6Web/Tornado/contents/{+path}","compare_url":"https://api.github.com/repos/M6Web/Tornado/compare/{base}...{head}","merges_url":"https://api.github.com/repos/M6Web/Tornado/merges","archive_url":"https://api.github.com/repos/M6Web/Tornado/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/M6Web/Tornado/downloads","issues_url":"https://api.github.com/repos/M6Web/Tornado/issues{/number}","pulls_url":"https://api.github.com/repos/M6Web/Tornado/pulls{/number}","milestones_url":"https://api.github.com/repos/M6Web/Tornado/milestones{/number}","notifications_url":"https://api.github.com/repos/M6Web/Tornado/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/M6Web/Tornado/labels{/name}","releases_url":"https://api.github.com/repos/M6Web/Tornado/releases{/id}","deployments_url":"https://api.github.com/repos/M6Web/Tornado/deployments","created_at":"2018-08-23T15:23:26Z","updated_at":"2018-09-28T08:15:18Z","pushed_at":"2018-09-30T19:08:25Z","git_url":"git://github.com/M6Web/Tornado.git","ssh_url":"git@github.com:M6Web/Tornado.git","clone_url":"https://github.com/M6Web/Tornado.git","svn_url":"https://github.com/M6Web/Tornado","homepage":null,"size":77,"stargazers_count":2,"watchers_count":2,"language":"PHP","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":5,"license":null,"forks":1,"open_issues":5,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/M6Web/Tornado/pulls/15"},"html":{"href":"https://github.com/M6Web/Tornado/pull/15"},"issue":{"href":"https://api.github.com/repos/M6Web/Tornado/issues/15"},"comments":{"href":"https://api.github.com/repos/M6Web/Tornado/issues/15/comments"},"review_comments":{"href":"https://api.github.com/repos/M6Web/Tornado/pulls/15/comments"},"review_comment":{"href":"https://api.github.com/repos/M6Web/Tornado/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/M6Web/Tornado/pulls/15/commits"},"statuses":{"href":"https://api.github.com/repos/M6Web/Tornado/statuses/50d697bad23c50a37c3496d97d03d45846e74c5c"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"lucascourot"}}