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 } }
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() } } }