@@ -24,12 +24,12 @@ type BlamePart struct {
2424
2525// BlameReader returns part of file blame one by one
2626type BlameReader struct {
27- cmd * exec.Cmd
28- pid int64
29- output io. ReadCloser
30- reader * bufio. Reader
31- lastSha * string
32- cancel context. CancelFunc
27+ cmd * exec.Cmd
28+ output io. ReadCloser
29+ reader * bufio. Reader
30+ lastSha * string
31+ cancel context. CancelFunc // Cancels the context that this reader runs in
32+ finished process. FinishedFunc // Tells the process manager we're finished and it can remove the associated process from the process table
3333}
3434
3535var shaLineRegex = regexp .MustCompile ("^([a-z0-9]{40})" )
@@ -100,8 +100,8 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
100100
101101// Close BlameReader - don't run NextPart after invoking that
102102func (r * BlameReader ) Close () error {
103- defer process . GetManager (). Remove ( r . pid )
104- r .cancel ()
103+ defer r . finished () // Only remove the process from the process table when the underlying command is closed
104+ r .cancel () // However, first cancel our own context early
105105
106106 _ = r .output .Close ()
107107
@@ -114,7 +114,7 @@ func (r *BlameReader) Close() error {
114114
115115// CreateBlameReader creates reader for given repository, commit and file
116116func CreateBlameReader (ctx context.Context , repoPath , commitID , file string ) (* BlameReader , error ) {
117- gitRepo , err := OpenRepository ( repoPath )
117+ gitRepo , err := OpenRepositoryCtx ( ctx , repoPath )
118118 if err != nil {
119119 return nil , err
120120 }
@@ -125,32 +125,31 @@ func CreateBlameReader(ctx context.Context, repoPath, commitID, file string) (*B
125125
126126func createBlameReader (ctx context.Context , dir string , command ... string ) (* BlameReader , error ) {
127127 // Here we use the provided context - this should be tied to the request performing the blame so that it does not hang around.
128- ctx , cancel := context .WithCancel (ctx )
128+ ctx , cancel , finished := process .GetManager ().AddContext (ctx , fmt .Sprintf ("GetBlame [repo_path: %s]" , dir ))
129+
129130 cmd := exec .CommandContext (ctx , command [0 ], command [1 :]... )
130131 cmd .Dir = dir
131132 cmd .Stderr = os .Stderr
132133
133134 stdout , err := cmd .StdoutPipe ()
134135 if err != nil {
135- defer cancel ()
136+ defer finished ()
136137 return nil , fmt .Errorf ("StdoutPipe: %v" , err )
137138 }
138139
139140 if err = cmd .Start (); err != nil {
140- defer cancel ()
141+ defer finished ()
142+ _ = stdout .Close ()
141143 return nil , fmt .Errorf ("Start: %v" , err )
142144 }
143145
144- pid := process .GetManager ().Add (fmt .Sprintf ("GetBlame [repo_path: %s]" , dir ), cancel )
145-
146146 reader := bufio .NewReader (stdout )
147147
148148 return & BlameReader {
149- cmd ,
150- pid ,
151- stdout ,
152- reader ,
153- nil ,
154- cancel ,
149+ cmd : cmd ,
150+ output : stdout ,
151+ reader : reader ,
152+ cancel : cancel ,
153+ finished : finished ,
155154 }, nil
156155}
0 commit comments