Exemple #1
0
// Starts listening for commands through the given app's connection.
// Since this is a blocking function, it should likely be called in
// a goroutine.
// At the end of the function, closes the application's network resources.
func ListenForCommands(a *app.App) {
	defer closeApp(a)

	// loop forever consuming messages
	for {
		// get the next command
		strategy, err := getCommand(a)
		if err != nil {
			id := "NO_ID_FOUND"
			if a.Manifest != nil {
				id = a.Manifest.InstanceId
			}
			logging.Error("Application %s encountered fatal error: %s",
				id,
				err.Error())
			return
		}

		// do the command
		if strategy.GetVerb() == "APP_MANIFEST" {
			if !strategy.Execute() {
				logging.Error("Application's manifest did not parse correctly")
				return
			}
		} else {
			// HACK to get around golang compiler error
			// originally:
			//   go strategy.Execute()
			// message:
			//   "go requires function call not conversion"
			go performStrategy(strategy)
		}
	}
}
func (c *commandStrategy) Execute() bool {
	var err error
	ret := true

	switch c.verb {
	case "APP_MANIFEST":
		ret = c.appManifest()
	case "APP_UP", "APP_DOWN", "APP_IN_USE":
		err = c.statusChange()
	case "MSG_QUERY":
		err = c.msgQuery()
	case "MSG_BROADCAST":
		err = c.msgBroadcast()
	case "MSG_QUERY_SUCCESS":
		err = c.msgQuerySuccess()
	case "MSG_QUERY_FAIL":
		err = c.msgQueryFail()
	default:
		err = fmt.Errorf("No matching verb found for %s", c.verb)
	}

	if err != nil {
		id := "NO_ID_FOUND"
		if c.app.Manifest != nil {
			id = c.app.Manifest.InstanceId
		}
		logging.Error("Application %s had command error %s", id, err.Error())
		b, _ := json.Marshal(c.body)
		return newFailedCommandStrategy(c.app, string(b), err.Error()).Execute()
	}
	return ret
}
// Parses a command given the command's message string
// (verb and body, no message length)
func ParseCommand(a *app.App, message string) (CommandStrategy, bool) {
	id := "NO_ID_FOUND"
	if a.Manifest != nil {
		id = a.Manifest.InstanceId
	}
	logging.Debug("Parsing from app %s: \n%s", id, message)

	ret, err := internalParseCommand(a, message)
	if err != nil {
		logging.Error("Parse failed from app %s: %s", id, err.Error())
		return newFailedCommandStrategy(a, message, err.Error()), false
	}
	return ret, true
}
// construct the app based on its manifest
func (c *commandStrategy) appManifest() bool {
	c.app.RWMutex.Lock()
	defer c.app.RWMutex.Unlock()

	logging.Debug("Parsing application's manifest")

	man, err := decodeManifest(c.body)
	if err != nil {
		logging.Error("App's manifest is invalid: %s", err)
		sendManifestFail(c.app, err.Error())
		return false
	}
	if _, exists := registry.GetInstance(man.InstanceId); exists {
		logging.Error("App's instance id is already taken: %s", man.InstanceId)
		sendManifestFail(c.app, fmt.Sprintf("instanceId %s is in use", man.InstanceId))
		return false
	}
	c.app.Status = app.STATUS_DOWN
	c.app.Manifest = man
	registry.Register(c.app)
	sendManifestOkAndDependencies(c.app)
	logging.Info("App '%s' now connected with manifest parsed", c.app.Manifest.InstanceId)
	return true
}