Пример #1
0
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()
		}
	}
}
Пример #2
0
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
}