iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 4
2

3: Frontend/Backend Protocol

2018/10/18

It's recommended to read on Gitbook for better experience.

StellarSQL is a relational DBMS (RDBMS). Usually, RDBMS is 2-tier client/server architecture, which includes a server and a client. A client might be any devices which wants to access databases, and a server is running a DBMS for handling requests from clients.

There must be a protocol between client and server, in order to communication and data transmission. MySQL and PostgreSQL apply message stream communication as their protocol. MySQL and PostgreSQL do talk about protocol on their document:

Of course, you can also use HTTP protocol. Firebase is a NoSQL cloud database, and clients send HTTP requests for querying data. However HTTP is somehow too "fat" for the purpose of data querying, so message stream might be suitable in the case of DBMS.

Now, we can start to develop a little about Tokio.rs for StellarSQL, which we talked about on yesterday.

Create server

Based on the reason above, I would also use message stream communication as the protocol for StellarSQL.

I will think about the detail of the protocol in the following days. But now, we can implement the part of TCP stream by using Tokio.rs first.

We create a server first:

!FILENAME src/main.rs

    let addr = format!("127.0.0.1:{}", port).parse().unwrap();

    // Bind a TCP listener to the socket address.
    // Note that this is the Tokio TcpListener, which is fully async.
    let listener = TcpListener::bind(&addr).unwrap();

    // The server task asynchronously iterates over and processes each
    // incoming connection.
    let server = listener
        .incoming()
        .for_each(move |socket| {
            // Spawn a task to process the connection
            // TODO process()
            Ok(())
        }).map_err(|err| {
            println!("accept error = {:?}", err);
        });

    tokio::run(server);
    println!("StellarSQL running on {} port", port);

Continue to the day before yesterday, we let address use the port from arguments or configuration. So the server will serve at 127.0.0.1:PORT.

Then we let server listen to any sockets input from connections. For servers or DBMS, it is always that clients ask requests and servers answer responses. So, you could see there is a listener that will handles any sockets, which I remain it as TODO.

Finally, we run the server with tokio::run(server). According to the document, the Tokio is a pre-configured "out of the box" runtime for building asynchronous applications. It includes both a reactor and a task scheduler. This means applications are multi-threaded by default. In this case, we just use the default setting by Tokio.

Message

I also define the Message for message streaming. The Message struct is really basic and straightforward now. I will finish it and define the protocol in the following days. Then, we could use it for client/server communication later.

pub struct Message {
    /// The TCP socket.
    socket: TcpStream,

    /// Buffer used when reading from the socket. Data is not returned from this
    /// buffer until an entire message has been read.
    rd: BytesMut,

    /// Buffer used to stage data before writing it to the socket.
    wr: BytesMut,
}

impl Message {
    /// Create a new `Message` codec backed by the socket
    fn new(socket: TcpStream) -> Self {
        Message {
            socket,
            rd: BytesMut::new(),
            wr: BytesMut::new(),
        }
    }
}

Quick Link
1.StellarSQL Repository
2.Gitbook of this series

Author
Liu, An-Chi (劉安齊). A software engineer, who loves writing code and promoting CS to people. Welcome to follow me at Facebook Page. More information on Personal Site and Github.


上一篇
StellarSQL 2: Basic Concept of Server
下一篇
StellarSQL 4: Client/Server Communication Implementation
系列文
Let's build a DBMS: StellarSQL -- a minimal SQL DBMS written in Rust30

1 則留言

0
SunAllen
iT邦高手 1 級 ‧ 2018-10-19 12:50:04

大大,您這系列作品,第一篇連結,請讓我分享到我的臉書介紹一下...感謝您!

當然好啊哈哈哈

我要留言

立即登入留言