我有一个应用程序,可以响应客户端发送的消息.一条消息是reload_credentials,应用程序会在新客户端注册时收到该消息.然后,此消息将连接到Postgresql数据库,对所有凭据执行查询,然后将它们存储在常规
Ruby散列(client_id => client_token)中.
应用程序可能接收的一些其他消息是启动,停止,暂停,用于跟踪某些会话时间.我的观点是,我设想应用程序以下列方式运行:
>客户端发送消息
>消息排队
>正在处理队列
但是,例如,我不想阻止反应堆.此外,让我们假设我有一个reload_credentials消息,它是队列中的下一个消息.在从数据库重新加载凭据之前,我不希望处理队列中的任何其他消息.此外,当我处理某个消息(如等待凭据查询完成)时,我想允许其他消息入队.
你能指导我解决这个问题吗?我想我可能不得不使用em-synchrony,但我不确定.
解决方法
使用Postgresql EM驱动程序之一或EM.defer,以便您不会阻止反应堆.
当您收到“reload_credentials”消息时,只需翻转一个标志,该标志会导致所有后续消息入队. ‘reload_credentials’完成后,处理队列中的所有消息.在队列为空之后,翻转导致消息在接收时被处理的标志.
Postgresql的EM驱动程序列于此处:https://github.com/eventmachine/eventmachine/wiki/Protocol-Implementations
module Server def post_init @queue = [] @loading_credentials = false end def recieve_message(type,data) return @queue << [type,data] if @loading_credentials || !@queue.empty? return process_msg(type,data) unless :reload_credentials == type @loading_credentials = true reload_credentials do @loading_credentials = false process_queue end end def reload_credentials(&when_done) EM.defer( proc { query_and_load_credentials },when_done ) end def process_queue while (type,data = @queue.shift) process_msg(type,data) end end # lots of other methods end EM.start_server(HOST,PORT,Server)
如果您希望所有连接在任何连接收到“reload_connections”消息时对消息进行排队,则必须通过本征类进行协调.