{"action":"created","comment":{"url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/comments/49105754","id":49105754,"diff_hunk":"@@ -4,54 +4,246 @@ import (\n \t\"errors\"\n )\n \n-type message struct {\n-\tmethod          string\n-\tseqno           seqNumber\n-\tres             interface{}\n-\terr             interface{}\n-\tremainingFields int\n-\tdecodeSlots     []interface{}\n-}\n-\n-func decodeIntoMessage(dec decoder, m *message) error {\n-\tfor _, s := range m.decodeSlots {\n-\t\tif err := decodeMessage(dec, m, s); err != nil {\n-\t\t\treturn err\n+type RPCMessage interface {\n+\tType() MethodType\n+\tDecode(l int, d decoder, p *protocolHandler, cc *callContainer) error\n+\tRPCData\n+}\n+\n+type RPCData interface {\n+\tName() string\n+\tArg() interface{}\n+\tSeqNo() seqNumber\n+\tErr() error\n+\tRes() interface{}\n+\tResponseCh() chan RPCMessage\n+\tMinLength() int\n+\tDecodeData(int, decoder, *protocolHandler, *callContainer) error\n+}\n+\n+type BasicRPCData struct{}\n+\n+func (BasicRPCData) Name() string {\n+\tpanic(\"Name() not implemented for this type\")\n+}\n+\n+func (BasicRPCData) Arg() interface{} {\n+\tpanic(\"Arg() not implemented for this type\")\n+}\n+\n+func (BasicRPCData) SeqNo() seqNumber {\n+\tpanic(\"SeqNo() not implemented for this type\")\n+}\n+\n+func (BasicRPCData) Err() error {\n+\tpanic(\"Err() not implemented for this type\")\n+}\n+\n+func (BasicRPCData) Res() interface{} {\n+\tpanic(\"Res() not implemented for this type\")\n+}\n+\n+func (BasicRPCData) ResponseCh() chan RPCMessage {\n+\tpanic(\"ResponseCh() not implemented for this type\")\n+}\n+\n+type RPCCallData struct {\n+\tBasicRPCData\n+\tseqno seqNumber\n+\tname  string\n+\targ   interface{}\n+}\n+\n+func (RPCCallData) MinLength() int {\n+\treturn 3\n+}\n+\n+func (r *RPCCallData) DecodeData(l int, d decoder, p *protocolHandler, _ *callContainer) (err error) {\n+\tif err = d.Decode(&r.seqno); err != nil {\n+\t\treturn err\n+\t}\n+\tif err = d.Decode(&r.name); err != nil {\n+\t\treturn err\n+\t}\n+\tif r.arg, err = p.getArg(r.name); err != nil {\n+\t\treturn err\n+\t}\n+\treturn d.Decode(r.arg)\n+}\n+\n+func (r RPCCallData) SeqNo() seqNumber {\n+\treturn r.seqno\n+}\n+\n+func (r RPCCallData) Name() string {\n+\treturn r.name\n+}\n+\n+func (r RPCCallData) Arg() interface{} {\n+\treturn r.arg\n+}\n+\n+type RPCResponseData struct {\n+\tBasicRPCData\n+\tc   *call\n+\terr error\n+}\n+\n+func (r RPCResponseData) MinLength() int {\n+\treturn 3\n+}\n+\n+func (r *RPCResponseData) DecodeData(l int, d decoder, _ *protocolHandler, cc *callContainer) error {\n+\tvar seqNo seqNumber\n+\tif err := d.Decode(&seqNo); err != nil {\n+\t\treturn err\n+\t}\n+\n+\t// Attempt to retrieve the call\n+\tr.c = cc.RetrieveCall(seqNo)\n+\tif r.c == nil {\n+\t\treturn CallNotFoundError{seqNo}\n+\t}\n+\n+\t// Decode the error\n+\tvar responseErr interface{}\n+\tif r.c.errorUnwrapper != nil {\n+\t\tresponseErr = r.c.errorUnwrapper.MakeArg()\n+\t}\n+\tif err := d.Decode(responseErr); err != nil {\n+\t\treturn err\n+\t}\n+\n+\t// Ensure the error is wrapped correctly\n+\tif r.c.errorUnwrapper != nil {\n+\t\tvar dispatchErr error\n+\t\tr.err, dispatchErr = r.c.errorUnwrapper.UnwrapError(responseErr)\n+\t\tif dispatchErr != nil {\n+\t\t\treturn dispatchErr\n+\t\t}\n+\t} else if responseErr != nil {\n+\t\terrAsString, ok := responseErr.(*string)\n+\t\tif !ok {\n+\t\t\treturn errors.New(\"unable to convert error to string\")\n \t\t}\n+\t\tr.err = errors.New(*errAsString)\n+\t}\n+\n+\t// Decode the result\n+\tif r.c.res == nil {\n+\t\tr.c.res = new(interface{})\n \t}\n-\treturn nil\n+\treturn d.Decode(r.c.res)\n+}\n+\n+func (r RPCResponseData) SeqNo() seqNumber {\n+\treturn r.c.seqid\n }\n \n-func decodeMessage(dec decoder, m *message, i interface{}) error {\n-\terr := dec.Decode(i)\n-\t// TODO need to verify whether codec.Decode pulls from the reader if\n-\t// the decode fails, or whether the reader stays in the same state\n-\t// as before the Decode\n-\tm.remainingFields--\n-\treturn err\n+func (r RPCResponseData) Name() string {\n+\treturn r.c.method\n }\n \n-func decodeToNull(dec decoder, m *message) error {\n-\tvar err error\n-\tfor err == nil && m.remainingFields > 0 {\n-\t\ti := new(interface{})\n-\t\terr = decodeMessage(dec, m, i)\n+func (r RPCResponseData) Err() error {\n+\treturn r.err\n+}\n+\n+func (r RPCResponseData) Res() interface{} {\n+\treturn r.c.res\n+}\n+\n+func (r RPCResponseData) ResponseCh() chan RPCMessage {\n+\treturn r.c.resultCh\n+}\n+\n+type RPCNotifyData struct {\n+\tBasicRPCData\n+\tname string\n+\targ  interface{}\n+}\n+\n+func (r *RPCNotifyData) DecodeData(l int, d decoder, p *protocolHandler, _ *callContainer) (err error) {\n+\tif err = d.Decode(&r.name); err != nil {\n+\t\treturn err\n \t}\n-\treturn err\n+\tif r.arg, err = p.getArg(r.name); err != nil {\n+\t\treturn err\n+\t}\n+\treturn d.Decode(r.arg)\n }\n \n-func decodeError(dec decoder, m *message, f ErrorUnwrapper) (appErr error, dispatchErr error) {\n-\tif f != nil {\n-\t\targ := f.MakeArg()\n-\t\terr := decodeMessage(dec, m, arg)\n-\t\tif err != nil {\n-\t\t\treturn nil, err\n-\t\t}\n-\t\treturn f.UnwrapError(arg)\n+func (RPCNotifyData) MinLength() int {\n+\treturn 2\n+}\n+\n+func (r RPCNotifyData) SeqNo() seqNumber {\n+\treturn -1\n+}\n+\n+func (r RPCNotifyData) Name() string {\n+\treturn r.name\n+}\n+\n+func (r RPCNotifyData) Arg() interface{} {\n+\treturn r.arg\n+}\n+\n+type RPCCancelData struct {\n+\tBasicRPCData\n+\tseqno seqNumber\n+\tname  string\n+}\n+\n+func (r *RPCCancelData) DecodeData(l int, d decoder, p *protocolHandler, _ *callContainer) (err error) {\n+\tif err = d.Decode(&r.seqno); err != nil {\n+\t\treturn err\n+\t}\n+\treturn d.Decode(&r.name)\n+}\n+\n+func (RPCCancelData) MinLength() int {\n+\treturn 2\n+}\n+\n+func (r RPCCancelData) SeqNo() seqNumber {\n+\treturn r.seqno\n+}\n+\n+func (r RPCCancelData) Name() string {\n+\treturn r.name\n+}\n+\n+type RPCCall struct {\n+\ttyp MethodType\n+\n+\tRPCData\n+}\n+\n+func (c RPCCall) Type() MethodType {\n+\treturn c.typ\n+}\n+\n+func (c *RPCCall) Decode(l int, d decoder, p *protocolHandler, cc *callContainer) error {\n+\tif err := d.Decode(&c.typ); err != nil {\n+\t\treturn err\n+\t}\n+\n+\tswitch c.typ {\n+\tcase MethodCall:\n+\t\tc.RPCData = &RPCCallData{}\n+\tcase MethodResponse:\n+\t\tc.RPCData = &RPCResponseData{}\n+\tcase MethodNotify:\n+\t\tc.RPCData = &RPCNotifyData{}\n+\tcase MethodCancel:\n+\t\tc.RPCData = &RPCCancelData{}\n+\tdefault:\n+\t\tc.RPCData = nil\n+\t\treturn errors.New(\"invalid RPC type\")\n \t}\n-\tvar s string\n-\tif dispatchErr = decodeMessage(dec, m, &s); dispatchErr == nil && len(s) > 0 {\n-\t\tappErr = errors.New(s)\n+\tl--","path":"message.go","position":279,"original_position":279,"commit_id":"80d780577b9e29f059fc95af56cee6117ff144f3","original_commit_id":"80d780577b9e29f059fc95af56cee6117ff144f3","user":{"login":"jzila","id":59594,"avatar_url":"https://avatars.githubusercontent.com/u/59594?v=3","gravatar_id":"","url":"https://api.github.com/users/jzila","html_url":"https://github.com/jzila","followers_url":"https://api.github.com/users/jzila/followers","following_url":"https://api.github.com/users/jzila/following{/other_user}","gists_url":"https://api.github.com/users/jzila/gists{/gist_id}","starred_url":"https://api.github.com/users/jzila/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jzila/subscriptions","organizations_url":"https://api.github.com/users/jzila/orgs","repos_url":"https://api.github.com/users/jzila/repos","events_url":"https://api.github.com/users/jzila/events{/privacy}","received_events_url":"https://api.github.com/users/jzila/received_events","type":"User","site_admin":false},"body":"It can't go first because we first need to know the type of the `RPCData`.","created_at":"2016-01-07T18:19:52Z","updated_at":"2016-01-07T18:19:52Z","html_url":"https://github.com/keybase/go-framed-msgpack-rpc/pull/50#discussion_r49105754","pull_request_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/50","_links":{"self":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/comments/49105754"},"html":{"href":"https://github.com/keybase/go-framed-msgpack-rpc/pull/50#discussion_r49105754"},"pull_request":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/50"}}},"pull_request":{"url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/50","id":55045644,"html_url":"https://github.com/keybase/go-framed-msgpack-rpc/pull/50","diff_url":"https://github.com/keybase/go-framed-msgpack-rpc/pull/50.diff","patch_url":"https://github.com/keybase/go-framed-msgpack-rpc/pull/50.patch","issue_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues/50","number":50,"state":"open","locked":false,"title":"RPC Async Refactor","user":{"login":"jzila","id":59594,"avatar_url":"https://avatars.githubusercontent.com/u/59594?v=3","gravatar_id":"","url":"https://api.github.com/users/jzila","html_url":"https://github.com/jzila","followers_url":"https://api.github.com/users/jzila/followers","following_url":"https://api.github.com/users/jzila/following{/other_user}","gists_url":"https://api.github.com/users/jzila/gists{/gist_id}","starred_url":"https://api.github.com/users/jzila/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jzila/subscriptions","organizations_url":"https://api.github.com/users/jzila/orgs","repos_url":"https://api.github.com/users/jzila/repos","events_url":"https://api.github.com/users/jzila/events{/privacy}","received_events_url":"https://api.github.com/users/jzila/received_events","type":"User","site_admin":false},"body":"Fixes #7, #26, #29, #30, #38, #41, #44, #46, #49.\r\n\r\nOverall Changes:\r\n\r\n1. `packetizer` now loads the entire frame from the stream as a `[]byte`. It first loads the length of the frame and reads that many bytes, then hands the resulting `[]byte` to a pooled `codec.Decoder` using [`ResetBytes`](https://godoc.org/github.com/ugorji/go/codec#Decoder.ResetBytes) (zero-copy).\r\n1. `RPCMessage`s now own decoding themselves, for which they need a little bit of extra information: `protocolHandler`, and `callContainer` (new). The `transporter` is responsible for handing that information to the `packetHandler`. The `packetHandler` now owns all the interaction with the frame, delegating the `protocolHandler`, `callContainer`, and the frame's `codec.Decoder` to the `RPCMessage` to allow it to decode itself.\r\n1. `callContainer` now controls synchronized access to the `call` map, so it can be consulted by consumers to manage `call`s in flight.\r\n1. `protocolHandler` access is now synchronized.\r\n1. Dispatched calls now execute linearly, blocking the calling goroutine as appropriate, allowing them to clean up after themselves without any outside knowledge.\r\n1. Received messages are now handled in their final type-safe format, so there is no longer a decoding mess that has to be performed while handling a call.\r\n\r\n...and other miscellaneous smaller bugfixes.\r\n\r\nAll of this is done while preserving the zero-copy requirement that @maxtaco originally designed into this library.","created_at":"2016-01-05T01:38:12Z","updated_at":"2016-01-07T18:19:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7e4d3020f768ac783ecc9289ddb9f699e716a766","assignee":{"login":"akalin-keybase","id":13270622,"avatar_url":"https://avatars.githubusercontent.com/u/13270622?v=3","gravatar_id":"","url":"https://api.github.com/users/akalin-keybase","html_url":"https://github.com/akalin-keybase","followers_url":"https://api.github.com/users/akalin-keybase/followers","following_url":"https://api.github.com/users/akalin-keybase/following{/other_user}","gists_url":"https://api.github.com/users/akalin-keybase/gists{/gist_id}","starred_url":"https://api.github.com/users/akalin-keybase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akalin-keybase/subscriptions","organizations_url":"https://api.github.com/users/akalin-keybase/orgs","repos_url":"https://api.github.com/users/akalin-keybase/repos","events_url":"https://api.github.com/users/akalin-keybase/events{/privacy}","received_events_url":"https://api.github.com/users/akalin-keybase/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/50/commits","review_comments_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/50/comments","review_comment_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/comments{/number}","comments_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues/50/comments","statuses_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/statuses/80d780577b9e29f059fc95af56cee6117ff144f3","head":{"label":"keybase:jzila/rpc-refactor","ref":"jzila/rpc-refactor","sha":"80d780577b9e29f059fc95af56cee6117ff144f3","user":{"login":"keybase","id":5400834,"avatar_url":"https://avatars.githubusercontent.com/u/5400834?v=3","gravatar_id":"","url":"https://api.github.com/users/keybase","html_url":"https://github.com/keybase","followers_url":"https://api.github.com/users/keybase/followers","following_url":"https://api.github.com/users/keybase/following{/other_user}","gists_url":"https://api.github.com/users/keybase/gists{/gist_id}","starred_url":"https://api.github.com/users/keybase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keybase/subscriptions","organizations_url":"https://api.github.com/users/keybase/orgs","repos_url":"https://api.github.com/users/keybase/repos","events_url":"https://api.github.com/users/keybase/events{/privacy}","received_events_url":"https://api.github.com/users/keybase/received_events","type":"Organization","site_admin":false},"repo":{"id":43102191,"name":"go-framed-msgpack-rpc","full_name":"keybase/go-framed-msgpack-rpc","owner":{"login":"keybase","id":5400834,"avatar_url":"https://avatars.githubusercontent.com/u/5400834?v=3","gravatar_id":"","url":"https://api.github.com/users/keybase","html_url":"https://github.com/keybase","followers_url":"https://api.github.com/users/keybase/followers","following_url":"https://api.github.com/users/keybase/following{/other_user}","gists_url":"https://api.github.com/users/keybase/gists{/gist_id}","starred_url":"https://api.github.com/users/keybase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keybase/subscriptions","organizations_url":"https://api.github.com/users/keybase/orgs","repos_url":"https://api.github.com/users/keybase/repos","events_url":"https://api.github.com/users/keybase/events{/privacy}","received_events_url":"https://api.github.com/users/keybase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/keybase/go-framed-msgpack-rpc","description":"Framed RPC for go","fork":true,"url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc","forks_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/forks","keys_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/teams","hooks_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/hooks","issue_events_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues/events{/number}","events_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/events","assignees_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/assignees{/user}","branches_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/branches{/branch}","tags_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/tags","blobs_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/refs{/sha}","trees_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/statuses/{sha}","languages_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/languages","stargazers_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/stargazers","contributors_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/contributors","subscribers_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/subscribers","subscription_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/subscription","commits_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/commits{/sha}","git_commits_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/commits{/sha}","comments_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/comments{/number}","issue_comment_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues/comments{/number}","contents_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/contents/{+path}","compare_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/merges","archive_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/downloads","issues_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues{/number}","pulls_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls{/number}","milestones_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/milestones{/number}","notifications_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/labels{/name}","releases_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/releases{/id}","created_at":"2015-09-25T01:19:58Z","updated_at":"2015-10-03T15:52:20Z","pushed_at":"2016-01-06T20:19:39Z","git_url":"git://github.com/keybase/go-framed-msgpack-rpc.git","ssh_url":"git@github.com:keybase/go-framed-msgpack-rpc.git","clone_url":"https://github.com/keybase/go-framed-msgpack-rpc.git","svn_url":"https://github.com/keybase/go-framed-msgpack-rpc","homepage":null,"size":230,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":13,"forks":0,"open_issues":13,"watchers":0,"default_branch":"master"}},"base":{"label":"keybase:master","ref":"master","sha":"4e25f5ec641df586094c295c65df85e2836b5d10","user":{"login":"keybase","id":5400834,"avatar_url":"https://avatars.githubusercontent.com/u/5400834?v=3","gravatar_id":"","url":"https://api.github.com/users/keybase","html_url":"https://github.com/keybase","followers_url":"https://api.github.com/users/keybase/followers","following_url":"https://api.github.com/users/keybase/following{/other_user}","gists_url":"https://api.github.com/users/keybase/gists{/gist_id}","starred_url":"https://api.github.com/users/keybase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keybase/subscriptions","organizations_url":"https://api.github.com/users/keybase/orgs","repos_url":"https://api.github.com/users/keybase/repos","events_url":"https://api.github.com/users/keybase/events{/privacy}","received_events_url":"https://api.github.com/users/keybase/received_events","type":"Organization","site_admin":false},"repo":{"id":43102191,"name":"go-framed-msgpack-rpc","full_name":"keybase/go-framed-msgpack-rpc","owner":{"login":"keybase","id":5400834,"avatar_url":"https://avatars.githubusercontent.com/u/5400834?v=3","gravatar_id":"","url":"https://api.github.com/users/keybase","html_url":"https://github.com/keybase","followers_url":"https://api.github.com/users/keybase/followers","following_url":"https://api.github.com/users/keybase/following{/other_user}","gists_url":"https://api.github.com/users/keybase/gists{/gist_id}","starred_url":"https://api.github.com/users/keybase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keybase/subscriptions","organizations_url":"https://api.github.com/users/keybase/orgs","repos_url":"https://api.github.com/users/keybase/repos","events_url":"https://api.github.com/users/keybase/events{/privacy}","received_events_url":"https://api.github.com/users/keybase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/keybase/go-framed-msgpack-rpc","description":"Framed RPC for go","fork":true,"url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc","forks_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/forks","keys_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/teams","hooks_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/hooks","issue_events_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues/events{/number}","events_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/events","assignees_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/assignees{/user}","branches_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/branches{/branch}","tags_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/tags","blobs_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/refs{/sha}","trees_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/statuses/{sha}","languages_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/languages","stargazers_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/stargazers","contributors_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/contributors","subscribers_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/subscribers","subscription_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/subscription","commits_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/commits{/sha}","git_commits_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/git/commits{/sha}","comments_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/comments{/number}","issue_comment_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues/comments{/number}","contents_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/contents/{+path}","compare_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/merges","archive_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/downloads","issues_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues{/number}","pulls_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls{/number}","milestones_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/milestones{/number}","notifications_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/labels{/name}","releases_url":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/releases{/id}","created_at":"2015-09-25T01:19:58Z","updated_at":"2015-10-03T15:52:20Z","pushed_at":"2016-01-06T20:19:39Z","git_url":"git://github.com/keybase/go-framed-msgpack-rpc.git","ssh_url":"git@github.com:keybase/go-framed-msgpack-rpc.git","clone_url":"https://github.com/keybase/go-framed-msgpack-rpc.git","svn_url":"https://github.com/keybase/go-framed-msgpack-rpc","homepage":null,"size":230,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":13,"forks":0,"open_issues":13,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/50"},"html":{"href":"https://github.com/keybase/go-framed-msgpack-rpc/pull/50"},"issue":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues/50"},"comments":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/issues/50/comments"},"review_comments":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/50/comments"},"review_comment":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/pulls/50/commits"},"statuses":{"href":"https://api.github.com/repos/keybase/go-framed-msgpack-rpc/statuses/80d780577b9e29f059fc95af56cee6117ff144f3"}}}}