firemail
标题:
imap连接原型
[打印本页]
作者:
hechengjin
时间:
2016-7-22 15:39
标题:
imap连接原型
nsImapIncomingServer 维护imap连接队列 和任务队列
nsImapIncomingServer
nsCOMArray<nsIImapUrl> m_urlQueue; 任务队列
nsCOMArray<nsIImapProtocol> m_connectionCache; //imap连接线程队列
GetImapConnection(nsIImapUrl * aImapUrl,..)
{
1.从缓存中取可用连接
connection = m_connectionCache[i];
2.没有可用连接,且连接数少于最大连接数,则创建新连接
CreateProtocolInstance(nsIImapProtocol ** aImapConnection)
3.如果找不到可用连接,则放到队列中
m_urlQueue.AppendObject(aImapUrl); //GetImapConnectionAndLoadUrl
}
复制代码
作者:
hechengjin
时间:
2016-7-25 13:43
5.关于任务执行(
a.内部保持一个任务队列,下一个要执行的命令就从这里取 ??
b.自身可以产生新任务,且可向上层发送
c.任务支持优先级
)
6.线程根据要执行的任务分类(
a.T1(类型1):邮件同步线程,如:同步邮件头512封,下载邮件体512封,再同步邮件头512封,再下载邮件体512封.... 直到所有邮件都下载完。
邮件夹有一定的优先级,且点击的优先下,处理好中断,且从最新的邮件开始下。
新邮件的下载也放这里,注意优先级会提升
b.T2(类型2): 处理本地相关操作任务,如:已读未读 星标 邮件上载 邮件复制、移动等。
对于批量操作用时较长时,要细分任务粒度,且相关交互操作优先级提升
c.T3(类型3): 定时任务执行线程:如:定期更新邮件夹目录,定期同步邮件变动。
d.T4(类型4):邮件体下载线程:针对点击的邮件优先处理,如果没下载完或这个邮件比较大,又切换到读其它的邮件,直接放弃该任务,直接进行下一个任务的下载。
e.处理好相关同步,如a和d,已下载中的邮件,不要重复下载
)
问题:
1.imap连接内部会产生新任务吗?
2.多个imap连接都产生同一个新任务如何处理?
ImapThreadMainLoop
ProcessCurrentURL
ProcessSelectedStateURL
如:
同步某邮件夹的更新的任务(ProcessMailboxUpdate),发现新邮件需要接收
FetchMessage(idsToFetch, kFlags, fetchModifier);
则直接进行这项操作
----------------
加载任务后的处理流程
NS_IMETHODIMP nsImapProtocol::LoadImapUrl(nsIURI * aURL, nsISupports * aConsumer)
{
//1.本地能处理的任务直接处理返回
if (TryToRunUrlLocally(aURL, aConsumer))
return NS_OK;
//2.设置运行的Url
SetupWithUrl(aURL.)
{
m_runningUrl = do_QueryInterface(aURL, &rv);
}
//3.获取url的执行动作
m_runningUrl->GetImapAction(&imapAction);
m_needNoop = (imapAction == nsIImapUrl::nsImapSelectFolder || imapAction == nsIImapUrl::nsImapDeleteAllMsgs);
}
线程函数中处理要运行的Url
ProcessSelectedStateURL(){
case nsIImapUrl::nsImapSelectFolder:
ProcessMailboxUpdate(true);
}
ProcessMailboxUpdate(..)
{
needFolderSync
FetchMessage("1:*", kFlags);
}
FetchMessage(...)
{
SendData(protocolString);
ParseIMAPandCheckForNewMail(protocolString);
}
ParseIMAPandCheckForNewMail(..){
GetServerStateParser().ParseIMAPServerResponse(commandString, aIgnoreBadAndNOResponses);
}
nsImapServerResponseParser.cpp
ParseIMAPServerResponse(..){
response_data();
}
response_data()
{
mailbox_data();
numeric_mailbox_data();
}
numeric_mailbox_data()
{
msg_fetch();
}
msg_fetch()
{
}
//下面这些操作什么时候触发
case nsIImapUrl::nsImapSaveMessageToDisk: // nsImapService::SaveMessageToDisk
case nsIImapUrl::nsImapMsgFetch: //nsImapService::GetHeaders
case nsIImapUrl::nsImapMsgFetchPeek:
case nsIImapUrl::nsImapMsgDownloadForOffline: //上层指定要下载的邮件触发 nsImapService::DownloadMessagesForOffline(const nsACString &messageIds
case nsIImapUrl::nsImapMsgPreview:
一个自动处理离线下载的管理器
nsAutoSyncState::DownloadMessagesForOffline(nsIArray *aMessagesList)
nsAutoSyncManager::TimerCallback
{
autoSyncStateObj->ProcessExistingHeaders(kNumberOfHeadersToProcess, &leftToProcess);
}
--------------
任务的产生(粒度)
线程的分类管理
复制代码
作者:
hechengjin
时间:
2016-7-25 13:45
nsImapIncomingServer
nsCOMArray<nsIImapUrl> m_urlQueue; 任务队列
nsCOMArray<nsIImapProtocol> m_connectionCache; //imap连接线程队列
GetImapConnection(nsIImapUrl * aImapUrl,..)
{
1.从缓存中取可用连接
connection = m_connectionCache[i];
2.没有可用连接,且连接数少于最大连接数,则创建新连接
CreateProtocolInstance(nsIImapProtocol ** aImapConnection)
3.如果找不到可用连接,则放到队列中
m_urlQueue.AppendObject(aImapUrl); //GetImapConnectionAndLoadUrl
}
获取连接以后加载执行任务
rv = aProtocol->LoadImapUrl(mailnewsurl, aConsumer);
nsImapIncomingServer调用nsIImapService为了构建nsIImapUrl,然后再转回来调用nsImapIncomingServer,然后是nsImapProtocol
---------相关难点-----
多个imap线程连接之间,如何进行分开不重复执行相关任务,
imap线程内部永远不会自动产生新任务?
不需要时移除掉此连接 imapServer->RemoveConnection(this);
可自动获取上层的任务
rv = m_imapServerSink->LoadNextQueuedUrl(this, &anotherUrlRun);
LoadImapUrl的调用
nsImapIncomingServer下
GetImapConnectionAndLoadUrl ---- nsImapMockChannel::ReadFromImapConnection OnCacheEntryAvailable AsyncOpen
RetryUrl
LoadNextQueuedUrl
是否可共用连接的判断 :
in selected state can only run url with matching foldername //选择状态下只能是同一邮件夹下的相关任务可以共用
//头收完后,邮件体是如何触发收取的?
HeaderFetchCompleted()
nsImapMailFolder::ParseMsgHdrs(nsIImapProtocol *aProtocol, nsIImapHeaderXferInfo *aHdrXferInfo){
}
!nsImapProtocol::LoadImapUrl(nsIURI * aURL, nsISupports * aConsumer) 行 2205 C++
> !nsImapIncomingServer::LoadNextQueuedUrl(nsIImapProtocol * aProtocol, bool * aResult) 行 575 C++
!`anonymous namespace'::SyncRunnable2<nsIImapMailFolderSink,unsigned int,nsIImapUrl *>::Run() 行 147 C++ ---界面点击触发,不点不触发?
> !nsImapProtocol::LoadImapUrl(nsIURI * aURL, nsISupports * aConsumer) 行 2205 C++
!nsImapIncomingServer::LoadNextQueuedUrl(nsIImapProtocol * aProtocol, bool * aResult) 行 575 C++
!`anonymous namespace'::SyncRunnable2<nsIImapMailFolderSink,unsigned int,nsIImapUrl *>::Run() 行 147 C++ //nsImapMsgDownloadForOffline = 268435506,
nsImapMsgDownloadForOffline 邮件头下载完后,调用自动同步 HeaderFetchCompleted -> nsAutoSyncState
!nsImapService::DownloadMessagesForOffline(const nsACString & messageIds, nsIMsgFolder * aFolder, nsIUrlListener * aUrlListener, nsIMsgWindow * aMsgWindow) 行 3255 C++
!nsAutoSyncState::DownloadMessagesForOffline(nsIArray * aMessagesList) 行 651 C++
!nsAutoSyncManager::DownloadMessagesForOffline(nsIAutoSyncState * aAutoSyncStateObj, unsigned int aSizeLimit) 行 982 C++
!nsAutoSyncManager::OnDownloadQChanged(nsIAutoSyncState * aAutoSyncStateObj) 行 1206 C++
!nsAutoSyncState::PlaceIntoDownloadQ(const nsTArray<unsigned int> & aMsgKeyList) 行 154 C++
> !nsImapMailFolder::HeaderFetchCompleted(nsIImapProtocol * aProtocol) 行 5901 C++
复制代码
欢迎光临 firemail (http://firemail.wang:8088/)
Powered by Discuz! X3