提交 f1805483 编写于 作者: D Don Syme 提交者: Kevin Ransom (msft)

Cancel background work (#3063)

* cleanup

* cleanup

* diagnostics

* cleanup diagnostics

* even cleaner diagnostics

* cleanup diagnostics

* default tuning

* adjust tuning, more logging

* add test, fix whitespace

* cancel background steps

* reduce changes
上级 b4c4d622
......@@ -19,7 +19,7 @@ type internal IReactorOperations =
[<NoEquality; NoComparison>]
type internal ReactorCommands =
/// Kick off a build.
| SetBackgroundOp of ( (* userOpName: *) string * (* opName: *) string * (* opArg: *) string * (CompilationThreadToken -> bool)) option
| SetBackgroundOp of ( (* userOpName: *) string * (* opName: *) string * (* opArg: *) string * (CompilationThreadToken -> CancellationToken -> bool)) option
/// Do some work not synchronized in the mailbox.
| Op of userOpName: string * opName: string * opArg: string * CancellationToken * (CompilationThreadToken -> unit) * (unit -> unit)
/// Finish the background building
......@@ -39,6 +39,7 @@ type Reactor() =
// so that when the reactor picks up a thread from the threadpool we can set the culture
let culture = new CultureInfo(CultureInfo.CurrentUICulture.Name)
let mutable bgOpCts = new CancellationTokenSource()
/// Mailbox dispatch function.
let builder =
MailboxProcessor<_>.Start <| fun inbox ->
......@@ -74,6 +75,7 @@ type Reactor() =
| Some (SetBackgroundOp bgOpOpt) ->
//Trace.TraceInformation("Reactor: --> set background op, remaining {0}", inbox.CurrentQueueLength)
return! loop (bgOpOpt, onComplete, false)
| Some (Op (userOpName, opName, opArg, ct, op, ccont)) ->
if ct.IsCancellationRequested then ccont() else
Trace.TraceInformation("Reactor: {0:n3} --> {1}.{2} ({3}), remaining {4}", DateTime.Now.TimeOfDay.TotalSeconds, userOpName, opName, opArg, inbox.CurrentQueueLength)
......@@ -92,13 +94,21 @@ type Reactor() =
| None -> ()
| Some (bgUserOpName, bgOpName, bgOpArg, bgOp) ->
Trace.TraceInformation("Reactor: {0:n3} --> wait for background {1}.{2} ({3}), remaining {4}", DateTime.Now.TimeOfDay.TotalSeconds, bgUserOpName, bgOpName, bgOpArg, inbox.CurrentQueueLength)
while bgOp ctok do
bgOpCts.Dispose()
bgOpCts <- new CancellationTokenSource()
while not bgOpCts.IsCancellationRequested && bgOp ctok bgOpCts.Token do
()
if bgOpCts.IsCancellationRequested then
Trace.TraceInformation("FCS: <-- wait for background was cancelled {0}.{1}", bgUserOpName, bgOpName)
channel.Reply(())
return! loop (None, onComplete, false)
| Some (CompleteAllQueuedOps channel) ->
Trace.TraceInformation("Reactor: {0:n3} --> stop background work and complete all queued ops, remaining {1}", DateTime.Now.TimeOfDay.TotalSeconds, inbox.CurrentQueueLength)
return! loop (None, Some channel, false)
| None ->
match bgOpOpt, onComplete with
| _, Some onComplete -> onComplete.Reply()
......@@ -106,7 +116,11 @@ type Reactor() =
Trace.TraceInformation("Reactor: {0:n3} --> background step {1}.{2} ({3})", DateTime.Now.TimeOfDay.TotalSeconds, bgUserOpName, bgOpName, bgOpArg)
let time = Stopwatch()
time.Start()
let res = bgOp ctok
bgOpCts.Dispose()
bgOpCts <- new CancellationTokenSource()
let res = bgOp ctok bgOpCts.Token
if bgOpCts.IsCancellationRequested then
Trace.TraceInformation("FCS: <-- background step {0}.{1}, was cancelled", bgUserOpName, bgOpName)
time.Stop()
let taken = time.Elapsed.TotalMilliseconds
//if span.TotalMilliseconds > 100.0 then
......@@ -126,8 +140,13 @@ type Reactor() =
// [Foreground Mailbox Accessors] -----------------------------------------------------------
member r.SetBackgroundOp(bgOpOpt) =
Trace.TraceInformation("Reactor: {0:n3} enqueue start background, length {1}", DateTime.Now.TimeOfDay.TotalSeconds, builder.CurrentQueueLength)
bgOpCts.Cancel()
builder.Post(SetBackgroundOp bgOpOpt)
member r.CancelBackgroundOp() =
Trace.TraceInformation("FCS: trying to cancel any active background work")
bgOpCts.Cancel()
member r.EnqueueOp(userOpName, opName, opArg, op) =
Trace.TraceInformation("Reactor: {0:n3} enqueue {1}.{2} ({3}), length {4}", DateTime.Now.TimeOfDay.TotalSeconds, userOpName, opName, opArg, builder.CurrentQueueLength)
builder.Post(Op(userOpName, opName, opArg, CancellationToken.None, op, (fun () -> ())))
......
......@@ -26,7 +26,10 @@ type internal Reactor =
/// Set the background building function, which is called repeatedly
/// until it returns 'false'. If None then no background operation is used.
member SetBackgroundOp : ( (* userOpName:*) string * (* opName: *) string * (* opArg: *) string * (CompilationThreadToken -> bool)) option -> unit
member SetBackgroundOp : ( (* userOpName:*) string * (* opName: *) string * (* opArg: *) string * (CompilationThreadToken -> CancellationToken -> bool)) option -> unit
/// Cancel any work being don by the background building function.
member CancelBackgroundOp : unit -> unit
/// Block until the current implicit background build is complete. Unit test only.
member WaitForBackgroundOpCompletion : unit -> unit
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册