func pathExistedBefore(e cp.Event) (bool, error) { if e.Rev == 0 { return false, nil } sp := e.GetSnapshot() sp.Rev-- exists, _, err := sp.Exists(e.Path) return exists, err }
func newEvent(src cp.Event) (*Event, error) { event := &Event{ Type: EvUnknown, Rev: src.Rev, raw: src, } for re, ev := range eventPatterns { if match := re.FindStringSubmatch(src.Path); match != nil { switch ev { case pathApp: if src.IsSet() { event.Type = EvAppReg } else if src.IsDel() { event.Type = EvAppUnreg } event.Path = EventData{App: &match[1]} case pathRev: if src.IsSet() { event.Type = EvRevReg } else if src.IsDel() { event.Type = EvRevUnreg } event.Path = EventData{App: &match[1], Revision: &match[2]} case pathProc: if src.IsSet() { event.Type = EvProcReg } else if src.IsDel() { event.Type = EvProcUnreg } event.Path = EventData{App: &match[1], Proc: &match[2]} case pathProcAttrs: if !src.IsSet() { break } event.Type = EvProcAttrs event.Path = EventData{App: &match[1], Proc: &match[2]} case pathInsRegistered: if src.IsSet() { event.Type = EvInsReg } else if src.IsDel() { event.Type = EvInsUnreg } event.Path = EventData{Instance: &match[1]} case pathInsStart: if !src.IsSet() { break } // The start file can be in three different states: // 1. "" - instance got registered or unclaimed // 2. "<ip>" - instance got claimed // 3. "<ip> <host> <port> <tport> - instance got started if len(bytes.Fields(src.Body)) > 1 { event.Type = EvInsStart } else if len(src.Body) == 0 { // The file is empty, so distinguish between registered and // unclaimed by whether the file existed before already. existed, err := pathExistedBefore(src) if err != nil { return nil, err } if existed { event.Type = EvInsUnclaim } } event.Path = EventData{Instance: &match[1]} case pathInsStop: if !src.IsSet() { break } event.Type = EvInsStop event.Path = EventData{Instance: &match[1]} case pathInsStatus: if !src.IsSet() { break } switch InsStatus(src.Body) { case InsStatusRunning: event.Type = EvInsStart case InsStatusExited: event.Type = EvInsExit case InsStatusFailed: event.Type = EvInsFail case InsStatusLost: event.Type = EvInsLost } event.Path = EventData{Instance: &match[1]} } break } } return event, nil }