|
31 | 31 | server_properties,
|
32 | 32 | %% connection.block, connection.unblock handler
|
33 | 33 | block_handler,
|
| 34 | + blocked_by = sets:new([{version, 2}]), |
34 | 35 | closing = false %% #closing{} | false
|
35 | 36 | }).
|
36 | 37 |
|
@@ -199,9 +200,36 @@ handle_cast({server_misbehaved, AmqpError}, State) ->
|
199 | 200 | server_misbehaved_close(AmqpError, State);
|
200 | 201 | handle_cast({server_close, #'connection.close'{} = Close}, State) ->
|
201 | 202 | server_initiated_close(Close, State);
|
202 |
| -handle_cast({register_blocked_handler, HandlerPid}, State) -> |
| 203 | +handle_cast({register_blocked_handler, HandlerPid}, |
| 204 | + #state{blocked_by = BlockedBy} = State) -> |
203 | 205 | Ref = erlang:monitor(process, HandlerPid),
|
204 |
| - {noreply, State#state{block_handler = {HandlerPid, Ref}}}. |
| 206 | + State1 = State#state{block_handler = {HandlerPid, Ref}}, |
| 207 | + %% If an alarm is already active, immediately block the handler. |
| 208 | + _ = case sets:is_empty(BlockedBy) of |
| 209 | + false -> |
| 210 | + HandlerPid ! #'connection.blocked'{}; |
| 211 | + true -> |
| 212 | + ok |
| 213 | + end, |
| 214 | + {noreply, State1}; |
| 215 | +handle_cast({conserve_resources, Source, Conserve}, |
| 216 | + #state{blocked_by = BlockedBy} = State) -> |
| 217 | + WasNotBlocked = sets:is_empty(BlockedBy), |
| 218 | + BlockedBy1 = case Conserve of |
| 219 | + true -> |
| 220 | + sets:add_element(Source, BlockedBy); |
| 221 | + false -> |
| 222 | + sets:del_element(Source, BlockedBy) |
| 223 | + end, |
| 224 | + State1 = State#state{blocked_by = BlockedBy1}, |
| 225 | + case sets:is_empty(BlockedBy1) of |
| 226 | + true -> |
| 227 | + handle_method(#'connection.unblocked'{}, State1); |
| 228 | + false when WasNotBlocked -> |
| 229 | + handle_method(#'connection.blocked'{}, State1); |
| 230 | + false -> |
| 231 | + {noreply, State1} |
| 232 | + end. |
205 | 233 |
|
206 | 234 | %% @private
|
207 | 235 | handle_info({'DOWN', _, process, BlockHandler, Reason},
|
|
0 commit comments