nickva commented on code in PR #5491:
URL: https://github.com/apache/couchdb/pull/5491#discussion_r2080528815


##########
src/chttpd/src/chttpd_misc.erl:
##########
@@ -219,6 +220,112 @@ handle_task_status_req(#httpd{method = 'GET'} = Req) ->
 handle_task_status_req(Req) ->
     send_method_not_allowed(Req, "GET,HEAD").
 
+handle_resource_status_req(#httpd{method = 'POST'} = Req) ->
+    ok = chttpd:verify_is_server_admin(Req),
+    chttpd:validate_ctype(Req, "application/json"),
+    {Props} = chttpd:json_body_obj(Req),
+    Action = proplists:get_value(<<"action">>, Props),
+    Key = proplists:get_value(<<"key">>, Props),
+    Val = proplists:get_value(<<"val">>, Props),
+
+    CountBy = fun csrt:count_by/1,
+    GroupBy = fun csrt:group_by/2,
+    SortedBy1 = fun csrt:sorted_by/1,
+    SortedBy2 = fun csrt:sorted_by/2,
+    ConvertEle = fun erlang:binary_to_existing_atom/1,
+    ConvertList = fun(L) -> [ConvertEle(E) || E <- L] end,
+    ToJson = fun csrt_util:to_json/1,
+    JsonKeys = fun(PL) -> [[ToJson(K), V] || {K, V} <- PL] end,
+
+    Fun =
+        case {Action, Key, Val} of
+            {<<"count_by">>, Keys, undefined} when is_list(Keys) ->
+                Keys1 = [ConvertEle(K) || K <- Keys],
+                fun() -> CountBy(Keys1) end;
+            {<<"count_by">>, Key, undefined} ->
+                Key1 = ConvertEle(Key),
+                fun() -> CountBy(Key1) end;
+            {<<"group_by">>, Keys, Vals} when is_list(Keys) andalso 
is_list(Vals) ->
+                Keys1 = ConvertList(Keys),
+                Vals1 = ConvertList(Vals),
+                fun() -> GroupBy(Keys1, Vals1) end;
+            {<<"group_by">>, Key, Vals} when is_list(Vals) ->
+                Key1 = ConvertEle(Key),
+                Vals1 = ConvertList(Vals),
+                fun() -> GroupBy(Key1, Vals1) end;
+            {<<"group_by">>, Keys, Val} when is_list(Keys) ->
+                Keys1 = ConvertList(Keys),
+                Val1 = ConvertEle(Val),
+                fun() -> GroupBy(Keys1, Val1) end;
+            {<<"group_by">>, Key, Val} ->
+                Key1 = ConvertEle(Key),
+                Val1 = ConvertList(Val),
+                fun() -> GroupBy(Key1, Val1) end;
+            {<<"sorted_by">>, Key, undefined} ->
+                Key1 = ConvertEle(Key),
+                fun() -> JsonKeys(SortedBy1(Key1)) end;
+            {<<"sorted_by">>, Keys, undefined} when is_list(Keys) ->
+                Keys1 = [ConvertEle(K) || K <- Keys],
+                fun() -> JsonKeys(SortedBy1(Keys1)) end;
+            {<<"sorted_by">>, Keys, Vals} when is_list(Keys) andalso 
is_list(Vals) ->
+                Keys1 = ConvertList(Keys),
+                Vals1 = ConvertList(Vals),
+                fun() -> JsonKeys(SortedBy2(Keys1, Vals1)) end;
+            {<<"sorted_by">>, Key, Vals} when is_list(Vals) ->
+                Key1 = ConvertEle(Key),
+                Vals1 = ConvertList(Vals),
+                fun() -> JsonKeys(SortedBy2(Key1, Vals1)) end;
+            {<<"sorted_by">>, Keys, Val} when is_list(Keys) ->
+                Keys1 = ConvertList(Keys),
+                Val1 = ConvertEle(Val),
+                fun() -> JsonKeys(SortedBy2(Keys1, Val1)) end;
+            {<<"sorted_by">>, Key, Val} ->
+                Key1 = ConvertEle(Key),
+                Val1 = ConvertList(Val),
+                fun() -> JsonKeys(SortedBy2(Key1, Val1)) end;
+            _ ->
+                throw({badrequest, invalid_resource_request})
+        end,
+
+    Fun1 = fun() ->
+        case Fun() of
+            Map when is_map(Map) ->
+                {maps:fold(
+                    fun
+                        %% TODO: Skip 0 value entries?
+                        (_K, 0, A) -> A;
+                        (K, V, A) -> [{ToJson(K), V} | A]
+                    end,
+                    [],
+                    Map
+                )};
+            List when is_list(List) ->
+                List
+        end
+    end,
+
+    {Resp, _Bad} = rpc:multicall(erlang, apply, [
+        fun() ->
+            {node(), Fun1()}
+        end,
+        []
+    ]),

Review Comment:
   Unless absolutely necessary, it's not a good idea to pass function closures 
through the dist protocol. We've done that mistake with attachments in the past 
and had since removed it.
   
   It might be better to create  a utility function, and do an 
`erpc:multicall([node()|nodes()], mod, fun, [Action, Key, Val])`
   
   See how we get active tasks for instance: 
https://github.com/apache/couchdb/blob/c3789e97cebd6a1cb4872cb7d25fd3d7d64fb956/src/chttpd/src/chttpd_util.erl#L174-L188



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to