anchor.diff:  
   %% @doc Message handler when the rm_loop module is fully initialized.
   -spec on(message(), state()) -> state().
  -on({bench} = _Msg, State) ->
  -    ?TRACE1(_Msg, State),
  +on({bench} = Msg, {AllNodes, Leader, BenchPid, _IgnBenchT} = _State) ->
  +    ?TRACE1(Msg, _State),
       case get_bench_interval() of
           0 -> ok;
           I -> msg_delay:send_local(I, self(), {bench})
       end,
  -    run_bench(),
  +    comm:send_local(BenchPid, Msg),
  +    % send a timeout so that a haning bench service gets re-started
  +    msg_delay:send_local(get_bench_timeout_interval(), self(),
  +                         {bench_timeout, os:timestamp(), BenchPid}),
  +    {AllNodes, Leader, BenchPid, false};
  +
  +on({bench_result, Time, TimeInMs} = _Msg,
  +   {AllNodes, Leader, BenchPid, _IgnBenchT} = _State) ->
  +    ?TRACE1(_Msg, _State),
  +    monitor:proc_set_value(?MODULE, 'read_read',
  +                           fun(Old) -> rrd:add(Time, TimeInMs, Old) end),
  +    % ignore the bench_timeout message that will follow
  +    {AllNodes, Leader, BenchPid, true};
  +
  +on({bench_timeout, Time, BenchPid} = _Msg,
  +   {AllNodes, Leader, BenchPid, false} = _State) ->
  +    ?TRACE1(_Msg, _State),
  +    % the bench service could not reply within get_bench_timeout_interval() seconds
  +    % -> re-start service (it may hang) and assume this interval as the reported time
  +    erlang:exit(BenchPid, kill),
  +    monitor:proc_set_value(
  +      ?MODULE, 'read_read',
  +      fun(Old) -> rrd:add(Time, get_bench_timeout_interval() * 1000, Old) end),
  +    Self = self(),
  +    NewBenchPid = erlang:spawn(fun() -> bench_service(Self) end),
  +    {AllNodes, Leader, NewBenchPid, false};
  +
  +on({bench_timeout, _Time, _BenchPid} = _Msg, State) ->
  +    ?TRACE1(_Msg, State),
  +    % old or ignored timeout message
       State;
   
   on({collect_system_stats} = _Msg, State) ->
  
positive.code: -export([start_link/1, init/1, on/2, check_config/0]).
  
  -record(state,
          {id      = ?required(state, id)      :: uid:global_uid(),
           perf_rr = ?required(state, perf_rr) :: rrd:rrd(),
           perf_lh = ?required(state, perf_lh) :: rrd:rrd(),
           perf_tx = ?required(state, perf_tx) :: rrd:rrd()
          }).
  
  -type state() :: {AllNodes::#state{}, CollectingAtLeader::#state{}}.
  -type message() ::
      {bench} |
      {collect_system_stats} |
      {propagate} |
      {get_node_details_response, node_details:node_details()} |
  
negative.code: %% @doc Initialises the module with an empty state.
  -spec init(null) -> state().
  init(null) ->
      Self = self(),
      case get_bench_interval() of
          0 -> ok;
          I -> FirstDelay = randoms:rand_uniform(1, I + 1),
               msg_delay:send_local(FirstDelay, Self, {bench}),
               msg_delay:send_local(get_gather_interval(), Self, {propagate})
      end,
      init_bench(),
      init_system_stats(),
      msg_delay:send_local(10, Self, {collect_system_stats}),
      Now = os:timestamp(),
      BenchPid = erlang:spawn(fun() -> bench_service(Self) end),
      State = #state{id = uid:get_global_uid(),
                     perf_rr = rrd:create(get_gather_interval() * 1000000, 60, {timing_with_hist, ms}, Now),
                     perf_lh = rrd:create(get_gather_interval() * 1000000, 60, {timing, count}, Now),
                     perf_tx = rrd:create(get_gather_interval() * 1000000, 60, {timing_with_hist, ms}, Now)},
      {State, State, BenchPid, false}.
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Miscellaneous
  