blob: 3df7e1876d27e8214233fe4242d3700e58d6c638 [file] [log] [blame]
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.
-module(mem3_httpd).
-export([handle_membership_req/1, handle_shards_req/2,
handle_sync_req/2]).
%% includes
-include_lib("mem3/include/mem3.hrl").
-include_lib("couch/include/couch_db.hrl").
handle_membership_req(#httpd{method='GET',
path_parts=[<<"_membership">>]} = Req) ->
ClusterNodes = try mem3:nodes()
catch _:_ -> {ok,[]} end,
couch_httpd:send_json(Req, {[
{all_nodes, lists:sort([node()|nodes()])},
{cluster_nodes, lists:sort(ClusterNodes)}
]});
handle_membership_req(#httpd{path_parts=[<<"_membership">>]}=Req) ->
chttpd:send_method_not_allowed(Req, "GET").
handle_shards_req(#httpd{method='GET',
path_parts=[_DbName, <<"_shards">>]} = Req, Db) ->
DbName = mem3:dbname(couch_db:name(Db)),
Shards = mem3:shards(DbName),
JsonShards = json_shards(Shards, dict:new()),
couch_httpd:send_json(Req, {[
{shards, JsonShards}
]});
handle_shards_req(#httpd{method='GET',
path_parts=[_DbName, <<"_shards">>, DocId]} = Req, Db) ->
DbName = mem3:dbname(couch_db:name(Db)),
Shards = mem3:shards(DbName, DocId),
{[{Shard, Dbs}]} = json_shards(Shards, dict:new()),
couch_httpd:send_json(Req, {[
{range, Shard},
{nodes, Dbs}
]});
handle_shards_req(#httpd{path_parts=[_DbName, <<"_shards">>]}=Req, _Db) ->
chttpd:send_method_not_allowed(Req, "GET");
handle_shards_req(#httpd{path_parts=[_DbName, <<"_shards">>, _DocId]}=Req, _Db) ->
chttpd:send_method_not_allowed(Req, "GET").
handle_sync_req(#httpd{method='POST',
path_parts=[_DbName, <<"_sync_shards">>]} = Req, Db) ->
DbName = mem3:dbname(couch_db:name(Db)),
ShardList = [S#shard.name || S <- mem3:ushards(DbName)],
[ sync_shard(S) || S <- ShardList ],
chttpd:send_json(Req, 202, {[{ok, true}]});
handle_sync_req(Req, _) ->
chttpd:send_method_not_allowed(Req, "POST").
%%
%% internal
%%
json_shards([], AccIn) ->
List = dict:to_list(AccIn),
{lists:sort(List)};
json_shards([#shard{node=Node, range=[B,E]} | Rest], AccIn) ->
HexBeg = couch_util:to_hex(<<B:32/integer>>),
HexEnd = couch_util:to_hex(<<E:32/integer>>),
Range = list_to_binary(HexBeg ++ "-" ++ HexEnd),
json_shards(Rest, dict:append(Range, Node, AccIn)).
sync_shard(ShardName) ->
Shards = mem3_shards:for_shard_range(ShardName),
[rpc:call(S1#shard.node, mem3_sync, push, [S1, S2#shard.node]) ||
S1 <- Shards, S2 <- Shards, S1 =/= S2],
ok.