6
6
7
7
% % API
8
8
-export ([start_link /1 ,
9
- command /3
9
+ command /3 ,
10
+ query /3
10
11
]).
11
12
12
13
% % State functions
37
38
-type pending_reply () :: {reply | notify , {ra_index (), ra_term ()},
38
39
From :: term ()}.
39
40
41
+ -type query_fun () :: fun ((term ()) -> term ()).
42
+
40
43
-export_type ([server_ref / 0 ]).
41
44
42
45
-record (state , {node_state :: ra_node :ra_node_state (),
@@ -64,6 +67,12 @@ command(ServerRef, Data, ReplyMode) ->
64
67
Reply -> {ok , Reply , ServerRef }
65
68
end .
66
69
70
+ - spec query (ra_node_proc :server_ref (), query_fun (), dirty | consensus ) ->
71
+ {ok , IdxTerm :: {ra_index (), ra_term ()}, term ()}.
72
+ query (ServerRef , QueryFun , dirty ) ->
73
+ gen_statem :call (ServerRef , {query , QueryFun , dirty }).
74
+
75
+
67
76
% %%===================================================================
68
77
% %% gen_statem callbacks
69
78
% %%===================================================================
@@ -162,6 +171,9 @@ follower({call, From}, {command, _Data, _Flag},
162
171
follower ({call , From }, {command , _Data , _Flag } = Cmd ,
163
172
State = # state {pending_commands = Pending }) ->
164
173
{keep_state , State # state {pending_commands = [{From , Cmd } | Pending ]}};
174
+ follower ({call , From }, {query , QueryFun , dirty }, State = # state {node_state = NodeState }) ->
175
+ Reply = perform_query (QueryFun , dirty , NodeState ),
176
+ {keep_state , State , [{reply , From , Reply }]};
165
177
follower (EventType , Msg ,
166
178
State0 = # state {node_state = NodeState0 = #{id := Id }}) ->
167
179
? DBG (" ~p follower: ~p~n " , [Id , Msg ]),
@@ -179,7 +191,6 @@ follower(EventType, Msg,
179
191
election_timeout_action (State )}
180
192
end .
181
193
182
-
183
194
handle_event (_EventType , EventContent , StateName , State ) ->
184
195
? DBG (" handle_event unknownn ~p~n " , [EventContent ]),
185
196
{next_state , StateName , State }.
@@ -203,6 +214,11 @@ format_status(_Opt, [_PDict, _StateName, _State]) ->
203
214
% %% Internal functions
204
215
% %%===================================================================
205
216
217
+ perform_query (QueryFun , dirty , #{machine_state := MacState ,
218
+ last_applied := Last ,
219
+ current_term := Term }) ->
220
+ {ok , {Last , Term }, QueryFun (MacState )}.
221
+
206
222
make_caller_reply_actions (State = # state {pending_replies = []}) ->
207
223
{State , [], []};
208
224
make_caller_reply_actions (State = # state {pending_replies = Pending ,
0 commit comments