Fork me on GitHub
#missionary
<
2024-04-28
>
zy C16:04:02

hi! I have a question about m/race: My understanding of the behavior of race is: the second task should execute successfully, returning 2, and the first sleep task should be cancelled, so the only printed content should be :s 2, and :clean should not appear. but it looks like the second task is cancelled by m/race

(def cancel2 ((m/race (m/sleep 1000 1)
                        (fn [s f]
                          (s 2)
                          #(prn :clean)))
                #(prn :s %) #(js/console.log :f %)))
  ;; print:
  ;; :s 2
  ;; :clean

leonoel17:04:23

Observing :clean is an implementation detail. The cancelling function is supposed to become a no-op after completion, therefore m/race considers it safe to call it on the race winner.

zy C17:04:36

so even if the second task wins in the race, its canceller will still be called? did i understand it correctly?

leonoel17:04:49

yes, but it's accidental and you should not rely on that

zy C17:04:51

According to the docstring “If any task succeeds, others are cancelled then race completes with this result.” I originally thought that the canceller of the winning task would definitely not be called.

leonoel17:04:58

it may or may not be called, no guarantees

❤️ 1
zy C17:04:13

okay, understand now. thank you for the quick reply!

leonoel17:04:20

The reason is because cancellation and completion may be concurrent, when it happens the task process must be able to resolve the race condition and handle the "completion then cancellation" scenario. It is therefore always safe for the parent process to cancel after completion, so it's allowed to do that if it's beneficial for the implementation.

❤️ 1
👍 2
zy C17:04:56

Thank you so much for the detailed explanation! It might be best to add this explanation to the docstring or somewhere else? Otherwise, beginners like me might misunderstand the meaning of the m/race docstring.

leonoel17:04:01

This is expert-only material, as an application developer you're not supposed to write tasks manually

zy C17:04:30

haha, I am now half an expert

zy C17:04:35

thanks again

Eric Dvorsak11:04:20

@U053XQP4S by writing tasks manually you mean writing tasks following the task spec without using missionary api (eg m/sp)?