
[;1m  monitor(Type, Item, Opts)[0m

[;;4mSince[0m:
  OTP 24.0

  Provides an option list for modification of monitoring
  functionality provided by [;;4mmonitor/2[0m. The [;;4mType[0m and [;;4mItem[0m
  arguments have the same meaning as when passed to [;;4mmonitor/2[0m.

  Currently available options:

   • [;;4m{alias, UnaliasOpt}[0m - The returned monitor reference will
     also become an alias for the calling process. That is, the
     returned reference can be used for sending messages to the
     calling process. See also [;;4malias/0[0m. The [;;4mUnaliasOpt[0m
     determines how the alias should be deactivated.

      ￮ [;;4mexplicit_unalias[0m - Only an explicit call to [;;4m[0m
        [;;4munalias/1[0m will deactivate the alias.

      ￮ [;;4mdemonitor[0m - The alias will be automatically
        deactivated when the monitor is removed. This either
        via an explicit call to [;;4mdemonitor/1[0m or when it is
        automatically removed at the same time as a [;;4m'DOWN'[0m
        message is delivered due to the monitor. The alias can
        also still be deactivated via a call to [;;4munalias/1[0m.

      ￮ [;;4mreply_demonitor[0m - The alias will be automatically
        deactivated when the monitor is removed (see [;;4m[0m
        [;;4mdemonitor[0m option above) or a reply message sent via
        the alias is received. When a reply message is
        received via the alias the monitor will also be
        automatically removed. This is useful in client/server
        scenarios when a client monitors the server and will
        get the reply via the alias. Once the response is
        received both the alias and the monitor will be
        automatically removed regardless of whether the
        response is a reply or a [;;4m'DOWN'[0m message. The alias
        can also still be deactivated via a call to [;;4munalias/1[0m.
        Note that if the alias is removed using the [;;4munalias/1[0m
        BIF, the monitor will still be left active.

     Example:

       server() ->
           receive
               {request, AliasReqId, Request} ->
                   Result = perform_request(Request),
                   AliasReqId ! {reply, AliasReqId, Result}
           end,
           server().
       
       client(ServerPid, Request) ->
           AliasMonReqId = monitor(process, ServerPid, [{alias, reply_demonitor}]),
           ServerPid ! {request, AliasMonReqId, Request},
           %% Alias as well as monitor will be automatically deactivated if we
           %% receive a reply or a 'DOWN' message since we used 'reply_demonitor'
           %% as unalias option...
           receive
               {reply, AliasMonReqId, Result} ->
                   Result;
               {'DOWN', AliasMonReqId, process, ServerPid, ExitReason} ->
                   error(ExitReason)
           end.

     Note that both the server and the client in this example
     must be executing on at least OTP 24 systems in order for
     this to work.

     For more information on process aliases see the Process
     Aliases section of the Erlang Reference Manual.

   • [;;4m{tag, UserDefinedTag}[0m - Replace the default [;;4mTag[0m with [;;4m[0m
     [;;4mUserDefinedTag[0m in the monitor message delivered when the
     monitor is triggered. For example, when monitoring a
     process, the [;;4m'DOWN'[0m tag in the down message will be
     replaced by [;;4mUserDefinedTag[0m.

     An example of how the [;;4m{tag, UserDefinedTag}[0m option can be
     used in order to enable the new selective receive
     optimization, introduced in OTP 24, when making multiple
     requests to different servers:

       server() ->
           receive
               {request, From, ReqId, Request} ->
                   Result = perform_request(Request),
                   From ! {reply, self(), ReqId, Result}
           end,
           server().
       
       client(ServerPids, Request) when is_list(ServerPids) ->
           ReqId = make_ref(),
           lists:foreach(fun (ServerPid) ->
                                 _ = monitor(process, ServerPid,
                                             [{tag, {'DOWN', ReqId}}]),
                                 ServerPid ! {request, self(), ReqId, Request}
                         end,
                         ServerPids),
           receive_replies(ReqId, length(ServerPids), []).
       
       receive_replies(_ReqId, 0, Acc) ->
           Acc;
       receive_replies(ReqId, N, Acc) ->
           %% The compiler will detect that we match on the 'ReqId'
           %% reference in all clauses, and will enable the selective
           %% receive optimization which makes the receive able to
           %% skip past all messages present in the message queue at
           %% the time when the 'ReqId' reference was created...
           Res = receive
                     {reply, ServerPid, ReqId, Result} ->
                         %% Here we typically would have deactivated the
                         %% monitor by a call to demonitor(Mon, [flush]) but
                         %% we ignore this in this example for simplicity...
                         {ok, ServerPid, Result};
                     {{'DOWN', ReqId}, _Mon, process, ServerPid, ExitReason} ->
                         {error, ServerPid, ExitReason}
                 end,
           receive_replies(ReqId, N-1, [Res | Acc]).

     In order for this example to work as intended, the client
     must be executing on at least an OTP 24 system, but the
     servers may execute on older systems.
