Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit dc8cb17

Browse files
committed
MAke sure in-thread finally handlers are always called when appending chains
1 parent 737e52e commit dc8cb17

File tree

2 files changed

+29
-21
lines changed

2 files changed

+29
-21
lines changed

src/GitHub.Api/Git/RepositoryManager.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,15 @@ public int WaitForEvents()
186186

187187
public ITask CommitAllFiles(string message, string body)
188188
{
189-
var task = GitClient
190-
.AddAll()
189+
var task = GitClient.AddAll()
191190
.Then(GitClient.Commit(message, body));
192191

193192
return HookupHandlers(task, true);
194193
}
195194

196195
public ITask CommitFiles(List<string> files, string message, string body)
197196
{
198-
var task = GitClient
199-
.Add(files)
197+
var task = GitClient.Add(files)
200198
.Then(GitClient.Commit(message, body));
201199

202200
return HookupHandlers(task, true);
@@ -332,18 +330,9 @@ public ITask DiscardChanges(GitStatusEntry[] gitStatusEntries)
332330
}
333331
}
334332

335-
ITask<string> gitDiscardTask = null;
336333
if (itemsToRevert.Any())
337334
{
338-
gitDiscardTask = GitClient.Discard(itemsToRevert);
339-
task.Then(gitDiscardTask)
340-
// we're appending a new continuation after HookupHandlers has run,
341-
// we need to set the finally handler manually so it runs at the end of everything
342-
.Finally(s =>
343-
{
344-
watcher.Start();
345-
isBusy = false;
346-
});
335+
task.Then(GitClient.Discard(itemsToRevert));
347336
}
348337
}
349338
, () => gitStatusEntries);

src/GitHub.Api/Tasks/TaskBase.cs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using GitHub.Logging;
22
using System;
3+
using System.Collections.Generic;
34
using System.Threading;
45
using System.Threading.Tasks;
56

@@ -160,6 +161,7 @@ public virtual T Then<T>(T nextTask, TaskRunOptions runOptions = TaskRunOptions.
160161
nextTaskBase = nextTaskBase.GetTopMostTask() ?? nextTaskBase;
161162
// make the next task dependent on this one so it can get values from us
162163
nextTaskBase.SetDependsOn(this);
164+
var nextTaskFinallyHandler = nextTaskBase.finallyHandler;
163165

164166
if (runOptions == TaskRunOptions.OnSuccess)
165167
{
@@ -173,8 +175,8 @@ public virtual T Then<T>(T nextTask, TaskRunOptions runOptions = TaskRunOptions.
173175
SetFaultHandler(nextTaskBase.continuationOnAlways);
174176
if (nextTaskBase.catchHandler != null)
175177
Catch(nextTaskBase.catchHandler);
176-
if (nextTaskBase.finallyHandler != null)
177-
Finally(nextTaskBase.finallyHandler);
178+
if (nextTaskFinallyHandler != null)
179+
Finally(nextTaskFinallyHandler);
178180
}
179181
else if (runOptions == TaskRunOptions.OnFailure)
180182
{
@@ -186,6 +188,18 @@ public virtual T Then<T>(T nextTask, TaskRunOptions runOptions = TaskRunOptions.
186188
this.continuationOnAlways = nextTaskBase;
187189
DependsOn?.SetFaultHandler(nextTaskBase);
188190
}
191+
192+
// if the current task has a fault handler, attach it to the chain we're appending
193+
if (finallyHandler != null)
194+
{
195+
var endOfChainTask = nextTaskBase.GetBottomMostTask();
196+
while (endOfChainTask != this && endOfChainTask != null)
197+
{
198+
endOfChainTask.finallyHandler += finallyHandler;
199+
endOfChainTask = endOfChainTask.DependsOn;
200+
}
201+
}
202+
189203
return nextTask;
190204
}
191205

@@ -240,11 +254,7 @@ public ITask Finally(Action<bool, Exception> actionToContinueWith, TaskAffinity
240254
public T Finally<T>(T taskToContinueWith)
241255
where T : ITask
242256
{
243-
Guard.ArgumentNotNull(taskToContinueWith, nameof(taskToContinueWith));
244-
continuationOnAlways = (TaskBase)(object)taskToContinueWith;
245-
continuationOnAlways.SetDependsOn(this);
246-
DependsOn?.SetFaultHandler(continuationOnAlways);
247-
return taskToContinueWith;
257+
return Then(taskToContinueWith, TaskRunOptions.OnAlways);
248258
}
249259

250260
/// <summary>
@@ -363,6 +373,15 @@ protected TaskBase GetTopMostTask()
363373
return depends.GetTopMostTask(null, false);
364374
}
365375

376+
protected TaskBase GetBottomMostTask()
377+
{
378+
if (continuationOnSuccess != null)
379+
return continuationOnSuccess.GetBottomMostTask();
380+
else if (continuationOnAlways != null)
381+
return continuationOnAlways.GetBottomMostTask();
382+
return this;
383+
}
384+
366385
protected TaskBase GetTopMostTask(TaskBase ret, bool onlyCreatedState)
367386
{
368387
ret = (!onlyCreatedState || Task.Status == TaskStatus.Created ? this : ret);

0 commit comments

Comments
 (0)