Places parallelism -- how to return ASAP after 1st answer

Hi,

Taking the example program for places from the docs:

(let ([pls (for/list ([i (in-range 2)])
              (dynamic-place "place-worker.rkt" 'place-main))])
   (for ([i (in-range 2)]
         [p pls])
      (place-channel-put p i)
      (printf "~a\n" (place-channel-get p)))
   (map place-wait pls))

How can I return early, as soon as the 1st message gets back and kill all other places having not returned yet? I'm doing a lengthy computation involving a random search, that I would like to speed up.

Thanks!

A place channel can be used as a synchronizable event (see Events) to receive a value through the channel. A place channel is ready for synchronization when a message is available on the channel, and the place channel’s synchronization result is the message (which is removed on synchronization).

(let ([pls (for/list ([i (in-range 2)])
              (dynamic-place "place-worker.rkt" 'place-main))])
   (define result (apply sync pls))
   (map place-kill pls)
   (do-something-with result))

Apply is used with sync and returns with the result from one of the places.
(sync with multiple arguments (via apply) waits on those arguments and returns with one of them (when there is one that is ready))
Map kills all the places (if they aren't already dead).
do-something-with is a stub replace it with something or alternatively just return result as the expression's result from the let block.
Haven't tested it, but should work, does this do what you want?

If this is part of a larger program it might be a good idea to setup a custodian to make sure everything is cleaned up when you are done searching for stuff, alternatively you could use exception handlers or dynamic-wind.

3 Likes

Works perfectly! Thanks for the tips, I think I would've taken a long time to understand sync from reading the docs.

One nit: I prefer (for-each place-kill pls) (since we don't do anything with the results of place-kill).

2 Likes