Implement one of the Redis with Golang let the code run for a while

Source: Internet
Author: User

Write in front

In the previous article, we combed through the basic functions of the Godis v1.0 version, which is to achieve client/server interaction. First let the code run up, just calculate the vitality.
This article Godis version number: v0.0.1

In this series, minimize the introduction of Golang syntax, C grammar, and Redis principles, focusing on the theme "Using Golang for Redis". If there are omissions, deficiencies, please correct me.

Go to the Chase

Redis Event handlers

It is necessary to realize the interaction between C/s and network programming. In Redis, there is a way to implement:

*redis has developed its own network event handler based on Reactor mode: This processor is known as the file event handler (filename handler):

    • The file event handler uses an I/O multiplexing (multiplexing) program to listen to multiple sockets at the same time and correlate different event handlers for sockets based on the tasks currently performed by the socket.
    • When a listening socket is ready to perform an operation such as a connection answer (accept), read (read), write (write), close (close), the file event corresponding to the operation is generated, and the file event handler invokes the associated event handler before the socket to handle these events. *

Architecture diagram for Redis event handlers: Picture description

Redis is both simple and high-performance, but for the sake of its code complexity, Godis v0.0.1 will adopt a simpler mentally retarded solution. Godis's code uses the simplest synchronization technology to simplify network processing, because the complex does not:). Temporarily discard high-performance, only available. In future releases, the network layer will be optimized in conjunction with Golang's own features.

Godis's Solution

Client/server interaction, just use the Golang NET package for socket programming, write a process for the listener-read-process-reply service side and a process for the establishment-send-receive-display client.
Picture description
Both English and Chinese are the main functions of net package in Golang, here is a brief description of the net package functions used in this article:
RESOLVETCPADDR:
Use cases: tcpAddr, err := net.ResolveTCPAddr("tcp4", “127.0.0.1:9736”);
Function: Create a data structure of type TCPADDR, which contains IP and port, and is reserved for connection;

LISTENTCP:
Case:netListen, err := net.Listen("tcp", "127.0.0.1:9763");
Function: Monitor

Accept:
Case:conn, err := netListen.Accept()
Function: Receive request

Read:
Case:n, err := conn.Read(buff)
Function: Read data

Write:
Case:conn.Write([]byte(buff))
Function: Response data

Net. DIALTCP:
Case:conn, err := net.DialTCP("tcp", nil, tcpAddr)
Function: Establish connection

Code implementation

According to the process in the previous diagram, some of the code on the service side is as follows:

func main() {        netListen, err := net.Listen("tcp", "127.0.0.1:9736")        if err != nil {            log.Print("listen err ")        }        //checkError(err)        defer netListen.Close()            for {            conn, err := netListen.Accept()            if err != nil {                continue            }            go handle(conn)        }    }

See here for real-world full code implementations.
Before we set up the client, we passed the Telnet test to see if the server is available (Redis also supports Telnet connection, request, which is described later in the Protocol section).
Compiling godis-server.go
Go build godis-server.go and start./godis-server

Perform telnet localhost 9736

You can see the following reply:
Picture description

Next, following the steps of the simple flowchart, the client is implemented as follows:

func main() {    IPPort := "127.0.0.1:9736"    reader := bufio.NewReader(os.Stdin)    fmt.Println("Hi Godis")    tcpAddr, err := net.ResolveTCPAddr("tcp4", IPPort)    checkError(err)    conn, err := net.DialTCP("tcp", nil, tcpAddr)    checkError(err)    defer conn.Close()    for {        fmt.Print(IPPort + "> ")        text, _ := reader.ReadString('\n')        //清除掉回车换行符        text = strings.Replace(text, "\n", "", -1)        send2Server(text, conn)        buff := make([]byte, 1024)        n, err := conn.Read(buff)        checkError(err)        if n == 0 {            fmt.Println(IPPort+"> ", "nil")        } else {            fmt.Println(IPPort+">", string(buff))        }    }}

Compile the Cli.go and start the./CLI
Interact with the server, as shown in:
Picture description

The basic client/server communication is implemented here. The next step is to add a little interaction option, which is the option to execute the redis command line, to make it look more like redis.

Add a smooth exit to the service side.

Future increases in persistence will persist data to disk and prevent loss on smooth exit.
The way to use smooth exit is to let the client listen to the signal, have "exit" signal reach, finish the finishing work and then exit.
Simplify the code as follows:

func sigHandler(c chan os.Signal) {    for s := range c {        switch s {        case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:            exitHandler()        default:            fmt.Println("signal ", s)        }    }}func exitHandler() {    fmt.Println("exiting smoothly ...")    fmt.Println("bye ")    os.Exit(0)}```编译之后,执行Ctrl+c退出,可以看到:![clipboard.png](/img/bVbb2yA)本篇遇到过的问题:---------1.服务端读取客户端信息时,发生err时没有return,导致服务端会一直读取数据失败。解决方案:return或者其他可以退出goroutine的方案。本篇就是这样了。简陋是简陋了点,又不是不能用,李姐万岁。完整代码请看本篇对应的[release][7],(只有release才是当前本篇文章对应的完整代码,当前repo状态不是)。下集预告----    实现get/set命令。  [1]: https://github.com/alphali/godis/releases/tag/0.0.1  [2]: /img/bVbb1C3  [3]: /img/bVbb1FT  [4]: https://github.com/alphali/godis/releases/tag/0.0.1  [5]: /img/bVbb2mA  [6]: /img/bVbb2nw

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.