@@ -26,6 +26,7 @@ import (
26
26
27
27
"github.com/gorilla/handlers"
28
28
"github.com/opentracing/opentracing-go"
29
+ "github.com/soheilhy/cmux"
29
30
"github.com/spf13/cobra"
30
31
"github.com/spf13/viper"
31
32
jaegerClientConfig "github.com/uber/jaeger-client-go/config"
@@ -144,43 +145,53 @@ func main() {
144
145
r .Handle (mBldr .HTTPRoute , h )
145
146
}
146
147
147
- portStr := ":" + strconv .Itoa (queryOpts .Port )
148
148
compressHandler := handlers .CompressHandler (r )
149
149
recoveryHandler := recoveryhandler .NewRecoveryHandler (logger , true )
150
150
151
+ // Create HTTP Server
152
+ httpServer := & http.Server {
153
+ Handler : recoveryHandler (compressHandler ),
154
+ }
155
+
151
156
// Create GRPC Server.
152
157
grpcServer := grpc .NewServer ()
153
158
154
- // Add logging.
155
159
grpclog .SetLoggerV2 (grpclog .NewLoggerV2 (ioutil .Discard , os .Stderr , os .Stderr ))
156
160
157
- // Register GRPC Handler.
158
- spanReaderGRPC , err := storageFactory .CreateSpanReader ()
159
- if err != nil {
160
- logger .Fatal ("Failed to create span reader" , zap .Error (err ))
161
- }
162
- spanReaderGRPC = storageMetrics .NewReadMetricsDecorator (spanReaderGRPC , baseFactory .Namespace (metrics.NSOptions {Name : "query-grpc" , Tags : nil }))
163
- dependencyReaderGRPC , err := storageFactory .CreateDependencyReader ()
161
+ grpcHandler := app .NewGRPCHandler (queryService , logger , tracer )
162
+ api_v2 .RegisterQueryServiceHandler (grpcServer , grpcHandler )
163
+
164
+ // Prepare cmux conn.
165
+ conn , err := net .Listen ("tcp" , fmt .Sprintf (":%d" , queryOpts .Port ))
164
166
if err != nil {
165
- logger .Fatal ("Failed to create dependency reader " , zap .Error (err ))
167
+ logger .Fatal ("Could not start listener " , zap .Error (err ))
166
168
}
167
169
168
- grpcHandler := NewGRPCHandler (spanReaderGRPC , dependencyReaderGRPC , apiHandlerOptions )
169
- api_v2 .RegisterQueryServiceHandler (grpcServer , grpcHandler )
170
+ // Create cmux server.
171
+ // cmux will reverse-proxy between HTTP and GRPC backends.
172
+ s := cmux .New (conn )
173
+
174
+ // Add GRPC and HTTP listeners.
175
+ grpcL := s .Match (
176
+ cmux .HTTP2HeaderField ("content-type" , "application/grpc" ),
177
+ cmux .HTTP2HeaderField ("content-type" , "application/grpc+proto" ))
178
+ httpL := s .Match (cmux .Any ())
170
179
171
180
go func () {
172
- logger .Info ("Starting HTTP+GRPC server" , zap .Int ("port" , queryOpts .Port ))
173
- conn , err := net .Listen ("tcp" , fmt .Sprintf (":%d" , queryOpts .Port ))
174
- if err != nil {
175
- logger .Fatal ("Could not launch service" , zap .Error (err ))
176
- }
177
-
178
- // Multiplexed server.
179
- // Use CombinedHandler here, which will "reverse-proxy" between HTTP and GRPC backends.
180
- srv .Serve (conn , NewCombinedHandler (grpcServer , recoveryHandler (compressHandler )))
181
+ logger .Info ("Starting HTTP server" , zap .Int ("port" , queryOpts .Port ))
182
+ httpServer .Serve (httpL )
181
183
hc .Set (healthcheck .Unavailable )
182
184
}()
183
185
186
+ go func () {
187
+ logger .Info ("Starting GRPC server" , zap .Int ("port" , queryOpts .Port ))
188
+ grpcServer .Serve (grpcL )
189
+ hc .Set (healthcheck .Unavailable )
190
+ }()
191
+
192
+ // Start cmux server.
193
+ s .Serve ()
194
+
184
195
hc .Ready ()
185
196
<- serverChannel
186
197
logger .Info ("Shutdown complete" )
0 commit comments