func (s *Server) Run(shutdown <-chan interface{}, conn client.Connection) error { node := &Node{ Host: *s.host, ExportPath: fmt.Sprintf("%s:%s", s.host.IPAddr, s.driver.ExportPath()), ExportTime: strconv.FormatInt(time.Now().UnixNano(), 16), } // Create the storage leader and client nodes if exists, _ := conn.Exists("/storage/leader"); !exists { conn.CreateDir("/storage/leader") } storageClientsPath := "/storage/clients" if exists, _ := conn.Exists(storageClientsPath); !exists { conn.CreateDir(storageClientsPath) } leader := conn.NewLeader("/storage/leader", node) leaderW, err := leader.TakeLead() if err != zookeeper.ErrDeadlock && err != nil { glog.Errorf("Could not take storage lead: %s", err) return err } // monitor dfs; log warnings each cycle; restart dfs if needed go s.monitor.MonitorDFSVolume(path.Join("/exports", s.driver.ExportPath()), s.host.IPAddr, node.ExportTime, shutdown, s.monitor.DFSVolumeMonitorPollUpdateFunc) // loop until shutdown event defer leader.ReleaseLead() for { clients, clientW, err := conn.ChildrenW(storageClientsPath) if err != nil { glog.Errorf("Could not set up watch for storage clients: %s", err) return err } s.monitor.SetMonitorStorageClients(conn, storageClientsPath) s.driver.SetClients(clients...) if err := s.driver.Sync(); err != nil { glog.Errorf("Error syncing driver: %s", err) return err } select { case e := <-clientW: glog.Info("storage.server: receieved event: %s", e) case <-leaderW: err := fmt.Errorf("storage.server: lost lead") return err case <-shutdown: return nil } } }
// CreateEndpointRegistry creates the endpoint registry and returns the EndpointRegistry type // This is created in the leader, most other calls will just get that one func CreateEndpointRegistry(conn client.Connection) (*EndpointRegistry, error) { path := zkEndpointsPath() if exists, err := zzk.PathExists(conn, path); err != nil { return nil, err } else if !exists { if err := conn.CreateDir(path); err != nil { glog.Errorf("error with CreateDir(%s) %+v", path, err) return nil, err } } return &EndpointRegistry{registryType{getPath: zkEndpointsPath, ephemeral: true}}, nil }
func (r *registryType) ensureDir(conn client.Connection, path string) error { timeout := time.After(time.Second * 60) var err error for { err = conn.CreateDir(path) if err == client.ErrNodeExists || err == nil { return nil } select { case <-timeout: break default: } } return fmt.Errorf("could not create dir: %s", path, err) }
// VHostRegistry ensures the vhost registry and returns the VhostRegistry type func VHostRegistry(conn client.Connection) (*VhostRegistry, error) { path := vhostPath() timeout := time.After(time.Second * 60) var err error for { err = conn.CreateDir(path) if err == client.ErrNodeExists || err == nil { err = nil break } select { case <-timeout: break default: } } if err != nil { glog.Errorf("error with CreateDir(%s) %+v", path, err) return nil, fmt.Errorf("could not create dir: %s", path, err) } return &VhostRegistry{registryType{getPath: vhostPath, ephemeral: true}}, nil }