go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/logdog/server/service/main.go (about)

     1  // Copyright 2021 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package service
    16  
    17  import (
    18  	"context"
    19  	"flag"
    20  
    21  	"go.chromium.org/luci/server"
    22  	"go.chromium.org/luci/server/gaeemulation"
    23  	"go.chromium.org/luci/server/module"
    24  
    25  	logdog "go.chromium.org/luci/logdog/api/endpoints/coordinator/services/v1"
    26  	"go.chromium.org/luci/logdog/common/storage"
    27  	"go.chromium.org/luci/logdog/common/storage/bigtable"
    28  	"go.chromium.org/luci/logdog/server/config"
    29  )
    30  
    31  // Implementations contains some preconfigured Logdog subsystem clients.
    32  type Implementations struct {
    33  	Storage     storage.Storage       // the intermediate storage
    34  	Coordinator logdog.ServicesClient // the bundling coordinator client
    35  }
    36  
    37  // MainCfg are global configuration options for `Main`.
    38  //
    39  // The settings here are tied to the code-to-be-executed, rather than the
    40  // the execution environment for the code.
    41  type MainCfg struct {
    42  	// The AppProfile for the global BigTable client for this service.
    43  	//
    44  	// If empty, the default application profile will be used.
    45  	BigTableAppProfile string
    46  }
    47  
    48  // Main initializes and runs a logdog microservice process.
    49  func Main(cfg MainCfg, init func(srv *server.Server, impl *Implementations) error) {
    50  	modules := []module.Module{
    51  		gaeemulation.NewModuleFromFlags(), // for fetching LUCI project configs
    52  	}
    53  
    54  	coordFlags := coordinatorFlags{}
    55  	coordFlags.register(flag.CommandLine)
    56  
    57  	storageFlags := bigtable.Flags{
    58  		AppProfile: cfg.BigTableAppProfile,
    59  	}
    60  	storageFlags.Register(flag.CommandLine)
    61  
    62  	server.Main(nil, modules, func(srv *server.Server) error {
    63  		if err := coordFlags.validate(); err != nil {
    64  			return err
    65  		}
    66  		if err := storageFlags.Validate(); err != nil {
    67  			return err
    68  		}
    69  
    70  		// Add an in-memory config caching to avoid hitting datastore all the time.
    71  		srv.Context = config.WithStore(srv.Context, &config.Store{})
    72  
    73  		// Initialize our Storage.
    74  		st, err := bigtable.StorageFromFlags(srv.Context, &storageFlags)
    75  		if err != nil {
    76  			return err
    77  		}
    78  		srv.RegisterCleanup(func(context.Context) { st.Close() })
    79  
    80  		// Initialize a Coordinator client that bundles requests together.
    81  		coordClient, err := coordinator(srv.Context, &coordFlags)
    82  		if err != nil {
    83  			return err
    84  		}
    85  		srv.RegisterCleanup(func(context.Context) { coordClient.Flush() })
    86  
    87  		// Let the particular microservice initialize itself.
    88  		return init(srv, &Implementations{
    89  			Storage:     st,
    90  			Coordinator: coordClient,
    91  		})
    92  	})
    93  }