Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

when lots of io requset running,the other requests will wait #1932

Open
meiyang1123 opened this issue Jun 6, 2019 · 2 comments
Open

when lots of io requset running,the other requests will wait #1932

meiyang1123 opened this issue Jun 6, 2019 · 2 comments

Comments

@meiyang1123
Copy link

meiyang1123 commented Jun 6, 2019

  • go version: go1.12.2
  • gin version (or commit ref):
  • operating system: windows/amd64

Description

A Testing
run gin server with code

func main() {
	gin.SetMode(gin.ReleaseMode)
	r := gin.New()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{"message": "ping"})
	})
	r.GET("/wait10s", func(c *gin.Context) {
		time.Sleep(time.Second * 10)
		c.JSON(200, gin.H{"message": " 10s"})
	})
	r.GET("/download", func(c *gin.Context) {
               // a 5.85Mb file
		c.File(`D:\Project\awesomeProject\asset\SyncBaseInfo_1552615252.zip`)
	})
	r.Run() // listen and serve on 0.0.0.0:8080
}

and then request to the server with code

// requset.go
func get(url string, d time.Duration) {
	start := time.Now()
	resp, err := http.Get(url)
	if err != nil {
		fmt.Println(err.Error())
	} 
	defer resp.Body.Close()
	_, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err.Error())
	}
	d2 := time.Now().Sub(start)
	if d2 > d {
		fmt.Println(url, d2)
	}
}

func main() {
	sysGroup := sync.WaitGroup{}
	for i := 10; i < 50; i++ {
		go func() {
			sysGroup.Add(1)
			get("http://localhost:8080/wait10s", time.Millisecond*1000)
			sysGroup.Done()
		}()
	}

	for i := 0; i < 100; i++ {
		go func() {
			sysGroup.Add(1)
			get("http://localhost:8080/download", time.Millisecond*50)
			sysGroup.Done()
		}()

	}
	time.Sleep(time.Millisecond * 20)
	for i := 0; i < 100; i++ {
		go func() {
			sysGroup.Add(1)
			get("http://localhost:8080/ping", time.Millisecond*1)
			sysGroup.Done()
		}()
	}
	sysGroup.Wait()
}

when request.go run at first time,ping request will back before download request,when request.go run again,ping request will back after download .
image
Run server with go http ,the problem does not appear。

// run with package http
func IndexHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "hello world")
}

func waitHandler(w http.ResponseWriter, r *http.Request) {
	time.Sleep(time.Second * 10)
	fmt.Fprintln(w, "hello world")
}
func DownHandler(writer http.ResponseWriter, request *http.Request) {
	reader, err := os.Open(`D:\Project\awesomeProject\asset\SyncBaseInfo_1552615252.zip`)
	if err != nil || reader == nil {
		writer.Write([]byte("error !!"))
		return
	}
	defer reader.Close()
	http.ServeContent(writer, request, "heeh", time.Now(), reader)

}
func listenSignal() {
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	select {
	case <-sigs:
		fmt.Println("exitapp,sigs:", sigs)
		os.Exit(0)
	}
}
func main() {
	go func() {
		http.HandleFunc("/ping", IndexHandler)

		http.HandleFunc("/download", DownHandler)
		http.HandleFunc("/wait10s", waitHandler)
		http.ListenAndServe("0.0.0.0:8080", nil)
		fmt.Println(222222222222222)
	}()

	listenSignal()
}

@thinkerou
Copy link
Member

thinkerou commented Jun 6, 2019

@meiyang1123 please update your example, please see https://github.com/golang/go/blob/master/src/sync/example_test.go#L29, thanks!
please update and check, or else reopen.
now closing. thanks!

@meiyang1123
Copy link
Author

I update and check again, got the same result。

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"sync"
	"time"
)

func get(url string) {
	start := time.Now()
	resp, err := http.Get(url)
	if err != nil {
		fmt.Println(err.Error())
	}
	defer resp.Body.Close()
	_, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err.Error())
	}
	d2 := time.Now().Sub(start)
	fmt.Println(url, d2)

}

func main() {
	sysGroup := sync.WaitGroup{}
	var urls = []string{
		"http://localhost:8080/wait10s",
		"http://localhost:8080/download",
		"http://localhost:8080/ping",
	}
	for i := 0; i < 50; i++ {
		for _, url := range urls {
			sysGroup.Add(1)
			go func(url string) {
				defer sysGroup.Done()
				get(url)
			}(url)
		}

	}
	sysGroup.Wait()
}

Result:
image

I hope you can help me.

@thinkerou thinkerou reopened this Jun 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants