0

このスケジューラーを作成しましたが、入力時間間隔よりも時間がかかるf場合にその入力関数を「kill」することができません。frecurring

それfがスレッドではなくプロセスである場合、私が探しているのは、ある種の定義済みのハード プリエンプションである可能性があります。

そのf定義は、私が制御できないものです。これは、バッチ実行中に複数のデータベースからデータを処理する ETL ジョブを表しています。それfは書かれてgoおり、正常に動作しますが、実行に時間がかかりすぎる何らかの制御が必要です。

fはアトミックであることを知っているので、実行の最後にデータベースを変更するかどうかのどちらかです。したがって、時間がかかりすぎる場合は、「殺す」のが安全であると見なすことができます。

func schedule(f func(), recurring time.Duration) chan struct{} {
    ticker := time.NewTicker(recurring)
    quit := make(chan struct{})
    go func(inFunc func()) {
        for {
            select {
            case <-ticker.C:
                fmt.Println("Ticked")
                // when "go" is removed, then if "f()" takes
                // more than "recurring", then it postpones
                // the following executions of "f()"
                //
                // instead somehow it should be "killed"
                // 
                // check the timestamps in the execution of the test
                go inFunc()
            case <-quit:
                fmt.Println("Stopping the scheduler")
                ticker.Stop()
                return
            }
        }
    }(f)

    return quit
}

何が起こっているかを見るために、私はこのテストを書きました:

func TestSlowExecutions(t *testing.T) {
    // log some information using a human readable timestamp
    dummyLog := func(format string, a ...interface{}) (n int, err error) {
        prefix := fmt.Sprintf("[%v] ", time.Now())
        message := fmt.Sprintf(format, a...)
        return fmt.Printf("%s%s\n", prefix, message)
    }

    // UUID to be able to uniquely identify "fooFunc"
    newUuid := func() string {
        // sudo apt-get install uuid-runtime
        uuid, _ := exec.Command("uuidgen").Output()

        re := regexp.MustCompile(`\r?\n`)
        uuidStr := re.ReplaceAllString(string(uuid), "")
        return uuidStr
    }

    // simulate some sort of very slow execution
    fooFunc := func() {
        uuid := newUuid()
        dummyLog("Ticked")
        dummyLog("Starting task %s", uuid)
        time.Sleep(2 * time.Second)
        dummyLog("Finished task %s", uuid)
    }

    // test the very slow execution of "fooFunc"
    quitChan := schedule(fooFunc, 1*time.Second)

    time.Sleep(4 * time.Second)
    close(quitChan)
    // wait more to see the "closing" message
    time.Sleep(4 * time.Second)
}
4

1 に答える 1