Using go to implement asynchronous Web development

Source: Internet
Author: User
Tags key string
This is a creation in Article, where the information may have evolved or changed.

I wonder if you remember, about a year ago, my daydream about Web programming async model, and then this daydream I've been doing for days. PHP native implementation of Web programming asynchronous model, Gearman implementation of Web programming asynchronous Model (remnant).

At that time there is no connection, but also die Pibarai sticky in the asynchronous implementation of PHP refused to let go. Well, the implementation is cumbersome, the application is successful, the code is easy to write, the environment is to build ...

Before going to bed last night, I suddenly felt that I should really use go to implement the asynchronous Web, even if it is a good example. So, while eating, while knocking a ticket code made a very simple demo, share to everyone. Download the full code here: Webdemo.

Contains the following files:

    • async.go--Asynchronous Web
    • data.go--Analog Data
    • makefile--don't say, you know ...
    • page.go--page
    • sync.go--synchronizing the Web
    • timer.go--Logging of execution time
    • webdemo.go--Master File

Compile and run

Make run

Through the browser to access the synchronization mode of Http://127.0.0.1:8888/sync, and asynchronous mode of Http://127.0.0.1:8888/async. In the console will output the length of the request processing, in fact, even if you do not look at the statistical length, the speed difference between the two is very intuitive to understand.

mikespook@mikespook-desktop:~/desktop/webdemo$ make Run8g-o _go_.8 timer.go data.go page.go async.go sync.go rm-f _obj/w Ebdemo.agopack GRC _OBJ/WEBDEMO.A _go_.8 cp _obj/webdemo.a "/HOME/MIKESPOOK/BIN/GO/PKG/LINUX_386/WEBDEMO.A" 8g Webdemo.go8l-o webdemo webdemo.8./webdemo2011/03/25 15:06:35 async:2286230002011/03/25 15:06:57 sync:20024992000

The core idea is simple, I use time in the code of the mock data request. Sleep (), which allows each data request to be delayed by 0.2 seconds (a bad query time for a poorly tuned, large database table):

Data.gofunc getcontents (Key String) string {time    . Sleep//Delay    return to FMT. Sprintf ("%s. The quick brown fox jumps over the lazy dog. ", Key)}

For synchronous data requests, you must wait for the last data request to complete before the next data request is initiated (as the original PHP is), so if 100 data requests for 0.2 seconds, the final time will be greater than 20 seconds.
The following is a request for 100 data processing:

Webdemo.go Synchronous Data request Func SyncHandler (w http. Responsewriter, R *http. Request) {    timer: = Webdemo. Newtimer ("Sync")    defer timer. End ()    page: = Webdemo. Newsyncpage () for    I: = 0; i < +, i + + {        key: = StrConv. Itoa (i)        page. Setcontents (key)    }    page. Render (W)}

Here's how to get the data to the page and render the page output to HTTP. Methods of Resonsewriter:

Sync.gofunc (page *syncpage) setcontents (key string) {    Page.contents[key] = getcontents (key)}func (page *syncpage ) Render (w http. Responsewriter) {    lines: = "" For    I: = 0; I < Len (page.contents); i++ {        Key: = StrConv. Itoa (i)        lines + = Fmt. Sprintf (Template_line, Page.contents[key])    }    Block: = FMT. Sprintf (Template_block, lines)    FMT. fprintf (W, template_page, Block)}

For async, the total length of time is slightly greater than the length of a single data request. Here is the handler code of the asynchronous request, in fact, there is no difference with synchronization.

Webdemo.go Asynchronous Handlerfunc Asynchandler (w http. Responsewriter, R *http. Request) {    timer: = Webdemo. Newtimer ("async")    defer timer. End ()    page: = Webdemo. Newasyncpage ()    page. countout =    i:= 0; i < page. countout; i++ {        Key: = StrConv. Itoa (i)        page. Setcontents (key)    }    page. Render (W)}

In order to achieve asynchronous data acquisition, in the Async.go code, the Go language is used to implement the powerful channel. So defining a contents in the Asyncpage structure is Chan.

async.go//page Content Type asynccontents struct {    key, Value string}//page type asyncpage struct {    contents chan ASYNCC Ontents    Timeout chan bool    countout int    page Page}

In the Setcontents method of the Async page, use the GO keyword to create a goroutines to enter into Chan. Also establish another goroutines as timeout (in this case, timeout is not present, but this is necessary in the real world).

Async.gofunc (page *asyncpage) setcontents (key string) {    //asynchronous data Get    go func () {        page.contents <-ASYNCC Ontents{key, getcontents (Key)}    } ()    //Set timeout for page    go func () {Time        . Sleep (TIMEOUT)        page.timeout <-True    } ()}

The rendering of the page is also different from the way it was synchronized, with select to remove the data from Chan and render to the template.

Async.gofunc (page *asyncpage) Render (w http. Responsewriter) {    lines: = ""    loop:for I: = 0; I < page. countout; i++{        Select {Case line            : = <-page.contents:                lines = FMT. Sprintf ("%s" + Template_line, lines, line.value)                //each fetch a data, remove a timeout                go func () {<-page.timeout} () Case            <-page.timeout:                lines = FMT. Sprintf ("%s" + Template_line, lines, "Time Out") Break                LOOP        }    }    block: = FMT. Sprintf (Template_block, lines)    FMT. fprintf (W, template_page, Block)}

To demonstrate the structure of async, I didn't use a template to render the page. But it's pretty much a template to render: Asynchronously gets a variable called%varn on the template, and then renders the data collection to the template ...

The situation can be complicated when data acquisition is dependent, but if the Web page is treated as a tree (DOM tree? ), it's a good idea to get asynchronous data from a leaf node and push it up one layer at a point.

Related Article

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.