第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

火了,忘了戈羅丁戈朗

火了,忘了戈羅丁戈朗

Go
POPMUISE 2022-09-12 20:31:39
我編寫了一個 API,用于進行數(shù)據(jù)庫調(diào)用并執(zhí)行一些業(yè)務(wù)邏輯。我正在調(diào)用一個必須在后臺執(zhí)行某些操作的戈魯廷。由于 API 調(diào)用不應(yīng)等待此后臺任務(wù)完成,因此我在調(diào)用 goroutine 后立即返回 200 OK(讓我們假設(shè)后臺任務(wù)永遠不會給出任何錯誤)。我讀到戈魯廷將在戈魯廷完成其任務(wù)后被終止。這種火災(zāi)和忘記遠離戈魯丁泄漏是安全的嗎?一旦戈魯廷執(zhí)行了工作,它們是否會被終止和清理?func DefaultHandler(w http.ResponseWriter, r *http.Request) {    // Some DB calls    // Some business logics    go func() {        // some Task taking 5 sec    }()    w.WriteHeader(http.StatusOK)}
查看完整描述

4 回答

?
慕田峪7331174

TA貢獻1828條經(jīng)驗 獲得超13個贊

我建議始終控制您的戈魯丁,以避免內(nèi)存和系統(tǒng)耗盡。如果您收到請求激增,并且開始不受控制地生成goroutines,則系統(tǒng)可能很快就會關(guān)閉。


在那些需要立即返回200Ok的情況下,最好的方法是創(chuàng)建一個消息隊列,因此服務(wù)器只需要在隊列中創(chuàng)建一個作業(yè)并返回ok和忘記。其余部分將由使用者異步處理。


創(chuàng)建者(HTTP 服務(wù)器)>>>隊列>>>使用者


通常,隊列是外部資源 (RabbitMQ, AWS SQS...),但出于教學(xué)目的,您可以使用與消息隊列相同的通道實現(xiàn)相同的效果。


在示例中,您將看到我們?nèi)绾蝿?chuàng)建一個通道來傳達 2 個進程。然后,我們啟動將從通道讀取的工作進程,然后使用將寫入通道的處理程序啟動服務(wù)器。


嘗試在發(fā)送 curl 請求時使用緩沖區(qū)大小和作業(yè)時間。


package main


import (

    "fmt"

    "log"

    "net/http"

    "time"

)


/*

$ go run .


curl "http://localhost:8080?user_id=1"

curl "http://localhost:8080?user_id=2"

curl "http://localhost:8080?user_id=3"

curl "http://localhost:8080?user_id=....."


*/


func main() {


    queueSize := 10

    // This is our queue, a channel to communicate processes. Queue size is the number of items that can be stored in the channel

    myJobQueue := make(chan string, queueSize) // Search for 'buffered channels'


    // Starts a worker that will read continuously from our queue

    go myBackgroundWorker(myJobQueue)


    // We start our server with a handler that is receiving the queue to write to it

    if err := http.ListenAndServe("localhost:8080", myAsyncHandler(myJobQueue)); err != nil {

        panic(err)

    }

}


func myAsyncHandler(myJobQueue chan<- string) http.HandlerFunc {

    return func(rw http.ResponseWriter, r *http.Request) {

        // We check that in the query string we have a 'user_id' query param

        if userID := r.URL.Query().Get("user_id"); userID != "" {

            select {

            case myJobQueue <- userID: // We try to put the item into the queue ...

                rw.WriteHeader(http.StatusOK)

                rw.Write([]byte(fmt.Sprintf("queuing user process: %s", userID)))

            default: // If we cannot write to the queue it's because is full!

                rw.WriteHeader(http.StatusInternalServerError)

                rw.Write([]byte(`our internal queue is full, try it later`))

            }

            return

        }

        rw.WriteHeader(http.StatusBadRequest)

        rw.Write([]byte(`missing 'user_id' in query params`))

    }

}


