15 // DiscoverKeepServers gets list of available keep services from api server
16 func (this *KeepClient) DiscoverKeepServers() error {
19 // Get keep services from api server
20 err := this.Arvados.Call("GET", "keep_services", "", "accessible", nil, &list)
25 return this.loadKeepServers(list)
28 // LoadKeepServicesFromJSON gets list of available keep services from given JSON
29 func (this *KeepClient) LoadKeepServicesFromJSON(services string) error {
32 // Load keep services from given json
33 dec := json.NewDecoder(strings.NewReader(services))
34 if err := dec.Decode(&list); err != nil {
38 return this.loadKeepServers(list)
41 // RefreshServices calls DiscoverKeepServers to refresh the keep
42 // service list on SIGHUP; when the given interval has elapsed since
43 // the last refresh; and (if the last refresh failed) the given
44 // errInterval has elapsed.
45 func (kc *KeepClient) RefreshServices(interval, errInterval time.Duration) {
46 var previousRoots = []map[string]string{}
48 timer := time.NewTimer(interval)
49 gotHUP := make(chan os.Signal, 1)
50 signal.Notify(gotHUP, syscall.SIGHUP)
59 if err := kc.DiscoverKeepServers(); err != nil {
60 log.Println("Error retrieving services list: %v (retrying in %v)", err, errInterval)
61 timer.Reset(errInterval)
64 newRoots := []map[string]string{kc.LocalRoots(), kc.GatewayRoots()}
66 if !reflect.DeepEqual(previousRoots, newRoots) {
67 log.Printf("Updated services list: locals %v gateways %v", newRoots[0], newRoots[1])
68 previousRoots = newRoots
71 if len(newRoots[0]) == 0 {
72 log.Printf("WARNING: No local services (retrying in %v)", errInterval)
73 timer.Reset(errInterval)
79 func (this *KeepClient) loadKeepServers(list svcList) error {
80 listed := make(map[string]bool)
81 localRoots := make(map[string]string)
82 gatewayRoots := make(map[string]string)
83 writableLocalRoots := make(map[string]string)
85 // replicasPerService is 1 for disks; unknown or unlimited otherwise
86 this.replicasPerService = 1
87 this.Using_proxy = false
89 for _, service := range list.Items {
94 url := fmt.Sprintf("%s://%s:%d", scheme, service.Hostname, service.Port)
102 localRoots[service.Uuid] = url
103 if service.SvcType == "proxy" {
104 this.Using_proxy = true
107 if service.ReadOnly == false {
108 writableLocalRoots[service.Uuid] = url
109 if service.SvcType != "disk" {
110 this.replicasPerService = 0
114 // Gateway services are only used when specified by
115 // UUID, so there's nothing to gain by filtering them
116 // by service type. Including all accessible services
117 // (gateway and otherwise) merely accommodates more
118 // service configurations.
119 gatewayRoots[service.Uuid] = url
122 if this.Using_proxy {
123 this.setClientSettingsProxy()
125 this.setClientSettingsDisk()
128 this.SetServiceRoots(localRoots, writableLocalRoots, gatewayRoots)