【发布时间】:2019-01-20 21:59:11
【问题描述】:
我正在使用 Erlang 开发移动游戏后端。对于每个 HTTP 请求,它可能需要查询不同的数据源,例如 PostgreSQL、MongoDB 和 Redis。我想并行地对这些数据源进行独立调用,但找不到明确的 Erlang 方法。
例如,
handle_request(?POST, <<"login">>, UserId, Token) ->
% Verify token from PostgreSQL
AuthResult = auth_service:login(UserId, Token),
% Get user data such as outfits and level from MongoDB
UserDataResult = userdata_service:get(UserId),
% Get messages sent to the user from Redis
MessageResult = message_service:get(UserId),
% How to run the above 3 calls in parallel?
% Then wait for all their results here?
% Combine the result and send back to client
build_response(AuthResult, UserDataResult, MessageResult).
每个服务最终都会调用相应的数据驱动程序(epgsql、eredis、mongo_erlang),最终会在那里调用一些 pooboy:transaction 和 gen_server:call。如何设计这些服务模块也尚未确定。
我想确保上面的 3 个数据调用可以并行运行,然后 handle_request 函数等待所有这 3 个调用完成,然后调用 build_response。我怎样才能正确地做到这一点?
作为参考,在 NodeJS 中,我可能会这样做
var authPromise = AuthService.login(user_id, token);
var userDataPromise = UserdataService.get(user_id);
var messagePromise = MessageService.get(user_id);
Promise.all(authPromise, userDataPromise, messagePromise).then( function(values) {
buildResponse(values);
}
在 Scala 中我可能会这样做
val authFuture = AuthService.login(userId, token)
val userDataFuture = UserdataService.get(userId)
val messageFuture = MessageService.get(userId)
for {
auth <- authFuture
userData <- userDataFuture
message <- messageFuture
} yield ( buildResponse(auth, userData, message )
显然,我认为这个问题是一个承诺/未来/收益问题。但是有人告诉我,如果我在 Erlang 中寻找 Promise,我可能会走错方向。 Erlang 实现这一目标的最佳实践是什么?
【问题讨论】:
标签: asynchronous erlang