func myBackgroundWorker(myJobQueue <-chan string) {

    const (

        jobDuration = 10 * time.Second // simulation of a heavy background process

    )


    // We continuosly read from our queue and process the queue 1 by 1.

    // In this loop we could spawn more goroutines in a controlled way to paralelize work and increase the read throughput, but i don't want to overcomplicate the example.

    for userID := range myJobQueue {

        // rate limiter here ...

        // go func(u string){

        log.Printf("processing user: %s, started", userID)

        time.Sleep(jobDuration)

        log.Printf("processing user: %s, finisehd", userID)

        // }(userID)

    }

}


查看完整回答
反對 回復(fù) 2022-09-12
?
桃花長相依

TA貢獻1860條經(jīng)驗 獲得超8個贊

您無需處理“戈魯丁清理”,您只需啟動戈魯丁,當(dāng)作為戈魯廷返回的功能啟動時,它們將被清除。引用規(guī)范:圍棋聲明:

當(dāng)函數(shù)終止時,其戈魯廷也終止。如果函數(shù)具有任何返回值,則在函數(shù)完成時將丟棄這些返回值。

所以你所做的很好。但請注意,您啟動的 goroutine 不能使用或假定有關(guān)請求 () 和響應(yīng)編寫器 () 的任何內(nèi)容,您只能在從處理程序返回之前使用它們。rw

另請注意,您不必編寫 ,如果您從處理程序返回而不寫入任何內(nèi)容,則假定為成功并將自動發(fā)送回去。http.StatusOKHTTP 200 OK

查看相關(guān)/可能的重復(fù)項:在另一個戈魯廷上運行的 Webhook 進程


查看完整回答
反對 回復(fù) 2022-09-12
?
眼眸繁星

TA貢獻1873條經(jīng)驗 獲得超9個贊

沒有“戈魯丁清潔”,你可以使用網(wǎng)絡(luò)鉤子或像gocraft這樣的后臺工作。我能想到的使用你的解決方案的唯一方法是將同步包用于學(xué)習(xí)目的。


func DefaultHandler(w http.ResponseWriter, r *http.Request) {

// Some DB calls

// Some business logics

var wg sync.WaitGroup

wg.Add(1)

go func() {

  defer wg.Done()

    // some Task taking 5 sec

}()

w.WriteHeader(http.StatusOK)

wg.wait()

}


查看完整回答
反對 回復(fù) 2022-09-12
?
莫回?zé)o

TA貢獻1865條經(jīng)驗 獲得超7個贊

您可以等待戈魯廷完成使用:&sync.WaitGroup


// BusyTask

func BusyTask(t interface{}) error {

    var wg = &sync.WaitGroup{}


    wg.Add(1)

    go func() {

        // busy doing stuff

        time.Sleep(5 * time.Second)

        wg.Done()

    }()

    wg.Wait() // wait for goroutine


    return nil

}


// this will wait 5 second till goroutune finish

func main() {

    fmt.Println("hello")


    BusyTask("some task...")


    fmt.Println("done")

}

另一種方法是將 a 附加到戈魯丁并超時。context.Context


//

func BusyTaskContext(ctx context.Context, t string) error {

    done := make(chan struct{}, 1)

    //

    go func() {

        // time sleep 5 second

        time.Sleep(5 * time.Second)

        // do tasks and signle done

        done <- struct{}{}

        close(done)

    }()

    //

    select {

    case <-ctx.Done():

        return errors.New("timeout")

    case <-done:

        return nil

    }

}


//

func main() {

    fmt.Println("hello")


    ctx, cancel := context.WithTimeout(context.TODO(), 2*time.Second)

    defer cancel()


    if err := BusyTaskContext(ctx, "some task..."); err != nil {

        fmt.Println(err)

        return

    }


    fmt.Println("done")

}


查看完整回答
反對 回復(fù) 2022-09-12
  • 4 回答
  • 0 關(guān)注
  • 110 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號