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.Printf("WARNING: 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 DebugPrintf("DEBUG: 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
88 for _, service := range list.Items {
93 url := fmt.Sprintf("%s://%s:%d", scheme, service.Hostname, service.Port)
101 localRoots[service.Uuid] = url
102 if service.ReadOnly == false {
103 writableLocalRoots[service.Uuid] = url
104 if service.SvcType != "disk" {
105 this.replicasPerService = 0
109 if service.SvcType != "disk" {
110 this.foundNonDiskSvc = true
113 // Gateway services are only used when specified by
114 // UUID, so there's nothing to gain by filtering them
115 // by service type. Including all accessible services
116 // (gateway and otherwise) merely accommodates more
117 // service configurations.
118 gatewayRoots[service.Uuid] = url
121 if this.foundNonDiskSvc {
122 this.setClientSettingsNonDisk()
124 this.setClientSettingsDisk()
127 this.SetServiceRoots(localRoots, writableLocalRoots, gatewayRoots)