{"action":"created","comment":{"url":"https://api.github.com/repos/wikimedia/restbase/pulls/comments/44621257","id":44621257,"diff_hunk":"@@ -450,6 +443,170 @@ templates:\n                 request:\n                   uri: https://wikimedia.org/api/rest_v1/metrics/pageviews/top/{+rest}\n \n+      /{module:graphoid}/v1/store/{format}:\n+        post:\n+          x-setup-handler:\n+            - init:\n+                uri: /{domain}/sys/post_data/graphoid.request\n+            - init:\n+                uri: /{domain}/sys/key_value/graphoid.png\n+                body:\n+                  keyType: string\n+                  valueType: blob\n+            - init:\n+                uri: /{domain}/sys/key_value/graphoid.svg\n+                body:\n+                  keyType: string\n+                  valueType: blob\n+          x-request-handler:\n+            - calculate_hash:\n+                request:\n+                  method: put\n+                  uri: /{domain}/sys/post_data/graphoid.request/hash\n+                  body: '{$.request.body}'\n+            - check_storage:\n+                request:\n+                  method: get\n+                  uri: /{domain}/sys/key_value/graphoid.{format}/{$.calculate_hash.body}\n+                  headers:\n+                    cache-control: '{cache-control}'\n+                return_if:\n+                  status: '2xx'\n+                return:\n+                  status: 200\n+                  headers: '{$.check_storage.headers}'\n+                  body: '{$.check_storage.body}'\n+                catch:\n+                  status: 404\n+            - load_data:\n+                request:\n+                  method: post\n+                  uri: /{domain}/sys/graphoid/v1/handler/{format}\n+                  headers:\n+                    cache-control: '{cache-control}'\n+                    x-resource-location: '{$.calculate_hash.body}'\n+                  body: '{$.request.body}'\n+            - store_request:\n+                request:\n+                  method: put\n+                  uri: /{domain}/sys/post_data/graphoid.request/\n+                  body: '{$.request.body}'\n+            - return_content:\n+                return:\n+                  status: 200\n+                  headers: '{$.load_data.headers}'\n+                  body: '{$.load_data.body}'\n+      /{module:graphoid}/v1/preview/{format}:\n+        post:\n+          x-request-handler:\n+            - calculate_hash:\n+                request:\n+                  method: put\n+                  uri: /{domain}/sys/post_data/graphoid.request/hash\n+                  body: '{$$.merge($.request.body, {\"x-restbase-mode\": \"preview\"})}'\n+            - handle_req:\n+                request:\n+                  method: post\n+                  uri: /{domain}/sys/graphoid/v1/handler/{$.request.params.format}\n+                  headers:\n+                    max-age: 3600","path":"config.example.wikimedia.yaml","position":110,"original_position":110,"commit_id":"2badd64fd8a4aef77c6e7248642212f325e38665","original_commit_id":"2badd64fd8a4aef77c6e7248642212f325e38665","user":{"login":"gwicke","id":1225898,"avatar_url":"https://avatars.githubusercontent.com/u/1225898?v=3","gravatar_id":"","url":"https://api.github.com/users/gwicke","html_url":"https://github.com/gwicke","followers_url":"https://api.github.com/users/gwicke/followers","following_url":"https://api.github.com/users/gwicke/following{/other_user}","gists_url":"https://api.github.com/users/gwicke/gists{/gist_id}","starred_url":"https://api.github.com/users/gwicke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gwicke/subscriptions","organizations_url":"https://api.github.com/users/gwicke/orgs","repos_url":"https://api.github.com/users/gwicke/repos","events_url":"https://api.github.com/users/gwicke/events{/privacy}","received_events_url":"https://api.github.com/users/gwicke/received_events","type":"User","site_admin":false},"body":"It would be nice to use a shared stash for this, instead of relying on per-row TTLs.","created_at":"2015-11-12T04:46:10Z","updated_at":"2015-11-12T04:46:10Z","html_url":"https://github.com/wikimedia/restbase/pull/388#discussion_r44621257","pull_request_url":"https://api.github.com/repos/wikimedia/restbase/pulls/388","_links":{"self":{"href":"https://api.github.com/repos/wikimedia/restbase/pulls/comments/44621257"},"html":{"href":"https://github.com/wikimedia/restbase/pull/388#discussion_r44621257"},"pull_request":{"href":"https://api.github.com/repos/wikimedia/restbase/pulls/388"}}},"pull_request":{"url":"https://api.github.com/repos/wikimedia/restbase/pulls/388","id":48794649,"html_url":"https://github.com/wikimedia/restbase/pull/388","diff_url":"https://github.com/wikimedia/restbase/pull/388.diff","patch_url":"https://github.com/wikimedia/restbase/pull/388.patch","issue_url":"https://api.github.com/repos/wikimedia/restbase/issues/388","number":388,"state":"open","locked":false,"title":"Added graphoid endpoints","user":{"login":"Pchelolo","id":814754,"avatar_url":"https://avatars.githubusercontent.com/u/814754?v=3","gravatar_id":"","url":"https://api.github.com/users/Pchelolo","html_url":"https://github.com/Pchelolo","followers_url":"https://api.github.com/users/Pchelolo/followers","following_url":"https://api.github.com/users/Pchelolo/following{/other_user}","gists_url":"https://api.github.com/users/Pchelolo/gists{/gist_id}","starred_url":"https://api.github.com/users/Pchelolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Pchelolo/subscriptions","organizations_url":"https://api.github.com/users/Pchelolo/orgs","repos_url":"https://api.github.com/users/Pchelolo/repos","events_url":"https://api.github.com/users/Pchelolo/events{/privacy}","received_events_url":"https://api.github.com/users/Pchelolo/received_events","type":"User","site_admin":false},"body":"This is a work-in-progress PR and some features are not implemented yet.\r\n\r\nAdding 2 public routes:\r\n- `POST /media/graph/{format}?mode={store|preview}` - only for internal IPs\r\n - In store mode:\r\n    - A request hash is calculated\r\n    - Storage checked for already rendered content\r\n    - Two requests are sent to graphoid for png and svg content. If error occurs - it's propagated back to user and nothing is stored.\r\n    - Results for png and svg are stored\r\n    - Request is stored\r\n    - Result returned with `x-resource-location` header\r\n - In preview mode:\r\n    - Requests are passed to graphoid png and svg endpoints\r\n    - Results are stored. To avoid clashing hashes with `store` mode, special `stub` field is added to the data when a hash is calculated. The stub field is not stored.\r\n    - Result is returned with `x-resource-location` header\r\n- `GET /media/graph/{format}/{hash}`\r\n -  Content buckets for a given format is checked.\r\n - If not found - original request is loaded\r\n - Original request sent to graphoid to regenerate content\r\n - Result is stored and returned.\r\n\r\nBoth endpoints support `cache-control: no-cache` header to force rerendering.\r\n\r\nWhat's left:\r\n- Title and revision are not stored for debugging purposes yet - need to make some changes in post_data to not use them is hash calculation\r\n- Monitoring should be added to endpoints\r\n- Graphoid endpoints are not deployed yet, so all graphoid tests are failing.\r\n- There's not way to set _TTL for storage yet, so right now everything is stored permanently, even `preview` content.","created_at":"2015-10-26T20:45:13Z","updated_at":"2015-11-12T04:46:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"34429dcc89b70e377bbbfdb5d2b28096092bf3e4","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/wikimedia/restbase/pulls/388/commits","review_comments_url":"https://api.github.com/repos/wikimedia/restbase/pulls/388/comments","review_comment_url":"https://api.github.com/repos/wikimedia/restbase/pulls/comments{/number}","comments_url":"https://api.github.com/repos/wikimedia/restbase/issues/388/comments","statuses_url":"https://api.github.com/repos/wikimedia/restbase/statuses/2badd64fd8a4aef77c6e7248642212f325e38665","head":{"label":"Pchelolo:graphoid","ref":"graphoid","sha":"2badd64fd8a4aef77c6e7248642212f325e38665","user":{"login":"Pchelolo","id":814754,"avatar_url":"https://avatars.githubusercontent.com/u/814754?v=3","gravatar_id":"","url":"https://api.github.com/users/Pchelolo","html_url":"https://github.com/Pchelolo","followers_url":"https://api.github.com/users/Pchelolo/followers","following_url":"https://api.github.com/users/Pchelolo/following{/other_user}","gists_url":"https://api.github.com/users/Pchelolo/gists{/gist_id}","starred_url":"https://api.github.com/users/Pchelolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Pchelolo/subscriptions","organizations_url":"https://api.github.com/users/Pchelolo/orgs","repos_url":"https://api.github.com/users/Pchelolo/repos","events_url":"https://api.github.com/users/Pchelolo/events{/privacy}","received_events_url":"https://api.github.com/users/Pchelolo/received_events","type":"User","site_admin":false},"repo":{"id":37933525,"name":"restbase","full_name":"Pchelolo/restbase","owner":{"login":"Pchelolo","id":814754,"avatar_url":"https://avatars.githubusercontent.com/u/814754?v=3","gravatar_id":"","url":"https://api.github.com/users/Pchelolo","html_url":"https://github.com/Pchelolo","followers_url":"https://api.github.com/users/Pchelolo/followers","following_url":"https://api.github.com/users/Pchelolo/following{/other_user}","gists_url":"https://api.github.com/users/Pchelolo/gists{/gist_id}","starred_url":"https://api.github.com/users/Pchelolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Pchelolo/subscriptions","organizations_url":"https://api.github.com/users/Pchelolo/orgs","repos_url":"https://api.github.com/users/Pchelolo/repos","events_url":"https://api.github.com/users/Pchelolo/events{/privacy}","received_events_url":"https://api.github.com/users/Pchelolo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Pchelolo/restbase","description":"Distributed storage with REST API & dispatcher for backend services","fork":true,"url":"https://api.github.com/repos/Pchelolo/restbase","forks_url":"https://api.github.com/repos/Pchelolo/restbase/forks","keys_url":"https://api.github.com/repos/Pchelolo/restbase/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Pchelolo/restbase/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Pchelolo/restbase/teams","hooks_url":"https://api.github.com/repos/Pchelolo/restbase/hooks","issue_events_url":"https://api.github.com/repos/Pchelolo/restbase/issues/events{/number}","events_url":"https://api.github.com/repos/Pchelolo/restbase/events","assignees_url":"https://api.github.com/repos/Pchelolo/restbase/assignees{/user}","branches_url":"https://api.github.com/repos/Pchelolo/restbase/branches{/branch}","tags_url":"https://api.github.com/repos/Pchelolo/restbase/tags","blobs_url":"https://api.github.com/repos/Pchelolo/restbase/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Pchelolo/restbase/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Pchelolo/restbase/git/refs{/sha}","trees_url":"https://api.github.com/repos/Pchelolo/restbase/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Pchelolo/restbase/statuses/{sha}","languages_url":"https://api.github.com/repos/Pchelolo/restbase/languages","stargazers_url":"https://api.github.com/repos/Pchelolo/restbase/stargazers","contributors_url":"https://api.github.com/repos/Pchelolo/restbase/contributors","subscribers_url":"https://api.github.com/repos/Pchelolo/restbase/subscribers","subscription_url":"https://api.github.com/repos/Pchelolo/restbase/subscription","commits_url":"https://api.github.com/repos/Pchelolo/restbase/commits{/sha}","git_commits_url":"https://api.github.com/repos/Pchelolo/restbase/git/commits{/sha}","comments_url":"https://api.github.com/repos/Pchelolo/restbase/comments{/number}","issue_comment_url":"https://api.github.com/repos/Pchelolo/restbase/issues/comments{/number}","contents_url":"https://api.github.com/repos/Pchelolo/restbase/contents/{+path}","compare_url":"https://api.github.com/repos/Pchelolo/restbase/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Pchelolo/restbase/merges","archive_url":"https://api.github.com/repos/Pchelolo/restbase/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Pchelolo/restbase/downloads","issues_url":"https://api.github.com/repos/Pchelolo/restbase/issues{/number}","pulls_url":"https://api.github.com/repos/Pchelolo/restbase/pulls{/number}","milestones_url":"https://api.github.com/repos/Pchelolo/restbase/milestones{/number}","notifications_url":"https://api.github.com/repos/Pchelolo/restbase/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Pchelolo/restbase/labels{/name}","releases_url":"https://api.github.com/repos/Pchelolo/restbase/releases{/id}","created_at":"2015-06-23T17:22:56Z","updated_at":"2015-06-23T17:22:57Z","pushed_at":"2015-11-11T14:03:07Z","git_url":"git://github.com/Pchelolo/restbase.git","ssh_url":"git@github.com:Pchelolo/restbase.git","clone_url":"https://github.com/Pchelolo/restbase.git","svn_url":"https://github.com/Pchelolo/restbase","homepage":"https://www.mediawiki.org/wiki/RESTBase","size":2840,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"wikimedia:master","ref":"master","sha":"d417cfce77ae49a0391cb7b24d3af469507caa48","user":{"login":"wikimedia","id":56668,"avatar_url":"https://avatars.githubusercontent.com/u/56668?v=3","gravatar_id":"","url":"https://api.github.com/users/wikimedia","html_url":"https://github.com/wikimedia","followers_url":"https://api.github.com/users/wikimedia/followers","following_url":"https://api.github.com/users/wikimedia/following{/other_user}","gists_url":"https://api.github.com/users/wikimedia/gists{/gist_id}","starred_url":"https://api.github.com/users/wikimedia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wikimedia/subscriptions","organizations_url":"https://api.github.com/users/wikimedia/orgs","repos_url":"https://api.github.com/users/wikimedia/repos","events_url":"https://api.github.com/users/wikimedia/events{/privacy}","received_events_url":"https://api.github.com/users/wikimedia/received_events","type":"Organization","site_admin":false},"repo":{"id":19002414,"name":"restbase","full_name":"wikimedia/restbase","owner":{"login":"wikimedia","id":56668,"avatar_url":"https://avatars.githubusercontent.com/u/56668?v=3","gravatar_id":"","url":"https://api.github.com/users/wikimedia","html_url":"https://github.com/wikimedia","followers_url":"https://api.github.com/users/wikimedia/followers","following_url":"https://api.github.com/users/wikimedia/following{/other_user}","gists_url":"https://api.github.com/users/wikimedia/gists{/gist_id}","starred_url":"https://api.github.com/users/wikimedia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wikimedia/subscriptions","organizations_url":"https://api.github.com/users/wikimedia/orgs","repos_url":"https://api.github.com/users/wikimedia/repos","events_url":"https://api.github.com/users/wikimedia/events{/privacy}","received_events_url":"https://api.github.com/users/wikimedia/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/wikimedia/restbase","description":"Distributed storage with REST API & dispatcher for backend services","fork":false,"url":"https://api.github.com/repos/wikimedia/restbase","forks_url":"https://api.github.com/repos/wikimedia/restbase/forks","keys_url":"https://api.github.com/repos/wikimedia/restbase/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wikimedia/restbase/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wikimedia/restbase/teams","hooks_url":"https://api.github.com/repos/wikimedia/restbase/hooks","issue_events_url":"https://api.github.com/repos/wikimedia/restbase/issues/events{/number}","events_url":"https://api.github.com/repos/wikimedia/restbase/events","assignees_url":"https://api.github.com/repos/wikimedia/restbase/assignees{/user}","branches_url":"https://api.github.com/repos/wikimedia/restbase/branches{/branch}","tags_url":"https://api.github.com/repos/wikimedia/restbase/tags","blobs_url":"https://api.github.com/repos/wikimedia/restbase/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wikimedia/restbase/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wikimedia/restbase/git/refs{/sha}","trees_url":"https://api.github.com/repos/wikimedia/restbase/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wikimedia/restbase/statuses/{sha}","languages_url":"https://api.github.com/repos/wikimedia/restbase/languages","stargazers_url":"https://api.github.com/repos/wikimedia/restbase/stargazers","contributors_url":"https://api.github.com/repos/wikimedia/restbase/contributors","subscribers_url":"https://api.github.com/repos/wikimedia/restbase/subscribers","subscription_url":"https://api.github.com/repos/wikimedia/restbase/subscription","commits_url":"https://api.github.com/repos/wikimedia/restbase/commits{/sha}","git_commits_url":"https://api.github.com/repos/wikimedia/restbase/git/commits{/sha}","comments_url":"https://api.github.com/repos/wikimedia/restbase/comments{/number}","issue_comment_url":"https://api.github.com/repos/wikimedia/restbase/issues/comments{/number}","contents_url":"https://api.github.com/repos/wikimedia/restbase/contents/{+path}","compare_url":"https://api.github.com/repos/wikimedia/restbase/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wikimedia/restbase/merges","archive_url":"https://api.github.com/repos/wikimedia/restbase/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wikimedia/restbase/downloads","issues_url":"https://api.github.com/repos/wikimedia/restbase/issues{/number}","pulls_url":"https://api.github.com/repos/wikimedia/restbase/pulls{/number}","milestones_url":"https://api.github.com/repos/wikimedia/restbase/milestones{/number}","notifications_url":"https://api.github.com/repos/wikimedia/restbase/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wikimedia/restbase/labels{/name}","releases_url":"https://api.github.com/repos/wikimedia/restbase/releases{/id}","created_at":"2014-04-21T18:35:00Z","updated_at":"2015-11-04T16:44:05Z","pushed_at":"2015-11-12T00:26:31Z","git_url":"git://github.com/wikimedia/restbase.git","ssh_url":"git@github.com:wikimedia/restbase.git","clone_url":"https://github.com/wikimedia/restbase.git","svn_url":"https://github.com/wikimedia/restbase","homepage":"https://www.mediawiki.org/wiki/RESTBase","size":5243,"stargazers_count":33,"watchers_count":33,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":28,"mirror_url":null,"open_issues_count":5,"forks":28,"open_issues":5,"watchers":33,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/wikimedia/restbase/pulls/388"},"html":{"href":"https://github.com/wikimedia/restbase/pull/388"},"issue":{"href":"https://api.github.com/repos/wikimedia/restbase/issues/388"},"comments":{"href":"https://api.github.com/repos/wikimedia/restbase/issues/388/comments"},"review_comments":{"href":"https://api.github.com/repos/wikimedia/restbase/pulls/388/comments"},"review_comment":{"href":"https://api.github.com/repos/wikimedia/restbase/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/wikimedia/restbase/pulls/388/commits"},"statuses":{"href":"https://api.github.com/repos/wikimedia/restbase/statuses/2badd64fd8a4aef77c6e7248642212f325e38665"}}}}