在凤凰应用程序中提取微服务:Genserver

问题描述:

我在阅读this文章,了解如何从现有的凤凰应用程序中提取微服务。作者重构了phoenix应用程序控制器之一,并将其​​方法之一移至Genserver,之后他将该Genserver移至单独的应用程序,并在主项目中添加了依赖项。在凤凰应用程序中提取微服务:Genserver

但我在这里有点困惑,因为GenServer允许你只有两个服务器回调(它们是句柄调用和句柄转换)。但是如果我想要将一个功能作为微服务移出,我们最终将创建与该服务中涉及的端点一样多的Genserver,因为一个genserver会允许一个/两个方法调用。 genserver是提取服务的理想方法吗?

GenServer有3个主要回调:handle_casthandle_callhandle_info。每个函数都可以有多个子句,每个子句实现特定的功能。

例如,假设我有一个GenServer实施UserService模块,具有5个操作:createshowindexupdatedelete。让我们进一步假设我正在实施delete作为异步操作(所以使用handle_cast),其余为同步操作(使用handle_call)。

def handle_call({:create, user_data}, _from, state) do 
    new_user = User.create(user_data) // (However you create a user) 
    {:reply, new_user, state} 
end 

def handle_call(:index, _from, state) do 
    users = User.all 
    {:reply, users, state} 
end 

def handle_call({:update, user_changes}, _from, state) do 
    updated_user = User.update(user_changes) 
    {:reply, updated_user, state} 
end 

def handle_call({:show, user_id}, _from, state) do 
    user = User.get(user_id) 
    {:reply, user, state} 
end 

def handle_cast({:delete, user_id}, state) do 
    User.delete(user_id) 
    {:no_reply, state) 
end 

客户端模块可以调用user = GenServer.call(pid, {:show, user_id})使用show条款。主要的一点是,即使只定义了一些“函数”,也可以根据需要定义该函数的许多子句,并将模式匹配分派给正确的子句。

我对你的问题有点困惑,但我认为你没有正确的GenServers图片。

2个回调函数handle_callhandle_cast用于接收通过GenServer.callGenServer.cast函数发送的消息。还有handle_info可以接收任何发送到GenServer进程的非OTP消息。

呼叫是将阻止响应的同步消息。我想这就是你想要的微服务。 (Cast用于异步消息。)

单个GenServer实现可以接收通过call发送的任意数量的消息。

handle_call callback需要3个参数。第一个是它正在处理的信息。通常,该消息是一个标记元组,这意味着它的第一个项目标识它是哪种类型的消息。您可以处理多个不同的消息和使用模式匹配您的GenServer内执行正确的功能的语句是这样的:因为你需要

def handle_call({:message_one, foo}, _from, state) 
    # create some_response from foo or modify state here 
    {:reply, some_respone, state} 
end 
def handle_call({:message_two, bar}, _from, state) 
    # create some_response from bar or modify state here 
    {:reply, some_response, state} 
end 
def handle_call({:message_three, buzz}, _from, state) 
    # create some_response from buzz or modify state here 
    {:reply, some_response, state} 
end 

你GenServer可以有很多,这些功能的条款。您通常还会将这些消息标记原子作为实现细节并创建公共API函数,以将您的调用包装为GenServer.call