Add async argument in CodeBlock
If CodeBlocks contain time-consuming logic (e.g. API calls) they block the web server. The proposal is to add an async argument to the CodeBlock constructor that makes this logic perform asynchronously via WorkerAsyncProcess. The logic looks something like this:
- A
CodeBlockthat initializes a WorkerAsyncProcess using theWorkerAsyncProcessconstructor. The process should have the labelCodeBlockso that we know where it comes from. See example code:
WorkerAsyncProcess(
label="CodeBlock",
function=self._request_partial_payment,
arguments={
"participant": participant,
"payment": participant.calculate_reward(),
# "reason": _("Partial payment for incomplete participation"),
},
participant=participant,
unique=dict(participant_id=participant.id),
)
- A
wait_whilethat waits for this process to complete. Something like:
def code_block_process_finished(participant):
relevant_processes = [
p
for p in participant.async_processes
if p.label == "CodeBlock"
]
assert len(relevant_processes) == 1
process = relevant_processes[0]
assert not process.failed
return process.finished
wait_while(
condition=lambda participant: not code_block_process_finished(participant),
expected_wait=5.0,
check_interval=2.0,
)
We should have a test for this new feature. I propose creating a very simple demo that goes in the 'features' directory that has an async code block with a time.sleep() in it followed by setting a participant variable, and then a test assertion in def test_check_bot that checks that the variable got set correctly.
Edited by Peter Harrison