package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
defer fmt.Println("Finished")
fmt.Println("Hello world")
var results = requestAll([]string{"http://test.com", "http://test2.com"})
for _, result := range results {
fmt.Printf("Result: %s\n", result)
}
}
func mockHTTPRequest(url string) string {
timeDelay := rand.Intn(3000)
time.Sleep(time.Duration(timeDelay) * time.Millisecond)
return fmt.Sprintf("OK: Request %s %d ms\n", url, timeDelay)
}
func requestAll(urls []string) []string {
var length = len(urls)
requests := make(chan string, length)
defer close(requests)
// Use goroutine to send multiple time-consuming jobs to the channel.
for _, url := range urls {
go func(url2 string) {
requests <- mockHTTPRequest(url2)
}(url)
}
var responses = make([]string, 0, length)
for i := 0; i < length; i++ {
var response = <-requests
responses = append(responses, response)
}
return responses
}
Extended example:
package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
type Download interface {
getFile() string
getUrl() string
getDuration() time.Duration
setDuration(value time.Duration)
getError() error
setError(value error)
}
type DownloadInfo struct {
file string
url string
err error
duration time.Duration
}
func (r *DownloadInfo) getFile() string {
return r.file
}
func (r *DownloadInfo) getUrl() string {
return r.url
}
func (r *DownloadInfo) setDuration(value time.Duration) {
r.duration = value
}
func (r *DownloadInfo) getDuration() time.Duration {
return r.duration
}
func (r *DownloadInfo) setError(value error) {
r.err = value
}
func (r *DownloadInfo) getError() error {
return r.err
}
func createDownload(url string, file string) *DownloadInfo {
return &DownloadInfo{
url: url,
file: file,
duration: 0,
}
}
func main() {
defer fmt.Println("Finished")
fmt.Println("Hello world")
var data = []Download{
createDownload("https://download.visualstudio.microsoft.com/download/pr/15ab772d-ce5c-46e5-a90e-57df11adabfb/4b1b1330b6279a50c398f94cf716c71e/dotnet-sdk-6.0.301-win-x64.exe", "dotnet-sdk-6.0.301-win-x64.exe"),
createDownload("https://download.visualstudio.microsoft.com/download/pr/7989338b-8ae9-4a5d-8425-020148016812/c26361fde7f706279265a505b4d1d93a/dotnet-runtime-6.0.6-win-x64.exe", "dotnet-runtime-6.0.6-win-x64.exe"),
createDownload("https://download.visualstudio.microsoft.com/download/pr/test", "fail.txt"),
}
var results = requestAll(data)
for _, result := range results {
var err = result.getError()
if err != nil {
fmt.Printf("Result: %s -X %s\n", result.getUrl(), err)
} else {
fmt.Printf("Result: %s -> %s : %s\n", result.getUrl(), result.getFile(), result.getDuration())
}
}
}
func startDownload(d Download) Download {
var start = time.Now()
fmt.Printf("Start: %s\n", d.getUrl())
resp, err := http.Get(d.getUrl())
if err != nil {
// setErr(err)
return d
}
defer resp.Body.Close()
var success = resp.StatusCode >= 200 && resp.StatusCode < 400
if !success {
d.setError(fmt.Errorf("Failed with exit code %d", resp.StatusCode))
return d
}
out, err := os.Create(d.getFile())
if err != nil {
return d
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
return d
}
var elapsed = time.Since(start)
d.setDuration(elapsed)
fmt.Printf("End: %s : %s s\n", d.getUrl(), elapsed)
return d
}
func requestAll(downloads []Download) []Download {
var length = len(downloads)
requests := make(chan Download, length)
defer close(requests)
// Use goroutine to send multiple time-consuming jobs to the channel.
for _, d := range downloads {
go func(d2 Download) {
requests <- startDownload(d2)
}(d)
}
var responses = make([]Download, 0, length)
for i := 0; i < length; i++ {
var response = <-requests
responses = append(responses, response)
}
return responses
}
627900cookie-checkGo Simple ‘Async’ function