2016-08-28 4 views
1

Ich versuche herauszufinden, wie mit dem Kontextmuster in Go gearbeitet wird. Ich simuliere den Fall, wenn mehrere lang laufende Child-Gououtines wegen Timeout ihrer Ausführung abgebrochen werden müssen. Wie ich verstanden habe, besteht einer der Hauptnutzungen des Kontextes darin, alle Kindprozesse im Falle eines I/O-Timeouts zu stoppen oder wenn der Benutzer die Seite vor dem Ende der Verarbeitung verlässt.Abbrechen der Ausführung von untergeordneten Prozessen mithilfe des Kontexts

Mein Code:

package main 

import (
    "context" 
    "fmt" 
    "time" 
) 

func doIt(ctx context.Context, filename string) { 
    // simulate not ending file processing - 
    // internals of this loop could not change 
    // e.g. it is call of some third party or stdlib function that hangs 
    for { 
     fmt.Printf("processing file %s\n", filename) 
     time.Sleep(50 * time.Millisecond) 
    } 
} 

func main() { 
    startFileProcessing() 
    fmt.Println("End of processing") 
    time.Sleep(500 * time.Millisecond) 
    fmt.Println("Do something else") 

} 

func startFileProcessing() { 
    // set file processing timeout 
    ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*100) 
    defer cancel() 

    // start two parallel processes 
    go doIt(ctx, "file1") 
    go doIt(ctx, "file2") 

    select { 
    case <-ctx.Done(): 
     fmt.Println("file processing timeout") 
     return 
    } 
} 

Playground.

Welche Ausgänge:

processing file file2 
processing file file1 
processing file file1 
processing file file2 
processing file file1 
file processing timeout 
End of processing 
processing file file2 
processing file file2 
processing file file1 
processing file file1 
processing file file2 
Do something else 

Ich erwarte nicht, um zu sehen, "Verarbeitungsdatei" Zeilen nach "Dateiverarbeitung timeout".

Wie es zu beheben?

Bearbeiten: @ Mellow Marmot wies darauf hin, dass der Kontext Kindergououtines nicht auf eigene Faust und vorgeschlagene Lösung für diese zu stoppen. Aber seine Änderungen sind innerhalb der Schleife in doIt Funktion, die die Frage nicht vollständig beantwortet, weil anstelle von Schleife in doIt Funktion könnte es einige Third Party (oder StdLib) Funktionsaufruf, der nicht geändert werden konnte.

Also lassen Sie mich Frage umformulieren -

Wie einige lange laufenden Prozesse zu Interna von denen kündige ich keinen Zugang haben - die für mehr Zeit als Timeout hängt?

Antwort

3

Der Kontext stoppt Kindergououtines nicht von selbst. Der Anwendungscode, der in den Goroutinen ausgeführt wird, muss den Kontext überprüfen und von der Goroutine zurückkehren, wenn der Kontext abgeschlossen ist. Hier ist ein Beispiel dafür, wie der Kontext zu überprüfen:

func doIt(ctx context.Context, filename string) { 
    // simulate not ending file processing 
    for { 
    fmt.Printf("processing file %s\n", filename) 
    time.Sleep(50 * time.Millisecond) 
    select { 
    case <-ctx.Done(): 
     return 
    default: 
    } 
    } 
} 

playground example

Es ist nicht möglich, einen langen Lauf goroutine abzubrechen, wenn die Ausführung von Code in der goroutine einen Mechanismus so zu tun gibt. Es gibt keinen Mechanismus zum Töten einer Goroutine außerhalb des Codes, der in der Goroutine ausgeführt wird.

+0

danke. Aber der erste Loop-Zyklus sperrt die Zeile "case <-ctx.Done():", bis das Timing abgelaufen ist - das erwarte ich nicht. Ändern Sie es in Wählen Sie { Fall <-ctx.Done(): zurück Standard: } behebt diesen Fehler. – sev3ryn

+0

, aber, wie man einige lang laufende Prozesse zu Internals annulliere, von denen ich keinen Zugang habe - lässt sagen, dass anstelle der Funktion doIt einige Third Party oder stdlib Funktion - für mehr Zeit als Zeitüberschreitung hängt. – sev3ryn

+1

@ sev3ryn Es ist nicht möglich, eine lange laufende Goroutine abzubrechen, es sei denn, der Code, der in der Goroutine ausgeführt wird, bietet einen Mechanismus, um dies zu tun. Es gibt keinen Mechanismus zum Töten einer Goroutine außerhalb des Codes, der in der Goroutine ausgeführt wird. –

Verwandte Themen