Example #1
0
// Test the creation of identifiers based on parts.
func TestIdentifier(t *testing.T) {
	assert := audit.NewTestingAssertion(t, true)

	// Identifier.
	id := identifier.Identifier("One", 2, "three four")
	assert.Equal(id, "one:2:three-four", "wrong Identifier() result")

	id = identifier.Identifier(2011, 6, 22, "One, two, or  three things.")
	assert.Equal(id, "2011:6:22:one-two-or-three-things", "wrong Identifier() result")
}
Example #2
0
func addRoom(env cells.Environment, buildingName string, roomName string) {
	r := newRoom(roomName, buildingName, []string{"hell"})
	roomID := identifier.Identifier("room", buildingName, roomName)
	env.StartCell(roomID, r)

	paID := identifier.Identifier("building", buildingName, "pa")
	subscribe(env, paID, roomID)

	env.EmitNew(identifier.Identifier("building", buildingName), ROOM_ADDED, cells.PayloadValues{
		"room": roomID,
	}, nil)
}
Example #3
0
func (r *room) Init(ctx cells.Context) (err error) {
	r.ctx = ctx
	r.censorID = identifier.Identifier("room", r.buildingName, r.name, "censor")
	r.censor = newCensor(r.censorID, r.censoredWords)

	// TODO: hangs without goroutine
	go func() {
		roomID := identifier.Identifier("room", r.buildingName, r.name)
		env := r.ctx.Environment()
		env.StartCell(r.censorID, r.censor)
		subscribe(env, r.censorID, roomID)
	}()

	return
}
Example #4
0
func wsRoomHandler(w http.ResponseWriter, r *http.Request) {
	user := r.URL.Query().Get("user")

	if user == "" || user == "undefined" {
		http.Error(w, "user name not specified", http.StatusTeapot)
		return
	}

	vars := mux.Vars(r)
	building := vars["building"]
	room := vars["room"]
	roomID := makeRoomID(room, building)

	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Fatal(err)
	}

	wsb := newWebSocketBehavior(ws, user)
	id := identifier.Identifier("wsb", user, identifier.NewUUID())
	rootEnvironment.StartCell(id, wsb)
	subscribe(rootEnvironment, roomID, id)

	userID := addUser(rootEnvironment, building, room, user)

	defer func() {
		wsb.sendUserLeaveEvent()
		rootEnvironment.StopCell(userID)
		rootEnvironment.StopCell(id)
	}()

	go wsb.writePump()
	wsb.readPump()
}
Example #5
0
// newCell create a new cell around a behavior.
func newCell(env *environment, id string, behavior Behavior) (*cell, error) {
	logger.Infof("cell '%s' starts", id)
	// Init cell runtime.
	c := &cell{
		env:               env,
		id:                id,
		measuringID:       identifier.Identifier("cells", env.id, "cell", id),
		behavior:          behavior,
		emitters:          newConnections(),
		subscribers:       newConnections(),
		emitTimeoutTicker: time.NewTicker(5 * time.Second),
	}
	// Set configuration.
	if bebs, ok := behavior.(BehaviorEventBufferSize); ok {
		size := bebs.EventBufferSize()
		if size < minEventBufferSize {
			size = minEventBufferSize
		}
		c.eventc = make(chan Event, size)
	} else {
		c.eventc = make(chan Event, minEventBufferSize)
	}
	if brf, ok := behavior.(BehaviorRecoveringFrequency); ok {
		number, duration := brf.RecoveringFrequency()
		if duration.Seconds()/float64(number) < 0.1 {
			number = minRecoveringNumber
			duration = minRecoveringDuration
		}
		c.recoveringNumber = number
		c.recoveringDuration = duration
	} else {
		c.recoveringNumber = minRecoveringNumber
		c.recoveringDuration = minRecoveringDuration
	}
	if bet, ok := behavior.(BehaviorEmitTimeout); ok {
		timeout := bet.EmitTimeout()
		switch {
		case timeout < minEmitTimeout:
			timeout = minEmitTimeout
		case timeout > maxEmitTimeout:
			timeout = maxEmitTimeout
		}
		c.emitTimeout = int(timeout.Seconds() / 5)
	} else {
		c.emitTimeout = int(maxEmitTimeout.Seconds() / 5)
	}
	// Init behavior.
	if err := behavior.Init(c); err != nil {
		return nil, errors.Annotate(err, ErrCellInit, errorMessages, id)
	}
	// Start backend.
	c.loop = loop.GoRecoverable(c.backendLoop, c.checkRecovering, id)
	return c, nil
}
Example #6
0
func addLogUser(env cells.Environment, buildingName string, roomName string) {
	roomID := identifier.Identifier("room", buildingName, roomName)
	userID := makeUserID("logger")

	lu := &logUser{}
	lu.name = "logger"
	env.StartCell(userID, lu)

	subscribe(env, roomID, userID)

	env.EmitNew(roomID, "user-added", cells.PayloadValues{
		"user": userID,
	}, nil)
}
Example #7
0
func addUser(env cells.Environment, buildingName string, roomName string, userName string) string {
	roomID := identifier.Identifier("room", buildingName, roomName)
	userID := makeUserID(userName)

	u := newUser(userName)
	env.StartCell(userID, u)

	subscribe(env, roomID, userID)

	env.EmitNew(roomID, USER_ADDED, cells.PayloadValues{
		"user": userID,
	}, nil)

	return userID
}
Example #8
0
// NewEnvironment creates a new environment.
func NewEnvironment(idParts ...interface{}) Environment {
	var id string
	if len(idParts) == 0 {
		id = identifier.NewUUID().String()
	} else {
		id = identifier.Identifier(idParts...)
	}
	env := &environment{
		id:    id,
		cells: newRegistry(),
	}
	runtime.SetFinalizer(env, (*environment).Stop)
	logger.Infof("cells environment %q started", env.ID())
	return env
}
Example #9
0
// backendLoop is the backend for the processing of messages.
func (c *cell) backendLoop(l loop.Loop) error {
	monitoring.IncrVariable(identifier.Identifier("cells", c.env.ID(), "total-cells"))
	defer monitoring.DecrVariable(identifier.Identifier("cells", c.env.ID(), "total-cells"))

	for {
		select {
		case <-l.ShallStop():
			return c.behavior.Terminate()
		case subscribers := <-c.subscriberc:
			c.subscribers = subscribers
		case event := <-c.eventc:
			if event == nil {
				panic("received illegal nil event!")
			}
			measuring := monitoring.BeginMeasuring(c.measuringID)
			err := c.behavior.ProcessEvent(event)
			if err != nil {
				c.loop.Kill(err)
				continue
			}
			measuring.EndMeasuring()
		}
	}
}
Example #10
0
func addBuilding(env cells.Environment, buildingName string) string {
	b := &building{
		name:  buildingName,
		rooms: make(map[string]bool),
	}
	buildingID := makeBuildingID(buildingName)
	env.StartCell(buildingID, b)

	pa := &publicAddress{interval: time.Second * 10}
	paID := identifier.Identifier("building", buildingName, "pa")
	env.StartCell(paID, pa)

	subscribe(env, paID, buildingID)

	return buildingID
}
Example #11
0
// Do executes one Redis command and returns
// the result as result set.
func (conn *Connection) Do(cmd string, args ...interface{}) (*ResultSet, error) {
	cmd = strings.ToLower(cmd)
	if strings.Contains(cmd, "subscribe") {
		return nil, errors.New(ErrUseSubscription, errorMessages)
	}
	err := conn.ensureProtocol()
	if err != nil {
		return nil, err
	}
	if conn.database.monitoring {
		m := monitoring.BeginMeasuring(identifier.Identifier("redis", "command", cmd))
		defer m.EndMeasuring()
	}
	err = conn.resp.sendCommand(cmd, args...)
	logCommand(cmd, args, err, conn.database.logging)
	if err != nil {
		return nil, err
	}
	result, err := conn.resp.receiveResultSet()
	return result, err
}
Example #12
0
// Do executes one Redis command and returns
// the result as result set.
func (ppl *Pipeline) Do(cmd string, args ...interface{}) error {
	cmd = strings.ToLower(cmd)
	if strings.Contains(cmd, "subscribe") {
		return errors.New(ErrUseSubscription, errorMessages)
	}
	err := ppl.ensureProtocol()
	if err != nil {
		return err
	}
	if ppl.database.monitoring {
		m := monitoring.BeginMeasuring(identifier.Identifier("redis", "command", cmd))
		defer m.EndMeasuring()
	}
	err = ppl.resp.sendCommand(cmd, args...)
	logCommand(cmd, args, err, ppl.database.logging)
	if err != nil {
		return err
	}
	ppl.counter++
	return err
}
Example #13
0
// backendLoop is the backend for the processing of messages.
func (c *cell) backendLoop(l loop.Loop) error {
	totalCellsID := identifier.Identifier("cells", c.env.ID(), "total-cells")
	monitoring.IncrVariable(totalCellsID)
	defer monitoring.DecrVariable(totalCellsID)

	for {
		select {
		case <-l.ShallStop():
			return c.behavior.Terminate()
		case event := <-c.eventc:
			if event == nil {
				panic("received illegal nil event!")
			}
			measuring := monitoring.BeginMeasuring(c.measuringID)
			err := c.behavior.ProcessEvent(event)
			measuring.EndMeasuring()
			if err != nil {
				logger.Errorf("cell %q processed event %q with error: %v", c.id, event.Topic(), err)
				return err
			}
		}
	}
}
Example #14
0
func makeRoomID(name string, buildingName string) string {
	return identifier.Identifier("room", buildingName, name)
}
Example #15
0
func makeUserID(name string) string {
	return identifier.Identifier("user", name)
}
Example #16
0
func makeBuildingID(name string) string {
	return identifier.Identifier("building", name)
}