| OLD | NEW |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package service | 5 package service |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "flag" | 8 "flag" |
| 9 "fmt" | 9 "fmt" |
| 10 "net/http" | 10 "net/http" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 // | 101 // |
| 102 // Since, in production, this is running under an execution harness such
as | 102 // Since, in production, this is running under an execution harness such
as |
| 103 // Kubernetes, the service will restart and load the new configuration.
This | 103 // Kubernetes, the service will restart and load the new configuration.
This |
| 104 // is easier than implementing in-process configuration updating. | 104 // is easier than implementing in-process configuration updating. |
| 105 killCheckInterval clockflag.Duration | 105 killCheckInterval clockflag.Duration |
| 106 // testConfigFilePath is the path to a local configuration service files
ystem | 106 // testConfigFilePath is the path to a local configuration service files
ystem |
| 107 // (impl/filesystem) root. This is used for testing. | 107 // (impl/filesystem) root. This is used for testing. |
| 108 testConfigFilePath string | 108 testConfigFilePath string |
| 109 // serviceConfig is the cached service configuration. | 109 // serviceConfig is the cached service configuration. |
| 110 serviceConfig svcconfig.Config | 110 serviceConfig svcconfig.Config |
| 111 configCache config.MessageCache |
| 111 | 112 |
| 112 // serviceID is the cloud project ID, which is also this service's uniqu
e | 113 // serviceID is the cloud project ID, which is also this service's uniqu
e |
| 113 // ID. This can be specified by flag or, if on GCE, will automatically b
e | 114 // ID. This can be specified by flag or, if on GCE, will automatically b
e |
| 114 // probed from metadata. | 115 // probed from metadata. |
| 115 serviceID string | 116 serviceID string |
| 116 | 117 |
| 117 coord logdog.ServicesClient | 118 coord logdog.ServicesClient |
| 118 } | 119 } |
| 119 | 120 |
| 120 // Run performs service-wide initialization and invokes the specified run | 121 // Run performs service-wide initialization and invokes the specified run |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 if s.coordinatorInsecure { | 325 if s.coordinatorInsecure { |
| 325 prpcClient.Options.Insecure = true | 326 prpcClient.Options.Insecure = true |
| 326 } | 327 } |
| 327 sc := logdog.NewServicesPRPCClient(&prpcClient) | 328 sc := logdog.NewServicesPRPCClient(&prpcClient) |
| 328 | 329 |
| 329 // Wrap the resulting client in a retry harness. | 330 // Wrap the resulting client in a retry harness. |
| 330 return retryServicesClient.New(sc, nil), nil | 331 return retryServicesClient.New(sc, nil), nil |
| 331 } | 332 } |
| 332 | 333 |
| 333 func (s *Service) initConfig(c *context.Context) error { | 334 func (s *Service) initConfig(c *context.Context) error { |
| 334 » opts := config.CacheOptions{ | 335 » // Set up our in-memory config object cache. |
| 335 » » CacheExpiration: projectConfigCacheDuration, | 336 » s.configCache.Lifetime = projectConfigCacheDuration |
| 336 » } | |
| 337 | 337 |
| 338 // If a testConfigFilePath was specified, use a mock configuration servi
ce | 338 // If a testConfigFilePath was specified, use a mock configuration servi
ce |
| 339 // that loads from a local file. | 339 // that loads from a local file. |
| 340 var p client.Provider | 340 var p client.Provider |
| 341 if s.testConfigFilePath == "" { | 341 if s.testConfigFilePath == "" { |
| 342 ccfg, err := s.coord.GetConfig(*c, &google.Empty{}) | 342 ccfg, err := s.coord.GetConfig(*c, &google.Empty{}) |
| 343 if err != nil { | 343 if err != nil { |
| 344 return err | 344 return err |
| 345 } | 345 } |
| 346 | 346 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 373 } else { | 373 } else { |
| 374 // Test / Local: use filesystem config path. | 374 // Test / Local: use filesystem config path. |
| 375 ci, err := filesystem.New(s.testConfigFilePath) | 375 ci, err := filesystem.New(s.testConfigFilePath) |
| 376 if err != nil { | 376 if err != nil { |
| 377 return err | 377 return err |
| 378 } | 378 } |
| 379 p = &testconfig.Provider{Base: ci} | 379 p = &testconfig.Provider{Base: ci} |
| 380 } | 380 } |
| 381 | 381 |
| 382 // Add config caching layers. | 382 // Add config caching layers. |
| 383 opts := config.CacheOptions{ |
| 384 CacheExpiration: projectConfigCacheDuration, |
| 385 } |
| 383 *c = opts.WrapBackend(*c, &client.Backend{ | 386 *c = opts.WrapBackend(*c, &client.Backend{ |
| 384 Provider: p, | 387 Provider: p, |
| 385 }) | 388 }) |
| 386 | 389 |
| 387 // Load our service configuration. | 390 // Load our service configuration. |
| 388 var meta cfgclient.Meta | 391 var meta cfgclient.Meta |
| 389 cset, path := s.ServiceConfigPath() | 392 cset, path := s.ServiceConfigPath() |
| 390 if err := cfgclient.Get(*c, cfgclient.AsService, cset, path, textproto.M
essage(&s.serviceConfig), &meta); err != nil { | 393 if err := cfgclient.Get(*c, cfgclient.AsService, cset, path, textproto.M
essage(&s.serviceConfig), &meta); err != nil { |
| 391 return errors.Annotate(err).Reason("failed to load service confi
g").Err() | 394 return errors.Annotate(err).Reason("failed to load service confi
g").Err() |
| 392 } | 395 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 // project configuration for proj. | 428 // project configuration for proj. |
| 426 func (s *Service) ProjectConfigPath(proj cfgtypes.ProjectName) (cfgtypes.ConfigS
et, string) { | 429 func (s *Service) ProjectConfigPath(proj cfgtypes.ProjectName) (cfgtypes.ConfigS
et, string) { |
| 427 return cfgtypes.ProjectConfigSet(proj), svcconfig.ProjectConfigPath(s.se
rviceID) | 430 return cfgtypes.ProjectConfigSet(proj), svcconfig.ProjectConfigPath(s.se
rviceID) |
| 428 } | 431 } |
| 429 | 432 |
| 430 // ProjectConfig returns the current service's project configuration for proj. | 433 // ProjectConfig returns the current service's project configuration for proj. |
| 431 func (s *Service) ProjectConfig(c context.Context, proj cfgtypes.ProjectName) (*
svcconfig.ProjectConfig, error) { | 434 func (s *Service) ProjectConfig(c context.Context, proj cfgtypes.ProjectName) (*
svcconfig.ProjectConfig, error) { |
| 432 cset, path := s.ProjectConfigPath(proj) | 435 cset, path := s.ProjectConfigPath(proj) |
| 433 | 436 |
| 434 var pcfg svcconfig.ProjectConfig | 437 var pcfg svcconfig.ProjectConfig |
| 435 » if err := cfgclient.Get(c, cfgclient.AsService, cset, path, textproto.Me
ssage(&pcfg), nil); err != nil { | 438 » msg, err := s.configCache.Get(c, cset, path, &pcfg) |
| 439 » if err != nil { |
| 436 return nil, errors.Annotate(err).Reason("failed to load project
config from %(cset)s.%(path)s"). | 440 return nil, errors.Annotate(err).Reason("failed to load project
config from %(cset)s.%(path)s"). |
| 437 D("cset", cset).D("path", path).Err() | 441 D("cset", cset).D("path", path).Err() |
| 438 } | 442 } |
| 439 » return &pcfg, nil | 443 » return msg.(*svcconfig.ProjectConfig), nil |
| 440 } | 444 } |
| 441 | 445 |
| 442 // SetShutdownFunc sets the service shutdown function. | 446 // SetShutdownFunc sets the service shutdown function. |
| 443 func (s *Service) SetShutdownFunc(f func()) { | 447 func (s *Service) SetShutdownFunc(f func()) { |
| 444 s.shutdownFunc.Store(f) | 448 s.shutdownFunc.Store(f) |
| 445 } | 449 } |
| 446 | 450 |
| 447 func (s *Service) shutdown() { | 451 func (s *Service) shutdown() { |
| 448 v := s.shutdownFunc.Load() | 452 v := s.shutdownFunc.Load() |
| 449 if f, ok := v.(func()); ok { | 453 if f, ok := v.(func()); ok { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 // | 579 // |
| 576 // An optional permutation function can be provided to modify those Options | 580 // An optional permutation function can be provided to modify those Options |
| 577 // before the Authenticator is created. | 581 // before the Authenticator is created. |
| 578 func (s *Service) TokenSource(c context.Context, f func(o *auth.Options)) (oauth
2.TokenSource, error) { | 582 func (s *Service) TokenSource(c context.Context, f func(o *auth.Options)) (oauth
2.TokenSource, error) { |
| 579 a, err := s.Authenticator(c, f) | 583 a, err := s.Authenticator(c, f) |
| 580 if err != nil { | 584 if err != nil { |
| 581 return nil, err | 585 return nil, err |
| 582 } | 586 } |
| 583 return a.TokenSource() | 587 return a.TokenSource() |
| 584 } | 588 } |
| OLD | NEW |