SNAPKITTYWEST commited on
Commit
7e34e5d
·
verified ·
1 Parent(s): 6aef5ff

Add src/hk_api_search_h.erl

Browse files
Files changed (1) hide show
  1. src/hk_api_search_h.erl +77 -0
src/hk_api_search_h.erl ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ %%%-------------------------------------------------------------------
2
+ %%% @doc `/search' API domain.
3
+ %%%
4
+ %%% POST /api/search start a job (async, returns job_id immediately)
5
+ %%% GET /api/search list jobs (current stage/iteration each)
6
+ %%% GET /api/search/:id describe one job's current stage
7
+ %%% GET /api/search/:id/result final result if `done'; 202 (pending) otherwise
8
+ %%%
9
+ %%% Progress between "started" and "result ready" is observed via
10
+ %%% the `search.*' events on the event stream, per the pipeline's
11
+ %%% event-per-stage requirement -- this handler does not poll or
12
+ %%% block waiting for the pipeline itself.
13
+ %%% @end
14
+ %%%-------------------------------------------------------------------
15
+ -module(hk_api_search_h).
16
+
17
+ -export([init/2]).
18
+
19
+ init(Req0 = #{method := <<"POST">>}, collection) ->
20
+ RequestId = hk_api_util:request_id(Req0),
21
+ {ok, Body, Req1} = hk_api_util:read_json_body(Req0),
22
+ OwnerAgentId = maps:get(<<"owner_agent_id">>, Body, undefined),
23
+ Query = maps:get(<<"query">>, Body, <<>>),
24
+ MaxIterations = maps:get(<<"max_iterations">>, Body, 3),
25
+ Req = hk_api_util:run_operation(search_start, RequestId, fun() ->
26
+ case hk_search:start(OwnerAgentId, Query, #{max_iterations => MaxIterations}) of
27
+ {ok, JobId} -> {ok, {search_job, JobId}, #{job_id => JobId}};
28
+ {error, Reason} -> {error, Reason}
29
+ end
30
+ end, Req1),
31
+ {ok, Req, collection};
32
+
33
+ init(Req0 = #{method := <<"GET">>}, collection) ->
34
+ Jobs = [describe_or_skip(Id) || {Id, _Pid} <- hk_search_registry:list_jobs()],
35
+ Req = hk_api_util:reply_json(200, #{jobs => [M || {true, M} <- Jobs]}, Req0),
36
+ {ok, Req, collection};
37
+
38
+ init(Req0 = #{method := <<"GET">>}, item) ->
39
+ JobId = cowboy_req:binding(id, Req0),
40
+ Req = case hk_search_registry:lookup(JobId) of
41
+ {ok, Pid} ->
42
+ {ok, Job} = hk_search_job:describe(Pid),
43
+ hk_api_util:reply_json(200, hk_schema:to_map(Job), Req0);
44
+ {error, not_found} ->
45
+ hk_api_util:reply_error(404, job_not_found, Req0)
46
+ end,
47
+ {ok, Req, item};
48
+
49
+ init(Req0 = #{method := <<"GET">>}, result) ->
50
+ JobId = cowboy_req:binding(id, Req0),
51
+ Req = case hk_search_registry:lookup(JobId) of
52
+ {ok, Pid} ->
53
+ case hk_search_job:await_result(Pid, 300) of
54
+ {ok, Result} -> hk_api_util:reply_json(200, Result, Req0);
55
+ {error, pending} -> hk_api_util:reply_json(202, #{status => pending}, Req0);
56
+ {error, Reason} -> hk_api_util:reply_error(422, Reason, Req0)
57
+ end;
58
+ {error, not_found} ->
59
+ hk_api_util:reply_error(404, job_not_found, Req0)
60
+ end,
61
+ {ok, Req, result};
62
+
63
+ init(Req0, State) ->
64
+ Req = hk_api_util:reply_error(405, method_not_allowed, Req0),
65
+ {ok, Req, State}.
66
+
67
+ %%% internal
68
+
69
+ describe_or_skip(JobId) ->
70
+ case hk_search_registry:lookup(JobId) of
71
+ {ok, Pid} ->
72
+ case catch hk_search_job:describe(Pid) of
73
+ {ok, Job} -> {true, hk_schema:to_map(Job)};
74
+ _ -> false
75
+ end;
76
+ _ -> false
77
+ end.