{"action":"created","comment":{"url":"https://api.github.com/repos/basho/machi/pulls/comments/42238874","id":42238874,"diff_hunk":"@@ -548,12 +548,119 @@ do_read_chunk2(File, Offset, Size, Depth, STime, TO,\n             read_repair(ConsistencyMode, read, File, Offset, Size, Depth, STime, S);\n             %% {reply, {error, not_written}, S};\n         {error, written} ->\n-            exit({todo_should_never_happen,?MODULE,?LINE,File,Offset,Size})\n+            exit({todo_should_never_happen,?MODULE,?LINE,File,Offset,Size});\n+        {error, trimmed}=Err ->\n+            {reply, Err, S}\n+    end.\n+\n+do_trim_chunk(File, Offset, Size, 0=Depth, STime, TO, S) ->\n+    do_trim_chunk(File, Offset, Size, Depth+1, STime, TO, S);\n+    \n+do_trim_chunk(File, Offset, Size, Depth, STime, TO, #state{proj=P}=S) ->\n+    sleep_a_while(Depth),\n+    DiffMs = timer:now_diff(os:timestamp(), STime) div 1000,\n+    if DiffMs > TO ->\n+            {reply, {error, partition}, S};\n+       true ->\n+            %% This is suboptimal for performance: there are some paths\n+            %% through this point where our current projection is good\n+            %% enough.  But we're going to try to keep the code as simple\n+            %% as we can for now.\n+            S2 = update_proj(S#state{proj=undefined, bad_proj=P}),\n+            case S2#state.proj of\n+                P2 when P2 == undefined orelse\n+                        P2#projection_v1.upi == [] ->\n+                    do_trim_chunk(File, Offset, Size, Depth + 1,\n+                                  STime, TO, S2);\n+                _ ->\n+                    do_trim_chunk2(File, Offset, Size, Depth + 1,\n+                                   STime, TO, S2)\n+            end\n+    end.\n+\n+do_trim_chunk2(File, Offset, Size, Depth, STime, TO,\n+               #state{epoch_id=EpochID, proj=P, proxies_dict=PD}=S) ->\n+    [HeadFLU|RestFLUs] = mutation_flus(P),\n+    Proxy = orddict:fetch(HeadFLU, PD),\n+    case ?FLU_PC:trim_chunk(Proxy, EpochID, File, Offset, Size, ?TIMEOUT) of\n+        ok ->\n+            %% From this point onward, we use the same code & logic path as\n+            %% append does.\n+            do_trim_midtail(RestFLUs, undefined, File, Offset, Size,\n+                            [HeadFLU], 0, STime, TO, S);\n+        {error, bad_checksum}=BadCS ->\n+            {reply, BadCS, S};\n+        {error, Retry}\n+          when Retry == partition; Retry == bad_epoch; Retry == wedged ->\n+            do_trim_chunk(File, Offset, Size, Depth, STime, TO, S);\n+        {error, trimmed} ->\n+            {reply, ok, S}\n+    end.\n+\n+do_trim_midtail(RestFLUs, Prefix, File, Offset, Size,\n+                Ws, Depth, STime, TO, S)\n+  when RestFLUs == [] orelse Depth == 0 ->\n+       do_trim_midtail2(RestFLUs, Prefix, File, Offset, Size,\n+                        Ws, Depth + 1, STime, TO, S);\n+do_trim_midtail(_RestFLUs, Prefix, File, Offset, Size,\n+                Ws, Depth, STime, TO, #state{proj=P}=S) ->\n+    %% io:format(user, \"midtail sleep2,\", []),\n+    sleep_a_while(Depth),\n+    DiffMs = timer:now_diff(os:timestamp(), STime) div 1000,\n+    if DiffMs > TO ->\n+            {reply, {error, partition}, S};\n+       true ->\n+            S2 = update_proj(S#state{proj=undefined, bad_proj=P}),\n+            case S2#state.proj of\n+                undefined ->\n+                    {reply, {error, partition}, S};\n+                P2 ->\n+                    RestFLUs2 = mutation_flus(P2),\n+                    case RestFLUs2 -- Ws of\n+                        RestFLUs2 ->\n+                            %% None of the writes that we have done so far\n+                            %% are to FLUs that are in the RestFLUs2 list.\n+                            %% We are pessimistic here and assume that\n+                            %% those FLUs are permanently dead.  Start\n+                            %% over with a new sequencer assignment, at\n+                            %% the 2nd have of the impl (we have already\n+                            %% slept & refreshed the projection).\n+\n+                            if Prefix == undefined -> % atom! not binary()!!\n+                                    {error, partition};\n+                               true ->\n+                                    do_trim_chunk(Prefix, Offset, Size,\n+                                                  Depth, STime, TO, S2)\n+                            end;\n+                        RestFLUs3 ->\n+                            do_trim_midtail2(RestFLUs3, Prefix, File, Offset, Size,\n+                                             Ws, Depth + 1, STime, TO, S2)\n+                    end\n+            end\n+    end.            \n+\n+do_trim_midtail2([], _Prefix, _File, _Offset, _Size,\n+                   _Ws, _Depth, _STime, _TO, S) ->\n+    %% io:format(user, \"ok!\\n\", []),\n+    {reply, ok, S};\n+do_trim_midtail2([FLU|RestFLUs]=FLUs, Prefix, File, Offset, Size,\n+                   Ws, Depth, STime, TO,\n+                   #state{epoch_id=EpochID, proxies_dict=PD}=S) ->\n+    Proxy = orddict:fetch(FLU, PD),\n+    case ?FLU_PC:trim_chunk(Proxy, EpochID, File, Offset, Size, ?TIMEOUT) of\n+        ok ->\n+            %% io:format(user, \"write ~w,\", [FLU]),\n+            do_trim_midtail2(RestFLUs, Prefix, File, Offset, Size,\n+                             [FLU|Ws], Depth, STime, TO, S);\n+        {error, bad_checksum}=BadCS ->\n+            %% TODO: alternate strategy?\n+            {reply, BadCS, S};\n+        {error, Retry}\n+          when Retry == partition; Retry == bad_epoch; Retry == wedged ->\n+            do_trim_midtail(FLUs, Prefix, File, Offset, Size,\n+                            Ws, Depth, STime, TO, S)\n     end.","path":"src/machi_cr_client.erl","position":116,"original_position":116,"commit_id":"272730e67109e0c9996e76cdb0284b43823c14aa","original_commit_id":"272730e67109e0c9996e76cdb0284b43823c14aa","user":{"login":"slfritchie","id":75320,"avatar_url":"https://avatars.githubusercontent.com/u/75320?v=3","gravatar_id":"","url":"https://api.github.com/users/slfritchie","html_url":"https://github.com/slfritchie","followers_url":"https://api.github.com/users/slfritchie/followers","following_url":"https://api.github.com/users/slfritchie/following{/other_user}","gists_url":"https://api.github.com/users/slfritchie/gists{/gist_id}","starred_url":"https://api.github.com/users/slfritchie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/slfritchie/subscriptions","organizations_url":"https://api.github.com/users/slfritchie/orgs","repos_url":"https://api.github.com/users/slfritchie/repos","events_url":"https://api.github.com/users/slfritchie/events{/privacy}","received_events_url":"https://api.github.com/users/slfritchie/received_events","type":"User","site_admin":false},"body":"Similar to the case mentioned in my comment at line 596, it's possible to have a legitimate `{error, trimmed}` response here.  Again, I believe we should continue to the remaining members of the chain (including repairing members).","created_at":"2015-10-16T12:57:57Z","updated_at":"2015-10-16T12:57:57Z","html_url":"https://github.com/basho/machi/pull/14#discussion_r42238874","pull_request_url":"https://api.github.com/repos/basho/machi/pulls/14","_links":{"self":{"href":"https://api.github.com/repos/basho/machi/pulls/comments/42238874"},"html":{"href":"https://github.com/basho/machi/pull/14#discussion_r42238874"},"pull_request":{"href":"https://api.github.com/repos/basho/machi/pulls/14"}}},"pull_request":{"url":"https://api.github.com/repos/basho/machi/pulls/14","id":47882502,"html_url":"https://github.com/basho/machi/pull/14","diff_url":"https://github.com/basho/machi/pull/14.diff","patch_url":"https://github.com/basho/machi/pull/14.patch","issue_url":"https://api.github.com/repos/basho/machi/issues/14","number":14,"state":"open","locked":false,"title":"Add trim commands along with low level PB API","user":{"login":"kuenishi","id":11440,"avatar_url":"https://avatars.githubusercontent.com/u/11440?v=3","gravatar_id":"","url":"https://api.github.com/users/kuenishi","html_url":"https://github.com/kuenishi","followers_url":"https://api.github.com/users/kuenishi/followers","following_url":"https://api.github.com/users/kuenishi/following{/other_user}","gists_url":"https://api.github.com/users/kuenishi/gists{/gist_id}","starred_url":"https://api.github.com/users/kuenishi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kuenishi/subscriptions","organizations_url":"https://api.github.com/users/kuenishi/orgs","repos_url":"https://api.github.com/users/kuenishi/repos","events_url":"https://api.github.com/users/kuenishi/events{/privacy}","received_events_url":"https://api.github.com/users/kuenishi/received_events","type":"User","site_admin":false},"body":"Follows #11 . This pull request includes:\r\n\r\n* Low level PB protocol definitions and their implementations at FLU server\r\n* Introduces a change at \r\n* Actual trim command that leaves a trim mark checksum file\r\n\r\nA `read_chunk()` will return `{error, trimmed}` if that chunk is trimmed. If a arbitrary read request that does not match trim-table, the flu server returns raw data in the file without checking whether it's trimmed or not. But that will be done in the next-next-(^10) pull request.","created_at":"2015-10-16T08:21:40Z","updated_at":"2015-10-16T12:57:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"dc3b95d9614d852e25c5e5dbda236027aa44d3c7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/basho/machi/pulls/14/commits","review_comments_url":"https://api.github.com/repos/basho/machi/pulls/14/comments","review_comment_url":"https://api.github.com/repos/basho/machi/pulls/comments{/number}","comments_url":"https://api.github.com/repos/basho/machi/issues/14/comments","statuses_url":"https://api.github.com/repos/basho/machi/statuses/272730e67109e0c9996e76cdb0284b43823c14aa","head":{"label":"basho:ku/trim-commands","ref":"ku/trim-commands","sha":"272730e67109e0c9996e76cdb0284b43823c14aa","user":{"login":"basho","id":176293,"avatar_url":"https://avatars.githubusercontent.com/u/176293?v=3","gravatar_id":"","url":"https://api.github.com/users/basho","html_url":"https://github.com/basho","followers_url":"https://api.github.com/users/basho/followers","following_url":"https://api.github.com/users/basho/following{/other_user}","gists_url":"https://api.github.com/users/basho/gists{/gist_id}","starred_url":"https://api.github.com/users/basho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/basho/subscriptions","organizations_url":"https://api.github.com/users/basho/orgs","repos_url":"https://api.github.com/users/basho/repos","events_url":"https://api.github.com/users/basho/events{/privacy}","received_events_url":"https://api.github.com/users/basho/received_events","type":"Organization","site_admin":false},"repo":{"id":30953709,"name":"machi","full_name":"basho/machi","owner":{"login":"basho","id":176293,"avatar_url":"https://avatars.githubusercontent.com/u/176293?v=3","gravatar_id":"","url":"https://api.github.com/users/basho","html_url":"https://github.com/basho","followers_url":"https://api.github.com/users/basho/followers","following_url":"https://api.github.com/users/basho/following{/other_user}","gists_url":"https://api.github.com/users/basho/gists{/gist_id}","starred_url":"https://api.github.com/users/basho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/basho/subscriptions","organizations_url":"https://api.github.com/users/basho/orgs","repos_url":"https://api.github.com/users/basho/repos","events_url":"https://api.github.com/users/basho/events{/privacy}","received_events_url":"https://api.github.com/users/basho/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/basho/machi","description":"Machi file store","fork":false,"url":"https://api.github.com/repos/basho/machi","forks_url":"https://api.github.com/repos/basho/machi/forks","keys_url":"https://api.github.com/repos/basho/machi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/basho/machi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/basho/machi/teams","hooks_url":"https://api.github.com/repos/basho/machi/hooks","issue_events_url":"https://api.github.com/repos/basho/machi/issues/events{/number}","events_url":"https://api.github.com/repos/basho/machi/events","assignees_url":"https://api.github.com/repos/basho/machi/assignees{/user}","branches_url":"https://api.github.com/repos/basho/machi/branches{/branch}","tags_url":"https://api.github.com/repos/basho/machi/tags","blobs_url":"https://api.github.com/repos/basho/machi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/basho/machi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/basho/machi/git/refs{/sha}","trees_url":"https://api.github.com/repos/basho/machi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/basho/machi/statuses/{sha}","languages_url":"https://api.github.com/repos/basho/machi/languages","stargazers_url":"https://api.github.com/repos/basho/machi/stargazers","contributors_url":"https://api.github.com/repos/basho/machi/contributors","subscribers_url":"https://api.github.com/repos/basho/machi/subscribers","subscription_url":"https://api.github.com/repos/basho/machi/subscription","commits_url":"https://api.github.com/repos/basho/machi/commits{/sha}","git_commits_url":"https://api.github.com/repos/basho/machi/git/commits{/sha}","comments_url":"https://api.github.com/repos/basho/machi/comments{/number}","issue_comment_url":"https://api.github.com/repos/basho/machi/issues/comments{/number}","contents_url":"https://api.github.com/repos/basho/machi/contents/{+path}","compare_url":"https://api.github.com/repos/basho/machi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/basho/machi/merges","archive_url":"https://api.github.com/repos/basho/machi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/basho/machi/downloads","issues_url":"https://api.github.com/repos/basho/machi/issues{/number}","pulls_url":"https://api.github.com/repos/basho/machi/pulls{/number}","milestones_url":"https://api.github.com/repos/basho/machi/milestones{/number}","notifications_url":"https://api.github.com/repos/basho/machi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/basho/machi/labels{/name}","releases_url":"https://api.github.com/repos/basho/machi/releases{/id}","created_at":"2015-02-18T05:40:05Z","updated_at":"2015-10-15T01:25:30Z","pushed_at":"2015-10-16T09:42:13Z","git_url":"git://github.com/basho/machi.git","ssh_url":"git@github.com:basho/machi.git","clone_url":"https://github.com/basho/machi.git","svn_url":"https://github.com/basho/machi","homepage":null,"size":5253,"stargazers_count":37,"watchers_count":37,"language":"Erlang","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"open_issues_count":3,"forks":1,"open_issues":3,"watchers":37,"default_branch":"master"}},"base":{"label":"basho:master","ref":"master","sha":"29eccd5beed7f3f67a0bff50960cbaa3931f4e6e","user":{"login":"basho","id":176293,"avatar_url":"https://avatars.githubusercontent.com/u/176293?v=3","gravatar_id":"","url":"https://api.github.com/users/basho","html_url":"https://github.com/basho","followers_url":"https://api.github.com/users/basho/followers","following_url":"https://api.github.com/users/basho/following{/other_user}","gists_url":"https://api.github.com/users/basho/gists{/gist_id}","starred_url":"https://api.github.com/users/basho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/basho/subscriptions","organizations_url":"https://api.github.com/users/basho/orgs","repos_url":"https://api.github.com/users/basho/repos","events_url":"https://api.github.com/users/basho/events{/privacy}","received_events_url":"https://api.github.com/users/basho/received_events","type":"Organization","site_admin":false},"repo":{"id":30953709,"name":"machi","full_name":"basho/machi","owner":{"login":"basho","id":176293,"avatar_url":"https://avatars.githubusercontent.com/u/176293?v=3","gravatar_id":"","url":"https://api.github.com/users/basho","html_url":"https://github.com/basho","followers_url":"https://api.github.com/users/basho/followers","following_url":"https://api.github.com/users/basho/following{/other_user}","gists_url":"https://api.github.com/users/basho/gists{/gist_id}","starred_url":"https://api.github.com/users/basho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/basho/subscriptions","organizations_url":"https://api.github.com/users/basho/orgs","repos_url":"https://api.github.com/users/basho/repos","events_url":"https://api.github.com/users/basho/events{/privacy}","received_events_url":"https://api.github.com/users/basho/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/basho/machi","description":"Machi file store","fork":false,"url":"https://api.github.com/repos/basho/machi","forks_url":"https://api.github.com/repos/basho/machi/forks","keys_url":"https://api.github.com/repos/basho/machi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/basho/machi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/basho/machi/teams","hooks_url":"https://api.github.com/repos/basho/machi/hooks","issue_events_url":"https://api.github.com/repos/basho/machi/issues/events{/number}","events_url":"https://api.github.com/repos/basho/machi/events","assignees_url":"https://api.github.com/repos/basho/machi/assignees{/user}","branches_url":"https://api.github.com/repos/basho/machi/branches{/branch}","tags_url":"https://api.github.com/repos/basho/machi/tags","blobs_url":"https://api.github.com/repos/basho/machi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/basho/machi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/basho/machi/git/refs{/sha}","trees_url":"https://api.github.com/repos/basho/machi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/basho/machi/statuses/{sha}","languages_url":"https://api.github.com/repos/basho/machi/languages","stargazers_url":"https://api.github.com/repos/basho/machi/stargazers","contributors_url":"https://api.github.com/repos/basho/machi/contributors","subscribers_url":"https://api.github.com/repos/basho/machi/subscribers","subscription_url":"https://api.github.com/repos/basho/machi/subscription","commits_url":"https://api.github.com/repos/basho/machi/commits{/sha}","git_commits_url":"https://api.github.com/repos/basho/machi/git/commits{/sha}","comments_url":"https://api.github.com/repos/basho/machi/comments{/number}","issue_comment_url":"https://api.github.com/repos/basho/machi/issues/comments{/number}","contents_url":"https://api.github.com/repos/basho/machi/contents/{+path}","compare_url":"https://api.github.com/repos/basho/machi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/basho/machi/merges","archive_url":"https://api.github.com/repos/basho/machi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/basho/machi/downloads","issues_url":"https://api.github.com/repos/basho/machi/issues{/number}","pulls_url":"https://api.github.com/repos/basho/machi/pulls{/number}","milestones_url":"https://api.github.com/repos/basho/machi/milestones{/number}","notifications_url":"https://api.github.com/repos/basho/machi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/basho/machi/labels{/name}","releases_url":"https://api.github.com/repos/basho/machi/releases{/id}","created_at":"2015-02-18T05:40:05Z","updated_at":"2015-10-15T01:25:30Z","pushed_at":"2015-10-16T09:42:13Z","git_url":"git://github.com/basho/machi.git","ssh_url":"git@github.com:basho/machi.git","clone_url":"https://github.com/basho/machi.git","svn_url":"https://github.com/basho/machi","homepage":null,"size":5253,"stargazers_count":37,"watchers_count":37,"language":"Erlang","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"open_issues_count":3,"forks":1,"open_issues":3,"watchers":37,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/basho/machi/pulls/14"},"html":{"href":"https://github.com/basho/machi/pull/14"},"issue":{"href":"https://api.github.com/repos/basho/machi/issues/14"},"comments":{"href":"https://api.github.com/repos/basho/machi/issues/14/comments"},"review_comments":{"href":"https://api.github.com/repos/basho/machi/pulls/14/comments"},"review_comment":{"href":"https://api.github.com/repos/basho/machi/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/basho/machi/pulls/14/commits"},"statuses":{"href":"https://api.github.com/repos/basho/machi/statuses/272730e67109e0c9996e76cdb0284b43823c14aa"}}}}