]> source.dussan.org Git - gitea.git/commitdiff
Clarify the git command Stdin hanging problem (#26967)
authorwxiaoguang <wxiaoguang@gmail.com>
Fri, 8 Sep 2023 13:20:38 +0000 (21:20 +0800)
committerGitHub <noreply@github.com>
Fri, 8 Sep 2023 13:20:38 +0000 (13:20 +0000)
modules/git/command.go
modules/indexer/code/indexer.go

index c38fd046966717d5807ccbb1ca091604e65ead99..f095bb18bef75f72b87bdf0beeb3c17e9b641ca2 100644 (file)
@@ -221,8 +221,18 @@ type RunOpts struct {
        Dir string
 
        Stdout, Stderr io.Writer
-       Stdin          io.Reader
-       PipelineFunc   func(context.Context, context.CancelFunc) error
+
+       // Stdin is used for passing input to the command
+       // The caller must make sure the Stdin writer is closed properly to finish the Run function.
+       // Otherwise, the Run function may hang for long time or forever, especially when the Git's context deadline is not the same as the caller's.
+       // Some common mistakes:
+       // * `defer stdinWriter.Close()` then call `cmd.Run()`: the Run() would never return if the command is killed by timeout
+       // * `go { case <- parentContext.Done(): stdinWriter.Close() }` with `cmd.Run(DefaultTimeout)`: the command would have been killed by timeout but the Run doesn't return until stdinWriter.Close()
+       // * `go { if stdoutReader.Read() err != nil: stdinWriter.Close() }` with `cmd.Run()`: the stdoutReader may never return error if the command is killed by timeout
+       // In the future, ideally the git module itself should have full control of the stdin, to avoid such problems and make it easier to refactor to a better architecture.
+       Stdin io.Reader
+
+       PipelineFunc func(context.Context, context.CancelFunc) error
 }
 
 func commonBaseEnvs() []string {
index 80bde7614f2b15c35aa8dfa9b2f9c1eb5c75eb1c..019773fe514b9e650a871174464618537ede5c9f 100644 (file)
@@ -122,21 +122,6 @@ func Init() {
                        indexer := *globalIndexer.Load()
                        for _, indexerData := range items {
                                log.Trace("IndexerData Process Repo: %d", indexerData.RepoID)
-
-                               // FIXME: it seems there is a bug in `CatFileBatch` or `nio.Pipe`, which will cause the process to hang forever in rare cases
-                               /*
-                                       sync.(*Cond).Wait(cond.go:70)
-                                       github.com/djherbis/nio/v3.(*PipeReader).Read(sync.go:106)
-                                       bufio.(*Reader).fill(bufio.go:106)
-                                       bufio.(*Reader).ReadSlice(bufio.go:372)
-                                       bufio.(*Reader).collectFragments(bufio.go:447)
-                                       bufio.(*Reader).ReadString(bufio.go:494)
-                                       code.gitea.io/gitea/modules/git.ReadBatchLine(batch_reader.go:149)
-                                       code.gitea.io/gitea/modules/indexer/code.(*BleveIndexer).addUpdate(bleve.go:214)
-                                       code.gitea.io/gitea/modules/indexer/code.(*BleveIndexer).Index(bleve.go:296)
-                                       code.gitea.io/gitea/modules/indexer/code.(*wrappedIndexer).Index(wrapped.go:74)
-                                       code.gitea.io/gitea/modules/indexer/code.index(indexer.go:105)
-                               */
                                if err := index(ctx, indexer, indexerData.RepoID); err != nil {
                                        unhandled = append(unhandled, indexerData)
                                        if !setting.IsInTesting {