Exemple #1
0
func StartListener(protoAddr string, app types.Application) (net.Listener, error) {
	parts := strings.SplitN(protoAddr, "://", 2)
	proto, addr := parts[0], parts[1]
	ln, err := net.Listen(proto, addr)
	if err != nil {
		return nil, err
	}

	// A goroutine to accept a connection.
	go func() {
		// semaphore := make(chan struct{}, maxNumberConnections)

		for {
			// semaphore <- struct{}{}

			// Accept a connection
			fmt.Println("Waiting for new connection...")
			conn, err := ln.Accept()
			if err != nil {
				Exit("Failed to accept connection")
			} else {
				fmt.Println("Accepted a new connection")
			}

			appContext := app.Open()
			closeConn := make(chan error, 2)             // Push to signal connection closed
			responses := make(chan types.Response, 1000) // A channel to buffer responses

			// Read requests from conn and deal with them
			go handleRequests(appContext, closeConn, conn, responses)
			// Pull responses from 'responses' and write them to conn.
			go handleResponses(closeConn, responses, conn)

			go func() {
				// Wait until signal to close connection
				errClose := <-closeConn
				if errClose != nil {
					fmt.Printf("Connection error: %v\n", errClose)
				} else {
					fmt.Println("Connection was closed.")
				}

				// Close the connection
				err := conn.Close()
				if err != nil {
					fmt.Printf("Error in closing connection: %v\n", err)
				}

				// Close the AppContext
				err = appContext.Close()
				if err != nil {
					fmt.Printf("Error in closing app context: %v\n", err)
				}

				// <-semaphore
			}()
		}

	}()

	return ln, nil
}
Exemple #2
0
func handleRequest(app types.Application, req types.Request, responses chan<- types.Response) {
	switch req := req.(type) {
	case types.RequestEcho:
		responses <- types.ResponseEcho{req.Message}
	case types.RequestFlush:
		responses <- types.ResponseFlush{}
	case types.RequestInfo:
		data := app.Info()
		responses <- types.ResponseInfo{data}
	case types.RequestSetOption:
		logStr := app.SetOption(req.Key, req.Value)
		responses <- types.ResponseSetOption{logStr}
	case types.RequestAppendTx:
		code, result, logStr := app.AppendTx(req.TxBytes)
		responses <- types.ResponseAppendTx{code, result, logStr}
	case types.RequestCheckTx:
		code, result, logStr := app.CheckTx(req.TxBytes)
		responses <- types.ResponseCheckTx{code, result, logStr}
	case types.RequestGetHash:
		hash, logStr := app.GetHash()
		responses <- types.ResponseGetHash{hash, logStr}
	case types.RequestQuery:
		result, logStr := app.Query(req.QueryBytes)
		responses <- types.ResponseQuery{result, logStr}
	default:
		responses <- types.ResponseException{"Unknown request"}
	}
}
Exemple #3
0
func handleRequest(app types.Application, req *types.Request, responses chan<- *types.Response) {
	switch req.Type {
	case types.MessageType_Echo:
		responses <- types.ResponseEcho(string(req.Data))
	case types.MessageType_Flush:
		responses <- types.ResponseFlush()
	case types.MessageType_Info:
		data := app.Info()
		responses <- types.ResponseInfo(data)
	case types.MessageType_SetOption:
		logStr := app.SetOption(req.Key, req.Value)
		responses <- types.ResponseSetOption(logStr)
	case types.MessageType_AppendTx:
		code, result, logStr := app.AppendTx(req.Data)
		responses <- types.ResponseAppendTx(code, result, logStr)
	case types.MessageType_CheckTx:
		code, result, logStr := app.CheckTx(req.Data)
		responses <- types.ResponseCheckTx(code, result, logStr)
	case types.MessageType_Commit:
		hash, logStr := app.Commit()
		responses <- types.ResponseCommit(hash, logStr)
	case types.MessageType_Query:
		code, result, logStr := app.Query(req.Data)
		responses <- types.ResponseQuery(code, result, logStr)
	default:
		responses <- types.ResponseException("Unknown request")
	}
}