Example #1
0
func main() {
	// Define and parse flags.
	conns := flag.Uint("conns", 20, "Sets number of connections to use.")
	count := flag.Uint("count", 1000, "Number of users to create.")
	flag.Parse()

	// Validate flags.
	if *conns == 0 {
		log.Fatal("Number of connections must be at least 1.")
	}
	if *count%*conns != 0 {
		log.Fatal("Please use a number of users which divides " +
			"into the number of connections.")
	}

	// Load configuration from config file.
	loadConfig()

	log.Print("Loaded configuration, starting...")

	// Launch the specified number of goroutines registering users.
	perConnCount := *count / *conns
	doneChan := make(chan bool, *conns)

	clientNodes := config.ClientNodes()
	for i := 0; i < int(*conns); i++ {
		node := clientNodes[i%len(clientNodes)]
		prefix := "Test-" + strconv.FormatUint(uint64(i), 10) + "-"
		go register(node, prefix, perConnCount, doneChan)
	}

	// Wait until they're all done.
	for i := uint(0); i < *conns; i++ {
		<-doneChan
	}
}
Example #2
0
func process() {

	// Try to make an outgoing connection to all other client nodes,
	// if we're not in a degraded state.
	store.StartTransaction()
	if !store.Degraded() {

		for _, node := range config.ClientNodes() {
			if node == config.Id() {
				continue
			}

			conn, err := connect.Dial(connect.RELAY_PROTOCOL, node)
			if err != nil {
				// No luck connecting.
				continue
			}

			connections[node] = append(connections[node], conn)
			go handleConn(node, conn)
		}
	}
	store.EndTransaction()

	// Retry connections once per config.CHANGE_TIMEOUT_PERIOD
	// Largely arbitrary.
	reconnectTicker := time.Tick(config.CHANGE_TIMEOUT_PERIOD)

	for {
		select {

		// Connection retry tick.
		// If not degraded, try to make an outgoing connection to any
		// client node that we do not have at least one connection to.
		case <-reconnectTicker:

			store.StartTransaction()

			// Do not attempt to make connections while degraded.
			if store.Degraded() {
				store.EndTransaction()
				break
			}

			for _, node := range config.ClientNodes() {
				if node == config.Id() {
					continue
				}
				if len(connections[node]) > 0 {
					continue
				}

				conn, err := connect.Dial(
					connect.RELAY_PROTOCOL, node)

				if err != nil {
					// No luck connecting.
					continue
				}

				connections[node] =
					append(connections[node], conn)
				go handleConn(node, conn)
			}

			store.EndTransaction()

		// New received connection.
		case receivedConn := <-receivedConnCh:
			node := receivedConn.node
			conn := receivedConn.conn

			store.StartTransaction()

			// If we are degraded, reject the connection.
			if store.Degraded() {
				conn.Close()
				store.EndTransaction()
				break
			}

			// Add to our connections.
			connections[node] = append(connections[node], conn)

			store.EndTransaction()

		// Terminated connection.
		case receivedConn := <-terminatedConnCh:
			node := receivedConn.node
			conn := receivedConn.conn

			store.StartTransaction()

			// Remove this connection from our connection list.
			index := -1
			for i, _ := range connections[node] {
				if conn == connections[node][i] {
					index = i
					break
				}
			}
			if index != -1 {
				connections[node] =
					append(connections[node][:index],
						connections[node][index+1:]...)
			}

			store.EndTransaction()
		}
	}
}