Discussion:
[elm-discuss] How to manage long running computations in Elm?
'Rupert Smith' via Elm Discuss
2017-06-06 14:20:42 UTC
Permalink
The problem with long running computations in a single threaded UI is that
they may cause the UI to block and become unresponsive for a period.
Definitely not an acceptable user experience.

I have created a library for helping with AI-type searches. This provides a
'next' function that steps the search along by examining a single 'node' in
the search space. The search space forms a graph, and as each node is
de-queued from the search buffer, it is checked to see if it is a goal
state, and all its successor states are created from a user supplied 'step'
function, and en-queued onto the search buffer.

http://package.elm-lang.org/packages/the-sett/ai-search/3.1.0/Search#next

next : SearchResult state -> SearchResult state

type SearchResult state
= Complete
| Goal state (() -> SearchResult state)
| Ongoing state (() -> SearchResult state)

So I can run just 1 or perhaps a few hundred iterations of the search in
each loop around the Elm 'update' function. I can return a Cmd that will
use the cause the () -> continuation to run some more iterations next time,
and that will also give control back to the Elm kernel to process other
Cmds and keep the UI responsive.

Its explicit time-slicing of the CPU in application code, which is not so
nice.

Ideally, I would have a background thread running the search. On every
iteration it would check a volatile (shared memory) flag in case the user
got bored waiting for the results and clicked cancel.

I know there have been a few experiments in hooking up Elm with webworker
threads. Has anyone tried this out? In particular was there a way to do
inter-process communication, specifically the cancel flag I described above?

There is some IPC stuff mentioned under 'Future Plans' (spawn/kill/send) in
the Process module:

http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Process

Could this be implemented on top of webworker threads?
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
'Rupert Smith' via Elm Discuss
2017-06-07 08:08:37 UTC
Permalink
Post by 'Rupert Smith' via Elm Discuss
The problem with long running computations in a single threaded UI is that
they may cause the UI to block and become unresponsive for a period.
Definitely not an acceptable user experience.
I have created a library for helping with AI-type searches. This provides
a 'next' function that steps the search along by examining a single 'node'
in the search space. The search space forms a graph, and as each node is
de-queued from the search buffer, it is checked to see if it is a goal
state, and all its successor states are created from a user supplied 'step'
function, and en-queued onto the search buffer.
I should add, it seems likely any long-running process will be structured
to have a loop at the top-level. This loop can be turned into a
continuation '() -> More a', to break the task down into steps. So this
does not just apply to my AI search library but any longer computation we
might want to do that puts too much delay into the UI update cycle.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Matthieu Pizenberg
2017-06-13 03:10:15 UTC
Permalink
Post by 'Rupert Smith' via Elm Discuss
The problem with long running computations in a single threaded UI is
that they may cause the UI to block and become unresponsive for a period.
Definitely not an acceptable user experience.
Yep, totally agree with you. I also would love to be able to run some
scientific computation, but the UI blocking is a stopper.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Vlad GURDIGA
2017-06-13 15:26:33 UTC
Permalink
One thing that I think I would have tried in this case, it to delegate the
long running computation to a webworker
<http://caniuse.com/#search=Web%20Workers>, and then talk with it through a
port.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
'Rupert Smith' via Elm Discuss
2017-06-13 21:08:05 UTC
Permalink
Post by Vlad GURDIGA
One thing that I think I would have tried in this case, it to delegate the
long running computation to a webworker
<http://caniuse.com/#search=Web%20Workers>, and then talk with it through
a port.
Yes, and I see Richard Feldman has had an experiment with Elm and
webworkers:

https://github.com/rtfeldman/elm-web-workers

