func (self *Server) listen() { errors := ErrorHandler() var EOF bool for !EOF { con, err := self.ln.AcceptTCP() if netutils.IsEOF(err) { EOF = true } else if err != nil { log.Panic(err) } else { send := netutils.TCPWriter(con, errors) recv := netutils.TCPReader(con, errors) go self.Connection(send, recv).Serve() } } }
func (s *YAKVS) listen() { errChan := make(chan error) go func() { for err := range errChan { s.logger.Println(err) } }() ticker := time.NewTicker(time.Millisecond * 100) // TODO config option? stopTickGoroutine := make(chan bool) go func() { for { select { case <-stopTickGoroutine: ticker.Stop() return case <-ticker.C: if s.config.Server.Connection_timeout > 0 { toTimeout := make([]*connection, 0) dTimeout := s.config.Server.Connection_timeout s.connectionsLock.RLock() for _, conn := range s.connections { conn.lastAccessLock.Lock() since := time.Since(conn.lastAccess) conn.lastAccessLock.Unlock() if since >= dTimeout { toTimeout = append(toTimeout, conn) } } s.connectionsLock.RUnlock() for _, conn := range toTimeout { conn.writeString(cTIMED_OUT) s.closeConnection(conn) } } } } }() s.logger.Println("yakvs server started") var cid uint64 var exit bool for !exit { conn, err := s.listener.AcceptTCP() if netutils.IsEOF(err) { exit = true } else if err != nil { s.logger.Panic(err) } else { s.runningLock.Lock() isRunning := s.running s.runningLock.Unlock() var canConnect bool if isRunning { maxClients := s.config.Server.Max_clients if maxClients == 0 { canConnect = true } else { s.connectionsLock.Lock() canConnect = len(s.connections) < maxClients s.connectionsLock.Unlock() } } else { canConnect = false exit = true } if canConnect { go s.accept(cid, conn, errChan).serve() if s.config.Logging.Connection_accepted { s.logger.Println("accepted connection " + strconv.FormatUint(cid, 10) + "@" + conn.RemoteAddr().String()) } cid++ } else { conn.Write([]byte(cCONNECTION_REFUSED)) conn.Close() if s.config.Logging.Connection_refused { s.logger.Println("ignored connection from " + conn.RemoteAddr().String()) } } } } close(errChan) stopTickGoroutine <- true }