forked from Bluehouse-Technology/grpc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathroute_guide_server_1.erl
116 lines (97 loc) · 4.03 KB
/
route_guide_server_1.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
-module(route_guide_server_1).
%% The initial version of this file was generated by grpc.
%% A simple implementation of the services has been added to the
%% generated skeleton functions.
-export([server_name/0,
decoder/0,
'GetFeature'/3,
'ListFeatures'/3,
'RecordRoute'/3,
'RouteChat'/3]).
-type 'RouteSummary'() ::
#{point_count => integer(),
feature_count => integer(),
distance => integer(),
elapsed_time => integer()}.
-type 'Point'() ::
#{latitude => integer(),
longitude => integer()}.
-type 'Rectangle'() ::
#{lo => 'Point'(),
hi => 'Point'()}.
-type 'RouteNote'() ::
#{location => 'Point'(),
message => string()}.
-type 'Feature'() ::
#{name => string(),
location => 'Point'()}.
-spec server_name() -> atom().
%% The name of the Cowboy server that will be started.
server_name() -> route_guide.
-spec decoder() -> module().
%% The module (generated by gpb) used to encode and decode protobuf
%% messages.
decoder() -> route_guide.
%% RPCs for service 'RouteGuide'
-spec 'GetFeature'(Message::'Point'(), Stream::grpc:stream(), State::any()) ->
{'Feature'(), grpc:stream()}.
%% This is a unary RPC
'GetFeature'(Message, Stream, _State) ->
Feature = #{name => find_point(Message, data()),
location => Message},
{Feature, Stream}.
-spec 'ListFeatures'(Message::'Rectangle'(), Stream::grpc:stream(), State::any()) ->
{['Feature'()], grpc:stream()}.
%% This is a server-to-client streaming RPC
'ListFeatures'(_Message, Stream, _State) ->
Stream2 = grpc:send(Stream,
#{name => "Louvre",
location => #{latitude => 4,
longitude => 5}}),
{[#{name => "Tour Eiffel",
location => #{latitude => 3,
longitude => 5}}], Stream2}.
-spec 'RecordRoute'(Message::'Point'() | eof, Stream::grpc:stream(), State::any()) ->
{continue, e_gprc:stream(), any()} | {'RouteSummary'(), grpc:stream()}.
%% This is a client-to-server streaming RPC. After the client has sent the last message
%% this function will be called a final time with 'eof' as the first argument. This last
%% invocation must return the response message.
'RecordRoute'(FirstPoint, Stream, undefined) ->
%% The fact that State == undefined tells us that this is the
%% first point. Set the starting state, and return 'continue' to
%% indicate that we are not done yet.
{continue, Stream, #{t_start => erlang:system_time(1),
acc => [FirstPoint]}};
'RecordRoute'(eof, Stream, #{t_start := T0, acc := Points}) ->
%% receiving 'eof' tells us that we need to return a result.
{#{elapsed_time => erlang:system_time(1) - T0,
point_count => length(Points),
feature_count => count_features(Points),
distance => distance(Points)}, Stream};
'RecordRoute'(Point, Stream, #{acc := Acc} = State) ->
{continue, Stream, State#{acc => [Point | Acc]}}.
-spec 'RouteChat'(Message::'RouteNote'() | eof, Stream::grpc:stream(), State::any()) ->
{['RouteNote'()], e_gprc:stream(), any()} | {['RouteNote'()], grpc:stream()}.
%% This is a bidirectional streaming RPC. If the client terminates the stream
%% this function will be called a final time with 'eof' as the first argument.
'RouteChat'(In, Stream, undefined) ->
'RouteChat'(In, Stream, []);
'RouteChat'(eof, Stream, _) ->
{[], Stream};
'RouteChat'(#{location := Location} = P, Stream, Data) ->
Messages = proplists:get_all_values(Location, Data),
{Messages, Stream, [{Location, P} | Data]}.
%% Supporting functions
data() ->
DataFile = filename:join([code:lib_dir(grpc, examples),
"route_guide", "server", "route_guide_data.dat"]),
{ok, [Points]} = file:consult(DataFile),
Points.
find_point(_Location, []) ->
"";
find_point(Location, [#{location := Location, name := Name} | _]) ->
Name;
find_point(Location, [_ | T]) ->
find_point(Location, T).
count_features(_) -> 42.
distance(_) -> 42.