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

Side by Side Diff: third_party/grpc/src/csharp/Grpc.Core/Server.cs

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 #region Copyright notice and license
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 #endregion
33
34 using System;
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Diagnostics;
38 using System.Runtime.InteropServices;
39 using System.Threading.Tasks;
40 using Grpc.Core.Internal;
41 using Grpc.Core.Logging;
42 using Grpc.Core.Utils;
43
44 namespace Grpc.Core
45 {
46 /// <summary>
47 /// gRPC server. A single server can server arbitrary number of services and can listen on more than one ports.
48 /// </summary>
49 public class Server
50 {
51 static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<Server>( );
52
53 readonly AtomicCounter activeCallCounter = new AtomicCounter();
54
55 readonly ServiceDefinitionCollection serviceDefinitions;
56 readonly ServerPortCollection ports;
57 readonly GrpcEnvironment environment;
58 readonly List<ChannelOption> options;
59 readonly ServerSafeHandle handle;
60 readonly object myLock = new object();
61
62 readonly List<ServerServiceDefinition> serviceDefinitionsList = new List <ServerServiceDefinition>();
63 readonly List<ServerPort> serverPortList = new List<ServerPort>();
64 readonly Dictionary<string, IServerCallHandler> callHandlers = new Dicti onary<string, IServerCallHandler>();
65 readonly TaskCompletionSource<object> shutdownTcs = new TaskCompletionSo urce<object>();
66
67 bool startRequested;
68 bool shutdownRequested;
69
70 /// <summary>
71 /// Create a new server.
72 /// </summary>
73 /// <param name="options">Channel options.</param>
74 public Server(IEnumerable<ChannelOption> options = null)
75 {
76 this.serviceDefinitions = new ServiceDefinitionCollection(this);
77 this.ports = new ServerPortCollection(this);
78 this.environment = GrpcEnvironment.AddRef();
79 this.options = options != null ? new List<ChannelOption>(options) : new List<ChannelOption>();
80 using (var channelArgs = ChannelOptions.CreateChannelArgs(this.optio ns))
81 {
82 this.handle = ServerSafeHandle.NewServer(environment.CompletionQ ueue, channelArgs);
83 }
84 }
85
86 /// <summary>
87 /// Services that will be exported by the server once started. Register a service with this
88 /// server by adding its definition to this collection.
89 /// </summary>
90 public ServiceDefinitionCollection Services
91 {
92 get
93 {
94 return serviceDefinitions;
95 }
96 }
97
98 /// <summary>
99 /// Ports on which the server will listen once started. Register a port with this
100 /// server by adding its definition to this collection.
101 /// </summary>
102 public ServerPortCollection Ports
103 {
104 get
105 {
106 return ports;
107 }
108 }
109
110 /// <summary>
111 /// To allow awaiting termination of the server.
112 /// </summary>
113 public Task ShutdownTask
114 {
115 get
116 {
117 return shutdownTcs.Task;
118 }
119 }
120
121 /// <summary>
122 /// Starts the server.
123 /// </summary>
124 public void Start()
125 {
126 lock (myLock)
127 {
128 GrpcPreconditions.CheckState(!startRequested);
129 startRequested = true;
130
131 handle.Start();
132 AllowOneRpc();
133 }
134 }
135
136 /// <summary>
137 /// Requests server shutdown and when there are no more calls being serv iced,
138 /// cleans up used resources. The returned task finishes when shutdown p rocedure
139 /// is complete.
140 /// </summary>
141 public async Task ShutdownAsync()
142 {
143 lock (myLock)
144 {
145 GrpcPreconditions.CheckState(startRequested);
146 GrpcPreconditions.CheckState(!shutdownRequested);
147 shutdownRequested = true;
148 }
149
150 handle.ShutdownAndNotify(HandleServerShutdown, environment);
151 await shutdownTcs.Task.ConfigureAwait(false);
152 DisposeHandle();
153
154 await Task.Run(() => GrpcEnvironment.Release()).ConfigureAwait(false );
155 }
156
157 /// <summary>
158 /// Requests server shutdown while cancelling all the in-progress calls.
159 /// The returned task finishes when shutdown procedure is complete.
160 /// </summary>
161 public async Task KillAsync()
162 {
163 lock (myLock)
164 {
165 GrpcPreconditions.CheckState(startRequested);
166 GrpcPreconditions.CheckState(!shutdownRequested);
167 shutdownRequested = true;
168 }
169
170 handle.ShutdownAndNotify(HandleServerShutdown, environment);
171 handle.CancelAllCalls();
172 await shutdownTcs.Task.ConfigureAwait(false);
173 DisposeHandle();
174
175 await Task.Run(() => GrpcEnvironment.Release()).ConfigureAwait(false );
176 }
177
178 internal void AddCallReference(object call)
179 {
180 activeCallCounter.Increment();
181
182 bool success = false;
183 handle.DangerousAddRef(ref success);
184 GrpcPreconditions.CheckState(success);
185 }
186
187 internal void RemoveCallReference(object call)
188 {
189 handle.DangerousRelease();
190 activeCallCounter.Decrement();
191 }
192
193 /// <summary>
194 /// Adds a service definition.
195 /// </summary>
196 private void AddServiceDefinitionInternal(ServerServiceDefinition servic eDefinition)
197 {
198 lock (myLock)
199 {
200 GrpcPreconditions.CheckState(!startRequested);
201 foreach (var entry in serviceDefinition.CallHandlers)
202 {
203 callHandlers.Add(entry.Key, entry.Value);
204 }
205 serviceDefinitionsList.Add(serviceDefinition);
206 }
207 }
208
209 /// <summary>
210 /// Adds a listening port.
211 /// </summary>
212 private int AddPortInternal(ServerPort serverPort)
213 {
214 lock (myLock)
215 {
216 GrpcPreconditions.CheckNotNull(serverPort.Credentials, "serverPo rt");
217 GrpcPreconditions.CheckState(!startRequested);
218 var address = string.Format("{0}:{1}", serverPort.Host, serverPo rt.Port);
219 int boundPort;
220 using (var nativeCredentials = serverPort.Credentials.ToNativeCr edentials())
221 {
222 if (nativeCredentials != null)
223 {
224 boundPort = handle.AddSecurePort(address, nativeCredenti als);
225 }
226 else
227 {
228 boundPort = handle.AddInsecurePort(address);
229 }
230 }
231 var newServerPort = new ServerPort(serverPort, boundPort);
232 this.serverPortList.Add(newServerPort);
233 return boundPort;
234 }
235 }
236
237 /// <summary>
238 /// Allows one new RPC call to be received by server.
239 /// </summary>
240 private void AllowOneRpc()
241 {
242 lock (myLock)
243 {
244 if (!shutdownRequested)
245 {
246 handle.RequestCall(HandleNewServerRpc, environment);
247 }
248 }
249 }
250
251 private void DisposeHandle()
252 {
253 var activeCallCount = activeCallCounter.Count;
254 if (activeCallCount > 0)
255 {
256 Logger.Warning("Server shutdown has finished but there are still {0} active calls for that server.", activeCallCount);
257 }
258 handle.Dispose();
259 }
260
261 /// <summary>
262 /// Selects corresponding handler for given call and handles the call.
263 /// </summary>
264 private async Task HandleCallAsync(ServerRpcNew newRpc)
265 {
266 try
267 {
268 IServerCallHandler callHandler;
269 if (!callHandlers.TryGetValue(newRpc.Method, out callHandler))
270 {
271 callHandler = NoSuchMethodCallHandler.Instance;
272 }
273 await callHandler.HandleCall(newRpc, environment).ConfigureAwait (false);
274 }
275 catch (Exception e)
276 {
277 Logger.Warning(e, "Exception while handling RPC.");
278 }
279 }
280
281 /// <summary>
282 /// Handles the native callback.
283 /// </summary>
284 private void HandleNewServerRpc(bool success, BatchContextSafeHandle ctx )
285 {
286 if (success)
287 {
288 ServerRpcNew newRpc = ctx.GetServerRpcNew(this);
289
290 // after server shutdown, the callback returns with null call
291 if (!newRpc.Call.IsInvalid)
292 {
293 Task.Run(async () => await HandleCallAsync(newRpc)).Configur eAwait(false);
294 }
295 }
296
297 AllowOneRpc();
298 }
299
300 /// <summary>
301 /// Handles native callback.
302 /// </summary>
303 private void HandleServerShutdown(bool success, BatchContextSafeHandle c tx)
304 {
305 shutdownTcs.SetResult(null);
306 }
307
308 /// <summary>
309 /// Collection of service definitions.
310 /// </summary>
311 public class ServiceDefinitionCollection : IEnumerable<ServerServiceDefi nition>
312 {
313 readonly Server server;
314
315 internal ServiceDefinitionCollection(Server server)
316 {
317 this.server = server;
318 }
319
320 /// <summary>
321 /// Adds a service definition to the server. This is how you registe r
322 /// handlers for a service with the server. Only call this before St art().
323 /// </summary>
324 public void Add(ServerServiceDefinition serviceDefinition)
325 {
326 server.AddServiceDefinitionInternal(serviceDefinition);
327 }
328
329 /// <summary>
330 /// Gets enumerator for this collection.
331 /// </summary>
332 public IEnumerator<ServerServiceDefinition> GetEnumerator()
333 {
334 return server.serviceDefinitionsList.GetEnumerator();
335 }
336
337 IEnumerator IEnumerable.GetEnumerator()
338 {
339 return server.serviceDefinitionsList.GetEnumerator();
340 }
341 }
342
343 /// <summary>
344 /// Collection of server ports.
345 /// </summary>
346 public class ServerPortCollection : IEnumerable<ServerPort>
347 {
348 readonly Server server;
349
350 internal ServerPortCollection(Server server)
351 {
352 this.server = server;
353 }
354
355 /// <summary>
356 /// Adds a new port on which server should listen.
357 /// Only call this before Start().
358 /// <returns>The port on which server will be listening.</returns>
359 /// </summary>
360 public int Add(ServerPort serverPort)
361 {
362 return server.AddPortInternal(serverPort);
363 }
364
365 /// <summary>
366 /// Adds a new port on which server should listen.
367 /// <returns>The port on which server will be listening.</returns>
368 /// </summary>
369 /// <param name="host">the host</param>
370 /// <param name="port">the port. If zero, an unused port is chosen a utomatically.</param>
371 /// <param name="credentials">credentials to use to secure this port .</param>
372 public int Add(string host, int port, ServerCredentials credentials)
373 {
374 return Add(new ServerPort(host, port, credentials));
375 }
376
377 /// <summary>
378 /// Gets enumerator for this collection.
379 /// </summary>
380 public IEnumerator<ServerPort> GetEnumerator()
381 {
382 return server.serverPortList.GetEnumerator();
383 }
384
385 IEnumerator IEnumerable.GetEnumerator()
386 {
387 return server.serverPortList.GetEnumerator();
388 }
389 }
390 }
391 }
OLDNEW
« no previous file with comments | « third_party/grpc/src/csharp/Grpc.Core/RpcException.cs ('k') | third_party/grpc/src/csharp/Grpc.Core/ServerCallContext.cs » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698