Comments (6)
For the second question, promises basically capture that same pattern. Note that if the job started as a promise is aborted or blocks forever, the promise will not be fulfilled. There is also somewhat more experimental support for joinable processes and for finalizers. The main problem with those is that they make use of finalizers, which are quite expensive. On the other hand, using finalizers this way doesn't add any overhead in the case where joinable processes or finalizers are not being used.
from hopac.
For the first question, the short answer is no, Hopac jobs do not currently provide any built-in method for outside cancellation or abort. This is partly an intentional design choice and partly due to performance reasons. The problem with aborting or cancelling jobs from outside is that it is not generally safe—the job being aborted might be executing a sequence of operations that must not be broken or something will be left in an inconsistent state. The performance issue with cancellation, like is done with async
is that it adds overhead even in case cancellation is not being used.
If the requirement to not modify the code is not absolute, then one potential solution could perhaps be to write a job builder with cancellation support. The builder could construct jobs by passing along an IVar or a cancellation token and poll that.
from hopac.
Thank you for the quick reply. Come to think of it, it is in principle impossible to have cancellation of jobs by job handle when multiple job processes can be launched in parallel from one handle.
I'm not writing a general purpose library so the requirement not to modify the code is not absolute but rather a general guideline for simplicity of design. I'm relatively new to F# and workflows. Do I need to write the appropriate job builder from scratch, or rather inherit from or wrap the existing one?
from hopac.
The Job<'x>
objects or values that you create with the job { ... }
workflow syntax or using the combinators Job.result
and >>=
aren't something that one usually calls handles. Job<'x>
objects encode computations. Probably the most fruitful way to think about the Job<'x>
type is to think of it as being like unit -> 'x
, in other words, a computation that, when called, produces a value of type 'x
. (Of course, the underlying implementation is slightly more complex and closer to the type ('x -> unit) -> unit
, but you can mostly ignore that. fixed)
type Job<'x> = unit -> 'x
let result x = fun () -> x
let (>>=) xJ x2yJ = fun () -> x2yJ (xJ ()) ()
So, basically, what you do with the job { ... }
notation or the result
and >>=
combinators is that you create computations. You can then start such computations as cheap lightweight threads.
The Proc
type can be seen as a handle to such a lightweight thread. However, Proc
only allows you to observe when a thread is known to be completed. It doesn't allow you to send messages to the thread or kill the the thread.
from hopac.
For the question on builders. You would likely write a new workflow builder. Here is a quick sketch of one way to do it:
type CancellableJob<'x> = IVar<unit> -> Job<'x>
type Can<'x> = CancellableJob<'x> // Abbreviation for convenience
type CancellableJobBuilder () =
member inline t.Delay (u2xC: unit -> Can<'x>) : Can<'x> =
fun uI -> u2xC () uI
member inline t.ReturnFrom (xC: Can<'x>) : Can<'x> = xC
member inline t.Return (x: 'x) : Can<'x> =
fun uI -> Job.result x
member inline t.Zero () : Can<unit> = fun _ -> Job.unit ()
member inline t.Bind (xC: Can<'x>, x2yC: 'x -> Can<'y>) : Can<'y> =
fun uI ->
xC uI >>= fun x ->
if IVar.Now.isFull uI then
Job.raises <| OperationCanceledException ()
else
x2yC x uI
// ...
member inline t.ReturnFrom (xJ: Job<'x>) : Can<'x> = fun _ -> xJ
member inline t.Bind (xJ: Job<'x>, x2yC: 'x -> Can<'y>) : Can<'y> =
t.Bind (t.ReturnFrom xJ, x2yC)
// ...
let can = CancellableJobBuilder ()
let jb = can {
let sleep = Hopac.Timer.Global.sleep (TimeSpan.FromMilliseconds 1000.)
let inner = can {
do! sleep
printfn "slept"}
do! inner
do! inner
}
let test = job {
let uI = ivar ()
do! Job.start (jb uI)
do! Hopac.Timer.Global.sleep (TimeSpan.FromMilliseconds 1500.)
do! uI <-= ()
}
(Despite having the test
above, I haven't actually tested anything at this point.)
from hopac.
Thanks so much for the explanation and the code snippet. It looks perfect!
from hopac.
Related Issues (20)
- Add Azure DevOps build HOT 2
- Problems with network stream HOT 9
- Handling exceptions HOT 9
- Stack Overflow in Alt.choose HOT 3
- Fibonacci benchmark fails with Stack Overflow on NET Core, but not on Framework HOT 4
- Production Ready? HOT 5
- IAsyncEnumerable<T> interop HOT 1
- How to convert to task? HOT 6
- ValueTask<T> interop HOT 1
- How to get the build working on Windows? HOT 2
- Stack overflow with recursive job HOT 5
- Is this project dead? HOT 1
- Why do these two code snippets result in different behavior HOT 1
- FSharp.Core 5.0 support HOT 15
- Why does the left side not uncommit after the right side has been chosen when using Alt.prepare? HOT 8
- How can uncaught exception errors be redirected?
- BadImageFormatException HOT 6
- How to conCollect but stop on first exception? HOT 8
- System.Diagnostics.Activity doesn't flow properly with Hopac, resulting in incorrect telemetry correlation
- Example of paranoid function?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hopac.