Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(740)

Side by Side Diff: appengine/cmd/dm/distributor/registry.go

Issue 1537883002: Initial distributor implementation (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: work in progress Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package distributor
6
7 import (
8 "fmt"
9 "reflect"
10 "sync"
11
12 "github.com/golang/protobuf/proto"
13 "github.com/luci/gae/service/info"
14 protos "github.com/luci/luci-go/appengine/cmd/dm/distributor/protos"
15 "golang.org/x/net/context"
16 )
17
18 var registry = struct {
19 sync.RWMutex
20 data map[reflect.Type]Factory
21 }{data: map[reflect.Type]Factory{}}
22
23 // Register enrolls a new distributor type in the registry. Calling
24 // this multiple times for the same proto Message will panic.
25 func Register(p proto.Message, factory Factory) {
26 if factory == nil {
27 panic("factory is nil")
28 }
29 if p == nil {
30 panic("proto.Message is nil")
31 }
32
33 typ := reflect.TypeOf(p)
34
35 registry.Lock()
36 defer registry.Unlock()
37 if _, ok := registry.data[typ]; ok {
38 panic(fmt.Errorf("trying to register %q twice", typ))
39 }
40 registry.data[typ] = factory
41 }
42
43 // MakeDistributor builds a distributor instance that's configured with the
44 // provided config.
45 //
46 // The configuration for this distributor are obtained from luci-config at the
47 // time an Execution is started.
48 func MakeDistributor(c context.Context, cfg *Config) (D, error) {
49 typ := reflect.TypeOf(cfg.ImplConfig)
50
51 registry.RLock()
52 fn, ok := registry.data[typ]
53 registry.RUnlock()
54
55 if !ok {
56 return nil, fmt.Errorf("unknown distributor type %T", cfg.ImplCo nfig)
57 }
58
59 return fn(c, cfg)
60 }
61
62 // LoadConfiguration loads the named distributor configurtaion from luci-config,
63 // possibly using the in-memory or memcache version.
64 func LoadConfiguration(c context.Context, cfgName string) (ret *Config, err erro r) {
65 cfgVersion := ""
66 fullDMConfig := proto.Message(nil)
67 // TODO(riannucci): get config and version from luci-config in a fast ca ched way.
68
69 configs := fullDMConfig.(*protos.Config)
70 cfg, ok := configs.DistributorConfigs[cfgName]
71 if !ok {
72 err = fmt.Errorf("unknown distributor configuration: %q", cfgNam e)
73 return
74 }
75 if alias := cfg.GetAlias(); alias != nil {
76 cfg, ok = configs.DistributorConfigs[alias.OtherConfig]
77 if !ok {
78 err = fmt.Errorf("unknown distributor configuration: %q (via alias %q)", cfgName, alias.OtherConfig)
79 return
80 }
81 if cfg.GetAlias() != nil {
82 err = fmt.Errorf("too many levels of indirection for ali as %q (points to alias %q)", cfgName, alias.OtherConfig)
83 return
84 }
85 }
86
87 dt := cfg.GetDistributorType()
88 if dt == nil {
89 err = fmt.Errorf("blank or unrecognized distributor_type")
90 return
91 }
92 dVal := reflect.ValueOf(dt)
93
94 // All non-nil DistributorType's have a single field which is the actual oneof
95 // value.
96 implConfig := dVal.Field(0).Interface().(proto.Message)
97
98 baseURL := fmt.Sprintf("https://%s/", info.Get(c).DefaultVersionHostname ())
99 ret = &Config{
100 baseURL,
101 baseURL + handlerPath(cfgName),
102 cfgName,
103 cfgVersion,
104 implConfig,
105 }
106 return
107 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698