email@example.com said: When the agent's thread-local "nested" field is non-nil, any sends are queued instead of being sent immediately. This is its normal state when agent actions are being executed.
Another piece of thread-local state is agent which is set to the current agent when an action is being executed. This state is also checked by 'await' so that it can throw if it's called during an agent action.
I can think of two options for allowing sends from agent error handlers:
A. Set "nested" to null before the error handler is invoked, allowing any sends from it to proceed immediately when send is called.
B. Clear "nested" to an empty vector as it is now, but then after invoking the error handler release any newly pending sends queued by the error handler.
This patch implements choice (A). It changes the state of the agent's "nested" field from an empty vector to null for the period of time between when the action has terminated with an error and the time when "nested" is normally set to null (after the next action, if any, has been queued. The things that happen during this time are:
1. the error handler (if any) is invoked
2. the error flag is reset (if error-mode is :continue)
3. the current action is popped off the agent's queue
4. the next action is queued
So this change allows sends from this agent during all of these steps. It does not change agent, so 'await' is still disallowed throughout these steps.
Of the 4 things done during this time period, only step 1 calls any user code in the current thread such that thread-local values would have any impact, and none of the others depend on the value of "nested" at all.
During step 1, the user's error handler will be called with agent true and nested nil, which is combination not normally seen. The reasons that sends from inside actions are normally held until later is prevent them from happening if the action fails to "commit" and update the agent's value, and to promise to users that any nested actions will see the updated agent's value (or a subsequent value). Neither of these reasons apply in this case because the state of the agent will not be updated due to the failed action, so allowing sends to proceed immediately is safe.