-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
09 Zinx Async
Case Source Code : https://github.com/aceld/zinx-usage/tree/main/zinx_async_op
Zinx's business threads are designed as a Worker Pool, where the number of workers handling business logic is controlled by WorkerPoolSize, which can be understood as the number of threads. Now, if at a certain point in time, one worker's logic contains a blocking operation, it will cause a delay in processing subsequent request messages by that worker. If all workers have long blocking logic, the server will struggle to handle client request messages in a timely manner. Therefore, it is recommended that the game business logic processed in the Worker Pool is generally non-blocking and operates purely in memory. If there are blocking operations, Zinx provides an asynchronous message processing module called Zasync_op.
After Zasync_op processes asynchronous messages, they are returned to the original worker handling the business logic. This design avoids potential issues of dirty reads and writes in the business logic.
func AsyncUserSaveData(request ziface.IRequest) *zasync_op.AsyncOpResult {
opId := 1 // Player's unique identifier Id
asyncResult := zasync_op.NewAsyncOpResult(request.GetConnection())
zasync_op.Process(
int(opId),
func() {
// Perform db operation
user := db_model.SaveUserData()
// Set the asynchronous return result
asyncResult.SetReturnedObj(user)
},
)
return asyncResult
}
Set the asynchronous return result asyncResult.SetReturnedObj
in the asynchronous processing function zasync_op.Process
.
// Async callback
asyncResult.OnComplete(func() {
zlog.Debug("OnComplete IN===>333")
returnedObj := asyncResult.GetReturnedObj()
if returnedObj == nil {
zlog.Debug("The asynchronous result has not been set yet when registering the callback function")
return
}
user := returnedObj.(*db_model.UserModel)
userLoginRsp := &msg_struct.MsgLoginResponse{
UserId: user.UserId,
UserName: user.Name,
ErrorCode: 0,
}
marshalData, marErr := json.Marshal(userLoginRsp)
if marErr != nil {
zlog.Error("LoginRouter marErr", marErr.Error())
return
}
// Send response to the client
conn := request.GetConnection()
if sendErr := conn.SendMsg(1, marshalData); sendErr != nil {
zlog.Error("LoginRouter sendErr", sendErr.Error())
return
}
zlog.Debug("OnComplete OUT===>333")
})
The async callback function asyncResult.OnComplete
and the asynchronous return result asyncResult.SetReturnedObj
are only necessary if there are additional business logic to be processed after the async operation. If you simply want the logic to execute asynchronously, calling zasync_op.Process
is sufficient.