xref: /aosp_15_r20/external/grpc-grpc/examples/python/multiplex/multiplex_server.py (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker# Copyright 2016 gRPC authors.
2*cc02d7e2SAndroid Build Coastguard Worker#
3*cc02d7e2SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*cc02d7e2SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*cc02d7e2SAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*cc02d7e2SAndroid Build Coastguard Worker#
7*cc02d7e2SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*cc02d7e2SAndroid Build Coastguard Worker#
9*cc02d7e2SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*cc02d7e2SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*cc02d7e2SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*cc02d7e2SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*cc02d7e2SAndroid Build Coastguard Worker# limitations under the License.
14*cc02d7e2SAndroid Build Coastguard Worker"""A gRPC server servicing both Greeter and RouteGuide RPCs."""
15*cc02d7e2SAndroid Build Coastguard Worker
16*cc02d7e2SAndroid Build Coastguard Workerfrom concurrent import futures
17*cc02d7e2SAndroid Build Coastguard Workerimport logging
18*cc02d7e2SAndroid Build Coastguard Workerimport math
19*cc02d7e2SAndroid Build Coastguard Workerimport time
20*cc02d7e2SAndroid Build Coastguard Worker
21*cc02d7e2SAndroid Build Coastguard Workerimport grpc
22*cc02d7e2SAndroid Build Coastguard Workerimport helloworld_pb2
23*cc02d7e2SAndroid Build Coastguard Workerimport helloworld_pb2_grpc
24*cc02d7e2SAndroid Build Coastguard Workerimport route_guide_pb2
25*cc02d7e2SAndroid Build Coastguard Workerimport route_guide_pb2_grpc
26*cc02d7e2SAndroid Build Coastguard Workerimport route_guide_resources
27*cc02d7e2SAndroid Build Coastguard Worker
28*cc02d7e2SAndroid Build Coastguard Worker
29*cc02d7e2SAndroid Build Coastguard Workerdef _get_feature(feature_db, point):
30*cc02d7e2SAndroid Build Coastguard Worker    """Returns Feature at given location or None."""
31*cc02d7e2SAndroid Build Coastguard Worker    for feature in feature_db:
32*cc02d7e2SAndroid Build Coastguard Worker        if feature.location == point:
33*cc02d7e2SAndroid Build Coastguard Worker            return feature
34*cc02d7e2SAndroid Build Coastguard Worker    return None
35*cc02d7e2SAndroid Build Coastguard Worker
36*cc02d7e2SAndroid Build Coastguard Worker
37*cc02d7e2SAndroid Build Coastguard Workerdef _get_distance(start, end):
38*cc02d7e2SAndroid Build Coastguard Worker    """Distance between two points."""
39*cc02d7e2SAndroid Build Coastguard Worker    coord_factor = 10000000.0
40*cc02d7e2SAndroid Build Coastguard Worker    lat_1 = start.latitude / coord_factor
41*cc02d7e2SAndroid Build Coastguard Worker    lat_2 = end.latitude / coord_factor
42*cc02d7e2SAndroid Build Coastguard Worker    lon_1 = start.longitude / coord_factor
43*cc02d7e2SAndroid Build Coastguard Worker    lon_2 = end.longitude / coord_factor
44*cc02d7e2SAndroid Build Coastguard Worker    lat_rad_1 = math.radians(lat_1)
45*cc02d7e2SAndroid Build Coastguard Worker    lat_rad_2 = math.radians(lat_2)
46*cc02d7e2SAndroid Build Coastguard Worker    delta_lat_rad = math.radians(lat_2 - lat_1)
47*cc02d7e2SAndroid Build Coastguard Worker    delta_lon_rad = math.radians(lon_2 - lon_1)
48*cc02d7e2SAndroid Build Coastguard Worker
49*cc02d7e2SAndroid Build Coastguard Worker    a = pow(math.sin(delta_lat_rad / 2), 2) + (
50*cc02d7e2SAndroid Build Coastguard Worker        math.cos(lat_rad_1)
51*cc02d7e2SAndroid Build Coastguard Worker        * math.cos(lat_rad_2)
52*cc02d7e2SAndroid Build Coastguard Worker        * pow(math.sin(delta_lon_rad / 2), 2)
53*cc02d7e2SAndroid Build Coastguard Worker    )
54*cc02d7e2SAndroid Build Coastguard Worker    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
55*cc02d7e2SAndroid Build Coastguard Worker    R = 6371000
56*cc02d7e2SAndroid Build Coastguard Worker    # metres
57*cc02d7e2SAndroid Build Coastguard Worker    return R * c
58*cc02d7e2SAndroid Build Coastguard Worker
59*cc02d7e2SAndroid Build Coastguard Worker
60*cc02d7e2SAndroid Build Coastguard Workerclass _GreeterServicer(helloworld_pb2_grpc.GreeterServicer):
61*cc02d7e2SAndroid Build Coastguard Worker    def SayHello(self, request, context):
62*cc02d7e2SAndroid Build Coastguard Worker        return helloworld_pb2.HelloReply(
63*cc02d7e2SAndroid Build Coastguard Worker            message="Hello, {}!".format(request.name)
64*cc02d7e2SAndroid Build Coastguard Worker        )
65*cc02d7e2SAndroid Build Coastguard Worker
66*cc02d7e2SAndroid Build Coastguard Worker
67*cc02d7e2SAndroid Build Coastguard Workerclass _RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
68*cc02d7e2SAndroid Build Coastguard Worker    """Provides methods that implement functionality of route guide server."""
69*cc02d7e2SAndroid Build Coastguard Worker
70*cc02d7e2SAndroid Build Coastguard Worker    def __init__(self):
71*cc02d7e2SAndroid Build Coastguard Worker        self.db = route_guide_resources.read_route_guide_database()
72*cc02d7e2SAndroid Build Coastguard Worker
73*cc02d7e2SAndroid Build Coastguard Worker    def GetFeature(self, request, context):
74*cc02d7e2SAndroid Build Coastguard Worker        feature = _get_feature(self.db, request)
75*cc02d7e2SAndroid Build Coastguard Worker        if feature is None:
76*cc02d7e2SAndroid Build Coastguard Worker            return route_guide_pb2.Feature(name="", location=request)
77*cc02d7e2SAndroid Build Coastguard Worker        else:
78*cc02d7e2SAndroid Build Coastguard Worker            return feature
79*cc02d7e2SAndroid Build Coastguard Worker
80*cc02d7e2SAndroid Build Coastguard Worker    def ListFeatures(self, request, context):
81*cc02d7e2SAndroid Build Coastguard Worker        left = min(request.lo.longitude, request.hi.longitude)
82*cc02d7e2SAndroid Build Coastguard Worker        right = max(request.lo.longitude, request.hi.longitude)
83*cc02d7e2SAndroid Build Coastguard Worker        top = max(request.lo.latitude, request.hi.latitude)
84*cc02d7e2SAndroid Build Coastguard Worker        bottom = min(request.lo.latitude, request.hi.latitude)
85*cc02d7e2SAndroid Build Coastguard Worker        for feature in self.db:
86*cc02d7e2SAndroid Build Coastguard Worker            if (
87*cc02d7e2SAndroid Build Coastguard Worker                feature.location.longitude >= left
88*cc02d7e2SAndroid Build Coastguard Worker                and feature.location.longitude <= right
89*cc02d7e2SAndroid Build Coastguard Worker                and feature.location.latitude >= bottom
90*cc02d7e2SAndroid Build Coastguard Worker                and feature.location.latitude <= top
91*cc02d7e2SAndroid Build Coastguard Worker            ):
92*cc02d7e2SAndroid Build Coastguard Worker                yield feature
93*cc02d7e2SAndroid Build Coastguard Worker
94*cc02d7e2SAndroid Build Coastguard Worker    def RecordRoute(self, request_iterator, context):
95*cc02d7e2SAndroid Build Coastguard Worker        point_count = 0
96*cc02d7e2SAndroid Build Coastguard Worker        feature_count = 0
97*cc02d7e2SAndroid Build Coastguard Worker        distance = 0.0
98*cc02d7e2SAndroid Build Coastguard Worker        prev_point = None
99*cc02d7e2SAndroid Build Coastguard Worker
100*cc02d7e2SAndroid Build Coastguard Worker        start_time = time.time()
101*cc02d7e2SAndroid Build Coastguard Worker        for point in request_iterator:
102*cc02d7e2SAndroid Build Coastguard Worker            point_count += 1
103*cc02d7e2SAndroid Build Coastguard Worker            if _get_feature(self.db, point):
104*cc02d7e2SAndroid Build Coastguard Worker                feature_count += 1
105*cc02d7e2SAndroid Build Coastguard Worker            if prev_point:
106*cc02d7e2SAndroid Build Coastguard Worker                distance += _get_distance(prev_point, point)
107*cc02d7e2SAndroid Build Coastguard Worker            prev_point = point
108*cc02d7e2SAndroid Build Coastguard Worker
109*cc02d7e2SAndroid Build Coastguard Worker        elapsed_time = time.time() - start_time
110*cc02d7e2SAndroid Build Coastguard Worker        return route_guide_pb2.RouteSummary(
111*cc02d7e2SAndroid Build Coastguard Worker            point_count=point_count,
112*cc02d7e2SAndroid Build Coastguard Worker            feature_count=feature_count,
113*cc02d7e2SAndroid Build Coastguard Worker            distance=int(distance),
114*cc02d7e2SAndroid Build Coastguard Worker            elapsed_time=int(elapsed_time),
115*cc02d7e2SAndroid Build Coastguard Worker        )
116*cc02d7e2SAndroid Build Coastguard Worker
117*cc02d7e2SAndroid Build Coastguard Worker    def RouteChat(self, request_iterator, context):
118*cc02d7e2SAndroid Build Coastguard Worker        prev_notes = []
119*cc02d7e2SAndroid Build Coastguard Worker        for new_note in request_iterator:
120*cc02d7e2SAndroid Build Coastguard Worker            for prev_note in prev_notes:
121*cc02d7e2SAndroid Build Coastguard Worker                if prev_note.location == new_note.location:
122*cc02d7e2SAndroid Build Coastguard Worker                    yield prev_note
123*cc02d7e2SAndroid Build Coastguard Worker            prev_notes.append(new_note)
124*cc02d7e2SAndroid Build Coastguard Worker
125*cc02d7e2SAndroid Build Coastguard Worker
126*cc02d7e2SAndroid Build Coastguard Workerdef serve():
127*cc02d7e2SAndroid Build Coastguard Worker    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
128*cc02d7e2SAndroid Build Coastguard Worker    helloworld_pb2_grpc.add_GreeterServicer_to_server(
129*cc02d7e2SAndroid Build Coastguard Worker        _GreeterServicer(), server
130*cc02d7e2SAndroid Build Coastguard Worker    )
131*cc02d7e2SAndroid Build Coastguard Worker    route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
132*cc02d7e2SAndroid Build Coastguard Worker        _RouteGuideServicer(), server
133*cc02d7e2SAndroid Build Coastguard Worker    )
134*cc02d7e2SAndroid Build Coastguard Worker    server.add_insecure_port("[::]:50051")
135*cc02d7e2SAndroid Build Coastguard Worker    server.start()
136*cc02d7e2SAndroid Build Coastguard Worker    server.wait_for_termination()
137*cc02d7e2SAndroid Build Coastguard Worker
138*cc02d7e2SAndroid Build Coastguard Worker
139*cc02d7e2SAndroid Build Coastguard Workerif __name__ == "__main__":
140*cc02d7e2SAndroid Build Coastguard Worker    logging.basicConfig()
141*cc02d7e2SAndroid Build Coastguard Worker    serve()
142