Its for Elm 0.17 so I guess just an experiment, but worth a look.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
'Rupert Smith' via Elm Discuss
2017-06-13 21:10:30 UTC
Permalink
Post by Matthieu Pizenberg
Post by 'Rupert Smith' via Elm Discuss
The problem with long running computations in a single threaded UI is
that they may cause the UI to block and become unresponsive for a period.
Definitely not an acceptable user experience.
Yep, totally agree with you. I also would love to be able to run some
scientific computation, but the UI blocking is a stopper.
But you can split the computation at some suitable point, returning a
continuation to 'calculate the rest later', then return to your 'update'
function and have it return a Cmd to come back in later and continue the
work. Did you try this technique? Its not ideal, but at least it makes it
no longer a stopper.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Matthieu Pizenberg
2017-06-14 01:39:57 UTC
Permalink
Post by Vlad GURDIGA
One thing that I think I would have tried in this case, it to delegate the
long running computation to a webworker
<http://caniuse.com/#search=Web%20Workers>, and then talk with it through
a port.
I'm not from the web community. I had bases in html+css+js, but pretty much
had to relearn my JS when started to try elm, so I've never used web
workers before. Not sure I'd like to take some time to learn how it works.
Post by Vlad GURDIGA
Did you try this technique? Its not ideal, but at least it makes it no
longer a stopper.
Nope, but thanks, I keep the idea in mind. Actually, It wasn't the only
issue I had since this was mainly image manipulation. The lack of binary
data type support was also very restricting. Then I didn't want to invest
too much energy in this. I prefer to wait and see for now, busy with other
matters. I'm still confident in the fact that elm is a great language and
evolves slowly but surely. I'm just here a bit too early for some of my
needs. For the rest, I'm very happy with elm.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jakub Hampl
2017-06-30 08:43:50 UTC
Permalink
One way of approaching this is to show the user progress in an interesting
way. In this example
<http://code.gampleman.eu/elm-visualization/ForceDirectedGraph/>, the
computation that calculates the final layout of a network graph (which is
pretty expensive) is animated so the user can watch the algorithm converge.
Post by Vlad GURDIGA
One thing that I think I would have tried in this case, it to delegate the
Post by Vlad GURDIGA
long running computation to a webworker
<http://caniuse.com/#search=Web%20Workers>, and then talk with it
through a port.
I'm not from the web community. I had bases in html+css+js, but pretty
much had to relearn my JS when started to try elm, so I've never used web
workers before. Not sure I'd like to take some time to learn how it works.
Post by Vlad GURDIGA
Did you try this technique? Its not ideal, but at least it makes it no
longer a stopper.
Nope, but thanks, I keep the idea in mind. Actually, It wasn't the only
issue I had since this was mainly image manipulation. The lack of binary
data type support was also very restricting. Then I didn't want to invest
too much energy in this. I prefer to wait and see for now, busy with other
matters. I'm still confident in the fact that elm is a great language and
evolves slowly but surely. I'm just here a bit too early for some of my
needs. For the rest, I'm very happy with elm.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
'Rupert Smith' via Elm Discuss
2017-07-02 17:59:46 UTC
Permalink
Post by Jakub Hampl
One way of approaching this is to show the user progress in an interesting
way. In this example
<http://code.gampleman.eu/elm-visualization/ForceDirectedGraph/>, the
computation that calculates the final layout of a network graph (which is
pretty expensive) is animated so the user can watch the algorithm converge.
Nice example, I like how you can interrupt it by clicking on one of the
other examples, so the UI is not getting frozen.

One thing about this example, is that is driven off of a timer tick. So if
each iteration of the node layout takes say one microsecond of CPU time,
and the timer ticks every millisecond - it will only use 1/1000th of the
CPU. Its fine for animation.

In my case I don't want to use a timer tick to drive the computation,
because I want to use 100% of the CPU (or close to it) to complete a
computation as quickly as possible, but still not block user interaction.

We had a good first Elm Scotland Meetup btw, hope you can make the next one.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jakub Hampl
2017-07-03 08:37:17 UTC
Permalink
In JS, you could measure the time of each iteration and then only do so many that it would fit into a “frame budget” (so < 16ms, or if you are updating the DOM you would probably only spend say 10ms). However, I’m not sure how easy that would be in Elm.
One way of approaching this is to show the user progress in an interesting way. In this example, the computation that calculates the final layout of a network graph (which is pretty expensive) is animated so the user can watch the algorithm converge.
Nice example, I like how you can interrupt it by clicking on one of the other examples, so the UI is not getting frozen.
One thing about this example, is that is driven off of a timer tick. So if each iteration of the node layout takes say one microsecond of CPU time, and the timer ticks every millisecond - it will only use 1/1000th of the CPU. Its fine for animation.
In my case I don't want to use a timer tick to drive the computation, because I want to use 100% of the CPU (or close to it) to complete a computation as quickly as possible, but still not block user interaction.
We had a good first Elm Scotland Meetup btw, hope you can make the next one.
--
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/M5teKjboylI/unsubscribe.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
'Rupert Smith' via Elm Discuss
2017-07-03 13:30:31 UTC
Permalink
Post by Jakub Hampl
In JS, you could measure the time of each iteration and then only do so
many that it would fit into a “frame budget” (so < 16ms, or if you are
updating the DOM you would probably only spend say 10ms). However, I’m not
sure how easy that would be in Elm.
Yes, I was considering that. I have a function that takes an argument 'n'
which tells it how many loops of the search to run (or terminate sooner if
it finds a goal state). I was thinking of running say 10 iterations and
timing how long that takes, then using the throughput from that (= num
iterations / time taken) to estimate how many iterations would fit in what
you call a "frame budget". Then on subsequent iterations try and do a frame
budgets worth each time.

Could work. Or web workers.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...