@@ -59,7 +59,8 @@ var API = resource.APINamespaceRDKInternal.WithServiceType(SubtypeName)
59
59
// InternalServiceName is used to refer to/depend on this service internally.
60
60
var InternalServiceName = resource .NewName (API , "builtin" )
61
61
62
- type WebService struct {
62
+ // Service is can bind to a socket and will register gRPC handlers.
63
+ type Service struct {
63
64
resource.Named
64
65
65
66
mu sync.Mutex
@@ -81,8 +82,8 @@ type WebService struct {
81
82
counter * RequestCounters
82
83
}
83
84
84
- // A Service controls the web server for a robot.
85
- type Service interface {
85
+ // A ServiceI controls the web server for a robot.
86
+ type ServiceI interface {
86
87
resource.Resource
87
88
88
89
// Start starts the web server
@@ -108,12 +109,13 @@ var internalWebServiceName = resource.NewName(
108
109
"builtin" ,
109
110
)
110
111
111
- func (svc * WebService ) Name () resource.Name {
112
+ // Name returns a resource name object for the web service.
113
+ func (svc * Service ) Name () resource.Name {
112
114
return internalWebServiceName
113
115
}
114
116
115
117
// Start starts the web server, will return an error if server is already up.
116
- func (svc * WebService ) Start (ctx context.Context , o weboptions.Options ) error {
118
+ func (svc * Service ) Start (ctx context.Context , o weboptions.Options ) error {
117
119
svc .mu .Lock ()
118
120
defer svc .mu .Unlock ()
119
121
if svc .isRunning {
@@ -163,21 +165,21 @@ func RunWebWithConfig(ctx context.Context, r robot.LocalRobot, cfg *config.Confi
163
165
}
164
166
165
167
// Address returns the address the service is listening on.
166
- func (svc * WebService ) Address () string {
168
+ func (svc * Service ) Address () string {
167
169
svc .mu .Lock ()
168
170
defer svc .mu .Unlock ()
169
171
return svc .addr
170
172
}
171
173
172
174
// ModuleAddress returns the unix socket path the module server is listening on.
173
- func (svc * WebService ) ModuleAddress () string {
175
+ func (svc * Service ) ModuleAddress () string {
174
176
svc .mu .Lock ()
175
177
defer svc .mu .Unlock ()
176
178
return svc .modAddr
177
179
}
178
180
179
181
// StartModule starts the grpc module server.
180
- func (svc * WebService ) StartModule (ctx context.Context ) error {
182
+ func (svc * Service ) StartModule (ctx context.Context ) error {
181
183
svc .mu .Lock ()
182
184
defer svc .mu .Unlock ()
183
185
if svc .modServer != nil {
@@ -256,7 +258,7 @@ func (svc *WebService) StartModule(ctx context.Context) error {
256
258
return nil
257
259
}
258
260
259
- func (svc * WebService ) refreshResources () error {
261
+ func (svc * Service ) refreshResources () error {
260
262
resources := make (map [resource.Name ]resource.Resource )
261
263
for _ , name := range svc .r .ResourceNames () {
262
264
resource , err := svc .r .ResourceByName (name )
@@ -270,7 +272,7 @@ func (svc *WebService) refreshResources() error {
270
272
271
273
// updateResources gets every existing resource on the robot's resource graph and updates ResourceAPICollection object
272
274
// with the correct resources, include deleting ones which have been removed from the resource graph.
273
- func (svc * WebService ) updateResources (resources map [resource.Name ]resource.Resource ) error {
275
+ func (svc * Service ) updateResources (resources map [resource.Name ]resource.Resource ) error {
274
276
groupedResources := make (map [resource.API ]map [resource.Name ]resource.Resource )
275
277
for n , v := range resources {
276
278
r , ok := groupedResources [n .API ]
@@ -326,13 +328,13 @@ func (svc *WebService) updateResources(resources map[resource.Name]resource.Reso
326
328
}
327
329
328
330
// Stop stops the main web service prior to actually closing (it leaves the module server running.)
329
- func (svc * WebService ) Stop () {
331
+ func (svc * Service ) Stop () {
330
332
svc .mu .Lock ()
331
333
defer svc .mu .Unlock ()
332
334
svc .stopWeb ()
333
335
}
334
336
335
- func (svc * WebService ) stopWeb () {
337
+ func (svc * Service ) stopWeb () {
336
338
if svc .cancelFunc != nil {
337
339
svc .cancelFunc ()
338
340
}
@@ -341,7 +343,7 @@ func (svc *WebService) stopWeb() {
341
343
}
342
344
343
345
// Close closes a webService via calls to its Cancel func.
344
- func (svc * WebService ) Close (ctx context.Context ) error {
346
+ func (svc * Service ) Close (ctx context.Context ) error {
345
347
svc .mu .Lock ()
346
348
defer svc .mu .Unlock ()
347
349
svc .stopWeb ()
@@ -355,7 +357,7 @@ func (svc *WebService) Close(ctx context.Context) error {
355
357
356
358
// runWeb takes the given robot and options and runs the web server. This function will
357
359
// block until the context is done.
358
- func (svc * WebService ) runWeb (ctx context.Context , options weboptions.Options ) (err error ) {
360
+ func (svc * Service ) runWeb (ctx context.Context , options weboptions.Options ) (err error ) {
359
361
if options .Network .BindAddress != "" && options .Network .Listener != nil {
360
362
return errors .New ("may only set one of network bind address or listener" )
361
363
}
@@ -499,16 +501,23 @@ func (svc *WebService) runWeb(ctx context.Context, options weboptions.Options) (
499
501
return err
500
502
}
501
503
502
- // Requests for resources are expected to be a gRPC object that includes a `GetName` method.
504
+ // Namer is used to get a resource name from incoming requests for countingfor request. Requests for
505
+ // resources are expected to be a gRPC object that includes a `GetName` method.
503
506
type Namer interface {
504
507
GetName () string
505
508
}
506
509
510
+ // RequestCounters maps string keys to atomic ints that get bumped on every incoming gRPC request
511
+ // for components.
507
512
type RequestCounters struct {
508
513
counts sync.Map
509
514
}
510
515
511
- func (mc * RequestCounters ) UnaryInterceptor (ctx context.Context , req any , info * googlegrpc.UnaryServerInfo , handler googlegrpc.UnaryHandler ) (resp any , err error ) {
516
+ // UnaryInterceptor returns an incoming server interceptor that will pull method information and
517
+ // optionally resource information to bump the request counters.
518
+ func (mc * RequestCounters ) UnaryInterceptor (
519
+ ctx context.Context , req any , info * googlegrpc.UnaryServerInfo , handler googlegrpc.UnaryHandler ,
520
+ ) (resp any , err error ) {
512
521
// Handle `info.FullMethod` values such as:
513
522
// - `/viam.component.motor.v1.MotorService/IsMoving`
514
523
// - `/viam.robot.v1.RobotService/SendSessionHeartbeat`
@@ -538,6 +547,7 @@ func (mc *RequestCounters) UnaryInterceptor(ctx context.Context, req any, info *
538
547
return handler (ctx , req )
539
548
}
540
549
550
+ // Stats satisfies the ftdc.Statser interface and will return a copy of the counters.
541
551
func (mc * RequestCounters ) Stats () any {
542
552
ret := make (map [string ]int64 )
543
553
mc .counts .Range (func (key , value any ) bool {
@@ -549,7 +559,7 @@ func (mc *RequestCounters) Stats() any {
549
559
}
550
560
551
561
// Initialize RPC Server options.
552
- func (svc * WebService ) initRPCOptions (listenerTCPAddr * net.TCPAddr , options weboptions.Options ) ([]rpc.ServerOption , error ) {
562
+ func (svc * Service ) initRPCOptions (listenerTCPAddr * net.TCPAddr , options weboptions.Options ) ([]rpc.ServerOption , error ) {
553
563
hosts := options .GetHosts (listenerTCPAddr )
554
564
555
565
webrtcOptions := rpc.WebRTCServerOptions {
@@ -639,7 +649,7 @@ func (svc *WebService) initRPCOptions(listenerTCPAddr *net.TCPAddr, options webo
639
649
}
640
650
641
651
// Initialize authentication handler options.
642
- func (svc * WebService ) initAuthHandlers (listenerTCPAddr * net.TCPAddr , options weboptions.Options ) ([]rpc.ServerOption , error ) {
652
+ func (svc * Service ) initAuthHandlers (listenerTCPAddr * net.TCPAddr , options weboptions.Options ) ([]rpc.ServerOption , error ) {
643
653
rpcOpts := []rpc.ServerOption {}
644
654
645
655
if options .Managed && len (options .Auth .Handlers ) == 1 {
@@ -718,7 +728,7 @@ func (svc *WebService) initAuthHandlers(listenerTCPAddr *net.TCPAddr, options we
718
728
}
719
729
720
730
// Register every API resource grpc service here.
721
- func (svc * WebService ) initAPIResourceCollections (ctx context.Context , mod bool ) error {
731
+ func (svc * Service ) initAPIResourceCollections (ctx context.Context , mod bool ) error {
722
732
// TODO (RSDK-144): only register necessary services
723
733
apiRegs := resource .RegisteredAPIs ()
724
734
for s , rs := range apiRegs {
@@ -740,7 +750,7 @@ func (svc *WebService) initAPIResourceCollections(ctx context.Context, mod bool)
740
750
}
741
751
742
752
// Initialize HTTP server.
743
- func (svc * WebService ) initHTTPServer (listenerTCPAddr * net.TCPAddr , options weboptions.Options ) (* http.Server , error ) {
753
+ func (svc * Service ) initHTTPServer (listenerTCPAddr * net.TCPAddr , options weboptions.Options ) (* http.Server , error ) {
744
754
mux := svc .initMux (options )
745
755
746
756
httpServer , err := utils .NewPossiblySecureHTTPServer (mux , utils.HTTPServerOptions {
@@ -757,7 +767,7 @@ func (svc *WebService) initHTTPServer(listenerTCPAddr *net.TCPAddr, options webo
757
767
}
758
768
759
769
// Initialize multiplexer between http handlers.
760
- func (svc * WebService ) initMux (options weboptions.Options ) * goji.Mux {
770
+ func (svc * Service ) initMux (options weboptions.Options ) * goji.Mux {
761
771
mux := goji .NewMux ()
762
772
// Note: used by viam-agent for health checks
763
773
mux .HandleFunc (pat .New ("/" ), func (w http.ResponseWriter , _ * http.Request ) {
@@ -814,7 +824,7 @@ func (svc *WebService) initMux(options weboptions.Options) *goji.Mux {
814
824
// It is invoked instead of returning the "unimplemented" gRPC error whenever a request is received for
815
825
// an unregistered service or method. These method could be registered on a remote viam-server or a module server
816
826
// so this handler will attempt to route the request to the correct next node in the chain.
817
- func (svc * WebService ) foreignServiceHandler (srv interface {}, stream googlegrpc.ServerStream ) error {
827
+ func (svc * Service ) foreignServiceHandler (srv interface {}, stream googlegrpc.ServerStream ) error {
818
828
// method will be in the form of PackageName.ServiceName/MethodName
819
829
method , ok := googlegrpc .MethodFromServerStream (stream )
820
830
if ! ok {
@@ -998,7 +1008,7 @@ type stats struct {
998
1008
}
999
1009
1000
1010
// Stats returns ftdc data on behalf of the rpcServer and other web services.
1001
- func (svc * WebService ) Stats () any {
1011
+ func (svc * Service ) Stats () any {
1002
1012
// RSDK-9369: It's not ideal to block in `Stats`. But we don't today expect this to be
1003
1013
// problematic, and alternatives are more complex/expensive.
1004
1014
svc .mu .Lock ()
@@ -1007,7 +1017,8 @@ func (svc *WebService) Stats() any {
1007
1017
return stats {RPCServer : svc .rpcServer .Stats ()}
1008
1018
}
1009
1019
1010
- func (svc * WebService ) RequestCounters () * RequestCounters {
1020
+ // RequestCounters returns the request counters for this web service.
1021
+ func (svc * Service ) RequestCounters () * RequestCounters {
1011
1022
return svc .counter
1012
1023
}
1013
1024
@@ -1020,7 +1031,7 @@ type RestartStatusResponse struct {
1020
1031
}
1021
1032
1022
1033
// Handles the `/restart_status` endpoint.
1023
- func (svc * WebService ) handleRestartStatus (w http.ResponseWriter , r * http.Request ) {
1034
+ func (svc * Service ) handleRestartStatus (w http.ResponseWriter , r * http.Request ) {
1024
1035
localRobot , isLocal := svc .r .(robot.LocalRobot )
1025
1036
if ! isLocal {
1026
1037
return
0 commit comments