Erlang 丢弃消息

Erlang drop messages

我有一个代理可以防止服务器因请求而过载。 客户端将请求发送给代理,代理决定是否将请求传递给服务器。

NrOfReq 是服务器正在处理的当前请求数。 MaxReq 是服务器之前可以处理的最大请求数 邮箱满了。

服务器每次处理请求时都会发送 ready_to_serve 原子 到代理。

每当 when-关键字后的守卫为假时,我想删除来自客户端的消息并防止它最终出现在代理邮箱中。 我该怎么做?

proxy(ServerPid, NrOfReq, MaxReq) ->
    receive
            {client_request, Request, ClientPid} when NrOfReq < MaxReq ->
                    New = NrOfReq + 1,
                    ServerPid ! {Request, ClientPid, self()};
            ready_to_serve ->
                    New = NrOfReq - 1
    end,
    proxy(ServerPid, New, MaxReq).

我从未尝试过你的提议,在我这边,我会为循环使用 2 个子句:

proxy(ServerPid, MaxReq, MaxReq) ->
    receive
            ready_to_serve ->
                    New = NrOfReq - 1
    end,
    proxy(ServerPid, New, MaxReq);

proxy(ServerPid, NrOfReq, MaxReq) ->
    receive
        {client_request, Request, ClientPid} ->
                New = NrOfReq + 1,
                ServerPid ! {Request, ClientPid, self()};
        ready_to_serve ->
                New = NrOfReq - 1
    end,
    proxy(ServerPid, New, MaxReq).

我觉得这个代理很奇怪。我在 Erlang 中最常看到的模式是为每个客户端生成 1 个服务器,并有专门的进程来生成这些服务器、管理存储 ...

  1. 将消息接收与消息处理分开

    proxy(ServerPid, NrOfReq, MaxReq) ->
        receive
            {client_request, Request, ClientPid} ->
                    if 
                        NrOfReq < MaxReq ->
                            New = NrOfReq + 1,
                            ServerPid ! {Request, ClientPid, self()};
                        true ->
                            'message-dropped';
                    end;
            ready_to_serve ->
                    New = NrOfReq - 1
    end,
    proxy(ServerPid, New, MaxReq).
    
  2. 否则为丢弃消息制定后备条款

    proxy(ServerPid, NrOfReq, MaxReq) ->
        receive
            {client_request, Request, ClientPid} when NrOfReq < MaxReq ->
                New = NrOfReq + 1,
                ServerPid ! {Request, ClientPid, self()};
            {client_request, Request, ClientPid} when NrOfReq >= MaxReq  ->
                'message-dropped';
            ready_to_serve ->
                New = NrOfReq - 1
    end,
    proxy(ServerPid, New, MaxReq).
    

后者有点扁平化,但在您决定更改邮件格式时可能会导致问题。

PS: 为什么你不使用 OTP?