-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial implementation of the Encore task library #125
Initial implementation of the Encore task library #125
Conversation
@albertnetymk I have tested it under Vagrant but, could you test that it works on Linux? |
I ran the test on my machine(Ubuntu 14.10) and it works! And don't forget to add tasks to the documentation :) |
@TheGrandmother thanks! Doc added! |
Will tasks ever block explicitly on futures? I mean will there be a call to "block" inside the code of a task? |
potentially, there could be. that case is not supported at the moment. what I mean is that there could be a case such that:
|
Works OK on my Linux. One comment on the syntax: |
@albertnetymk it's a keyword, the parenthesis are placed there to improve readability! :) |
I think the syntax should be |
@TobiasWrigstad regarding whether tasks will block. I see no reason why not. |
yes, exactly (@supercooldave last comment), which means that I'll have to fix await |
@supercooldave I have added documentation and an example with the requested syntax. E.g.
|
Sweet!! |
bd0f4df
to
5adb7d6
Compare
I had to rebase on top of If someone is familiar with the new tests that @kaeluka created, it would be great if someone could confirm that what I see is normal:
|
On my Linux, the result is the same except |
5adb7d6
to
04f6c57
Compare
70296c1
to
c8d2a1f
Compare
@albertnetymk updated the test as requested :) |
I've run this and it looks fine. |
If I understand it correctly, the logic goes like this: for each iteration, thread local task_runner picks one task_msg from global task_q, and call handle_msg on it. Possible improvement: Other than that, it looks good as the first implementation. |
@albertnetymk yes, that's how it works. First improvement: you are right, I took the main class because it's auto-generated and I need not change anything in the PonyRT (=> less conflicts when merging) Second improvement: I do not agree, it's true that it could be optimized but I decided to treat every message in the same way. The Thanks for your feedback, it's always appreciated! 👍 |
Note that because this was open for so long, it now has conflicts with my recent commits -- I changed the AST a little. |
first implementation of the task library with futures. tasks are run by a task runner actor who checks if there are tasks to execute and, if so, picks up a task from the mpmcq and runs the task. each `async` returns a future that's fulfilled whenever the task runner runs its task. The program doesn't finish until all the tasks are fulfilled!
there's high coupling between actors and tasks. refactor the code to alleviate in some aspects this high coupling. this means moving around some header files and extern variables / methods. Update the task library with const qualifiers.
the current implementation works under mac and linux. however, there is a problem when doing gc in the future. fulfilling a future fails by accessing the gc->mark of an actor that seems to be gc'd. i have disabled gc'ing futures for the time being until i can figure out what is wrong. added test for tasks with side-effects and when no one is getting on them.
there's no task trace function at the moment, which means that it's needed to add each field in the task to be traced. otherwise, the actor in which the task lives consideres that the task->env and task->dependencies are garbage and should be collected.
update async_block test to omit order. it doesn't test that it doubles the value but that the mod is 0. it tests that it uses `{`, `}` and the return is valid, not really the execution (it's non-deterministic)
this initial implementation does not support parallelism, since the task is blocked as soon as it's defined.
the construct `finish` delays the blocking of the asyncs until the end. Currently, the following form is supported: finish { async { e1, ... } async { e2, ... } } and it's translated to: let x0 = async { e1, ... } x1 = async { e2, ... } in get x0; get x1
previously we allowed only `async` constructs inside the body of `finish`. With this commit, you are allowed to enter other statements and the compiler won't produce code to `get` (block) on them, since they cannot be blocled.
78a8874
to
3f9bcb4
Compare
@supercooldave thanks, I just fixed it. |
I will check over this tonight. It's be good if @albertnetymk gives his approval too. |
(I hope you have squashed all that needs to be squashed.) |
the finish construct was not blocking on a task. there is a current limitation, only top level asyncs declared inside the body of the `finish` construct will be blocked. on the other hand, it doesn't block on futures, just on Async AST nodes.
3f9bcb4
to
455ade3
Compare
Looks good. |
Initial implementation of the Encore task library
Tasks are implemented as actors, where each scheduler has a specific task runner (actor for tasks). Tasks returns futures; at the moment, you cannot chain two tasks together to create dependencies between them, but you can create a task and chain it to a function (typical chain support).
there are some couple of examples for tasks:
global_async.enc
, tests usingasync
inside a global functionasync_force_gc.enc
, testsasync
creating many futures and forcing gc on the objectasync_foreach.enc
, testsasync
side effects, we don't block on the future produced by the taskasync_chain.enc
, simple example of chaining a task to an actor