anchor.diff: +%%
  +%% This is a 'ranch' managed worker. When a socket client
  +%% connects to the server, the socket is passed here and
  +%% we manage the overall communication.
  +%%
  +%% When the client first connects, we challenge for a valid
  +%% message containing the robot's name. If we get a valid-
  +%% looking message, we put a 'registration|robot_name' message
  +%% into the 'registration' tube of beanstalk for processing,
  +%% then we drop into loop that watches the 'robot_name_commands'
  +%% tube and forward them onto the connected socket client.
  +%%
   -module(robot_command_protocol).
   -behavior(ranch_protocol).
   
  
positive.code:   send_messages(Socket, Transport, Messages).
  
  send_message(Socket, Transport, Message) ->
    Transport:send(Socket, binary:encode_unsigned(length(Message))),
    Transport:send(Socket, Message).
  
negative.code: 
  loop(command_wait, Socket, Transport, Q, Log, TubeName) ->
    { watching, _ } = beanstalk:watch(Q, io_lib:format("~s_commands", [ TubeName ])),
    % Wait on the queue for 10 seconds
    case beanstalk:reserve(Q, 10) of
      { reserved, JobId, BMessage } ->
        send_message(Socket, Transport, binary:bin_to_list(BMessage)),
        { deleted } = beanstalk:delete(Q, JobId),
        loop(command_wait, Socket, Transport, Q, Log, TubeName);
      { timed_out } ->
        % The idea here is to see if the socket is still alive
        % before we loop back into waiting on the queue. If we
        % don't do this, we won't know we lost the client until
        % we actually get a command from the queue to send.
        case send_message(Socket, Transport, "noop") of
          ok -> 
            % Socket is OK, back to waiting on the tube
            loop(command_wait, Socket, Transport, Q, Log, TubeName);
          Error ->
            % OK, the socket is closed; notify of the de-registration
            % and drop out of the loop.
            { inserted, _ } = beanstalk:put(Q, binary:list_to_bin(io_lib:format("unregister|~s", [ TubeName ]))),
            syslog:log(Log, err, "Robot ~s closed the socket: ~p",  [ TubeName, Error ])
        end;
      Error ->
        % Log the error it and drop out of the loop.
        syslog:log(Log, err, "Error reserving a job: ~p",  [ Error ])
    end.
  
  