Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: third_party/grpc/examples/cpp/helloworld/greeter_async_server.cc

Issue 1932353002: Initial checkin of gRPC to third_party/ Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright 2015-2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34 #include <memory>
35 #include <iostream>
36 #include <string>
37 #include <thread>
38
39 #include <grpc++/grpc++.h>
40
41 #include "helloworld.grpc.pb.h"
42
43 using grpc::Server;
44 using grpc::ServerAsyncResponseWriter;
45 using grpc::ServerBuilder;
46 using grpc::ServerContext;
47 using grpc::ServerCompletionQueue;
48 using grpc::Status;
49 using helloworld::HelloRequest;
50 using helloworld::HelloReply;
51 using helloworld::Greeter;
52
53 class ServerImpl final {
54 public:
55 ~ServerImpl() {
56 server_->Shutdown();
57 // Always shutdown the completion queue after the server.
58 cq_->Shutdown();
59 }
60
61 // There is no shutdown handling in this code.
62 void Run() {
63 std::string server_address("0.0.0.0:50051");
64
65 ServerBuilder builder;
66 // Listen on the given address without any authentication mechanism.
67 builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
68 // Register "service_" as the instance through which we'll communicate with
69 // clients. In this case it corresponds to an *asynchronous* service.
70 builder.RegisterService(&service_);
71 // Get hold of the completion queue used for the asynchronous communication
72 // with the gRPC runtime.
73 cq_ = builder.AddCompletionQueue();
74 // Finally assemble the server.
75 server_ = builder.BuildAndStart();
76 std::cout << "Server listening on " << server_address << std::endl;
77
78 // Proceed to the server's main loop.
79 HandleRpcs();
80 }
81
82 private:
83 // Class encompasing the state and logic needed to serve a request.
84 class CallData {
85 public:
86 // Take in the "service" instance (in this case representing an asynchronous
87 // server) and the completion queue "cq" used for asynchronous communication
88 // with the gRPC runtime.
89 CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq)
90 : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) {
91 // Invoke the serving logic right away.
92 Proceed();
93 }
94
95 void Proceed() {
96 if (status_ == CREATE) {
97 // Make this instance progress to the PROCESS state.
98 status_ = PROCESS;
99
100 // As part of the initial CREATE state, we *request* that the system
101 // start processing SayHello requests. In this request, "this" acts are
102 // the tag uniquely identifying the request (so that different CallData
103 // instances can serve different requests concurrently), in this case
104 // the memory address of this CallData instance.
105 service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
106 this);
107 } else if (status_ == PROCESS) {
108 // Spawn a new CallData instance to serve new clients while we process
109 // the one for this CallData. The instance will deallocate itself as
110 // part of its FINISH state.
111 new CallData(service_, cq_);
112
113 // The actual processing.
114 std::string prefix("Hello ");
115 reply_.set_message(prefix + request_.name());
116
117 // And we are done! Let the gRPC runtime know we've finished, using the
118 // memory address of this instance as the uniquely identifying tag for
119 // the event.
120 status_ = FINISH;
121 responder_.Finish(reply_, Status::OK, this);
122 } else {
123 GPR_ASSERT(status_ == FINISH);
124 // Once in the FINISH state, deallocate ourselves (CallData).
125 delete this;
126 }
127 }
128
129 private:
130 // The means of communication with the gRPC runtime for an asynchronous
131 // server.
132 Greeter::AsyncService* service_;
133 // The producer-consumer queue where for asynchronous server notifications.
134 ServerCompletionQueue* cq_;
135 // Context for the rpc, allowing to tweak aspects of it such as the use
136 // of compression, authentication, as well as to send metadata back to the
137 // client.
138 ServerContext ctx_;
139
140 // What we get from the client.
141 HelloRequest request_;
142 // What we send back to the client.
143 HelloReply reply_;
144
145 // The means to get back to the client.
146 ServerAsyncResponseWriter<HelloReply> responder_;
147
148 // Let's implement a tiny state machine with the following states.
149 enum CallStatus { CREATE, PROCESS, FINISH };
150 CallStatus status_; // The current serving state.
151 };
152
153 // This can be run in multiple threads if needed.
154 void HandleRpcs() {
155 // Spawn a new CallData instance to serve new clients.
156 new CallData(&service_, cq_.get());
157 void* tag; // uniquely identifies a request.
158 bool ok;
159 while (true) {
160 // Block waiting to read the next event from the completion queue. The
161 // event is uniquely identified by its tag, which in this case is the
162 // memory address of a CallData instance.
163 cq_->Next(&tag, &ok);
164 GPR_ASSERT(ok);
165 static_cast<CallData*>(tag)->Proceed();
166 }
167 }
168
169 std::unique_ptr<ServerCompletionQueue> cq_;
170 Greeter::AsyncService service_;
171 std::unique_ptr<Server> server_;
172 };
173
174 int main(int argc, char** argv) {
175 ServerImpl server;
176 server.Run();
177
178 return 0;
179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698