很高兴听到您正在使用Celluloid
. 好问题。
不确定您如何创建和维护连接,无论TCPSocket
您是否有能力管理。如果你有能力TCPSocket
直接管理一个,你应该和它本身Celluloid::IO
一样使用Celluloid
。我也不知道你把从 IMAP 连接中提取的信息放在哪里。这两件事会影响你的策略。
您的方法还不错,但是是的-可以通过添加一些东西来完成繁重的投票工作来改进它;另一个只持有account_info
;以及触发工作和/或维持空闲状态的最终参与者。所以你最终会得到ImapWorker
(a pool) ImapMaintainer
, 和ImapRegistry
. 在这里,我想知道既然您正在轮询,是否需要保持开放连接而不是允许推送信息。如果您计划进行轮询并仍然保持连接打开,那么这三个参与者会执行以下操作:
ImapRegistry
把你account_info
放在一个Hash
. 这将有方法,如add
,get
和remove
。我推荐一个Hash
of这样你就可以在and@credentials
之间使用相同的 ID ;一个在其中保存实时连接,一个在其中保存实例。两者和都由相同的 ID 访问,但一个保持易失连接,而另一个只有静态数据可用于在必要时重新创建连接。通过这种方式,您的举重运动员可能会死亡,重生,整个系统可以自行再生。ImapMaintainer
ImapRegistry
@connections
account_info
@credentials
@connections
@credentials
ImapMaintainer
将在其中包含实际@connections
内容,并在其中every( interval ) { }
内置任务,添加到 whenaccount_info
存储在ImapRegistry
. 我看到了两项任务,具体取决于您计划轮询的频率。一种可能是简单地触摸 IMAP 连接来维护它,另一种可能是使用 . 轮询 IMAP 服务器ImapWorker
。就像说的那样,ImapWorker
将是一个保存在池中的池。所以它有, ,和。可能是一种情况,或者您可以在创建连接时为每个连接添加一个计时器。ImapMaintainer
@worker
@connections
@worker
#polling
#keepalive
polling
@connections.each
ImapWorker
有两种方法...一种是#touch
保持连接活跃。主要的是#poll
,它接受您维护的连接,并在其上运行轮询过程。该方法返回信息,甚至更好地存储它,然后工作人员返回到@worker
池中。这将给您带来的好处是让轮询过程发生在一个单独的线程中,而不仅仅是一个单独的光纤,并且还允许将最棘手的方面排除在最强大但最不知情的类型的参与者之外。
向后工作,如果ImapRegistry
接收#add
,它存储account_info
并提供ImapMaintainer
创建连接的对象和计时器(但它忘记account_info
并仅创建连接和计时器,或者只是创建连接并让一个大计时器维护与@worker
它的连接pool.ImapMaintainer
不可避免地会碰到计时器,因此在计时器的开始和结束时,它可以检查其连接。如果连接由于某种原因消失了,它可以用@registry.get
信息重新创建它。在其计时器提示的任务中,它可以运行@worker.poll
或@worker.alive
.
这说明了上述要求,显示了初始化器如何将参与者系统组合在一起,并且具有所提到的方法的不完整框架。
WORKERS = 9 #de arbitrarily chosen
class ImapRegistry
include Celluloid
def initialize
@maintainer = ImapMaintainer.supervise
@credentials = {}
end
def add( account_info )
...
end
def get( id )
...
end
def remove( id )
...
end
end
class ImapMaintainer
include Celluloid
def initialize
@worker = ImapWorker.pool size: WORKERS
@connections = {}
end
def add( id, credential )
...
end
def remove( id )
...
end
#de These exist if there is one big timer:
def polling
...
end
def keepalive
...
end
end
class ImapWorker
include Celluloid
def initialize
#de Nothing needed.
end
def poll( connection )
...
end
def touch( connection )
...
end
end
registry = ImapRegistry.supervise
我喜欢Celluloid
并希望你能取得很大的成功。请询问您是否需要澄清任何事情,但这至少是您需要考虑的另一种策略。