blob: 12d0c936348b42b3264a90c2eeaa92e861653d6f [file] [log] [blame]
Jan Tattermuscha7fff862015-02-13 11:08:08 -08001#region Copyright notice and license
2
Jan Tattermuschaf77b3d2015-02-13 11:22:21 -08003// Copyright 2015, Google Inc.
Jan Tattermuscha7fff862015-02-13 11:08:08 -08004// 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
Jan Tattermusch8ce5e8b2015-02-05 10:56:49 -080034using System;
35using Google.GRPC.Core.Internal;
36
37namespace Google.GRPC.Core
38{
39 internal interface IServerCallHandler
40 {
41 void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq);
42 }
43
44 internal class UnaryRequestServerCallHandler<TRequest, TResponse> : IServerCallHandler
45 {
46 readonly Method<TRequest, TResponse> method;
47 readonly UnaryRequestServerMethod<TRequest, TResponse> handler;
48
49 public UnaryRequestServerCallHandler(Method<TRequest, TResponse> method, UnaryRequestServerMethod<TRequest, TResponse> handler)
50 {
51 this.method = method;
52 this.handler = handler;
53 }
54
55 public void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq)
56 {
57 var asyncCall = new AsyncCall<TResponse, TRequest>(
Jan Tattermusch15111f52015-02-05 18:15:14 -080058 method.ResponseMarshaller.Serializer,
59 method.RequestMarshaller.Deserializer);
Jan Tattermusch8ce5e8b2015-02-05 10:56:49 -080060
61 asyncCall.InitializeServer(call);
62 asyncCall.Accept(cq);
63
64 var request = asyncCall.ReadAsync().Result;
65
66 var responseObserver = new ServerWritingObserver<TResponse, TRequest>(asyncCall);
67 handler(request, responseObserver);
68
69 asyncCall.Halfclosed.Wait();
Jan Tattermusch8ce5e8b2015-02-05 10:56:49 -080070 asyncCall.Finished.Wait();
71 }
72 }
73
74 internal class StreamingRequestServerCallHandler<TRequest, TResponse> : IServerCallHandler
75 {
76 readonly Method<TRequest, TResponse> method;
77 readonly StreamingRequestServerMethod<TRequest, TResponse> handler;
78
79 public StreamingRequestServerCallHandler(Method<TRequest, TResponse> method, StreamingRequestServerMethod<TRequest, TResponse> handler)
80 {
81 this.method = method;
82 this.handler = handler;
83 }
84
85 public void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq)
86 {
87 var asyncCall = new AsyncCall<TResponse, TRequest>(
Jan Tattermusch15111f52015-02-05 18:15:14 -080088 method.ResponseMarshaller.Serializer,
89 method.RequestMarshaller.Deserializer);
Jan Tattermusch8ce5e8b2015-02-05 10:56:49 -080090
91 asyncCall.InitializeServer(call);
92 asyncCall.Accept(cq);
93
94 var responseObserver = new ServerWritingObserver<TResponse, TRequest>(asyncCall);
95 var requestObserver = handler(responseObserver);
96
97 // feed the requests
98 asyncCall.StartReadingToStream(requestObserver);
99
100 asyncCall.Halfclosed.Wait();
Jan Tattermusch8ce5e8b2015-02-05 10:56:49 -0800101 asyncCall.Finished.Wait();
102 }
103 }
104
105 internal class NoSuchMethodCallHandler : IServerCallHandler
106 {
107 public void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq)
108 {
109 // We don't care about the payload type here.
110 AsyncCall<byte[], byte[]> asyncCall = new AsyncCall<byte[], byte[]>(
111 (payload) => payload, (payload) => payload);
112
113 asyncCall.InitializeServer(call);
114 asyncCall.Accept(cq);
115 asyncCall.WriteStatusAsync(new Status(StatusCode.GRPC_STATUS_UNIMPLEMENTED, "No such method.")).Wait();
116
117 asyncCall.Finished.Wait();
118 }
119 }
120}
121