comparison lisp/gnus/gnus-start.el @ 110189:821c596efa5f

Rewrite the Gnus group activation method to be more efficient; nnmh.el (nnmh-request-list-1): Fix up the recursion behavior; Add more changes related to the new methodology for requesting backend data.
author Katsumi Yamaoka <yamaoka@jpl.org>
date Sun, 05 Sep 2010 00:34:16 +0000
parents 5b9f64b04a04
children 1e69e141b6a0
comparison
equal deleted inserted replaced
110188:92e4fa270c92 110189:821c596efa5f
1682 gnus-activate-foreign-newsgroups) 1682 gnus-activate-foreign-newsgroups)
1683 (t 0)) 1683 (t 0))
1684 alevel)) 1684 alevel))
1685 (methods-cache nil) 1685 (methods-cache nil)
1686 (type-cache nil) 1686 (type-cache nil)
1687 scanned-methods info group active method retrieve-groups cmethod 1687 infos info group active method cmethod
1688 method-type) 1688 method-type method-group-list)
1689 (gnus-message 6 "Checking new news...") 1689 (gnus-message 6 "Checking new news...")
1690 1690
1691 (while newsrc 1691 (while newsrc
1692 (setq active (gnus-active (setq group (gnus-info-group 1692 (setq active (gnus-active (setq group (gnus-info-group
1693 (setq info (pop newsrc)))))) 1693 (setq info (pop newsrc))))))
1702 ;; >0 for an active group with messages 1702 ;; >0 for an active group with messages
1703 ;; 0 for an active group with no unread messages 1703 ;; 0 for an active group with no unread messages
1704 ;; nil for non-foreign groups that the user has requested not be checked 1704 ;; nil for non-foreign groups that the user has requested not be checked
1705 ;; t for unchecked foreign groups or bogus groups, or groups that can't 1705 ;; t for unchecked foreign groups or bogus groups, or groups that can't
1706 ;; be checked, for one reason or other. 1706 ;; be checked, for one reason or other.
1707 (when (setq method (gnus-info-method info)) 1707
1708 ;; First go through all the groups, see what select methods they
1709 ;; belong to, and then collect them into lists per unique select
1710 ;; method.
1711 (if (not (setq method (gnus-info-method info)))
1712 (setq method gnus-select-method)
1708 (if (setq cmethod (assoc method methods-cache)) 1713 (if (setq cmethod (assoc method methods-cache))
1709 (setq method (cdr cmethod)) 1714 (setq method (cdr cmethod))
1710 (setq cmethod (inline (gnus-server-get-method nil method))) 1715 (setq cmethod (inline (gnus-server-get-method nil method)))
1711 (push (cons method cmethod) methods-cache) 1716 (push (cons method cmethod) methods-cache)
1712 (setq method cmethod))) 1717 (setq method cmethod)))
1713 (when (and method 1718 (setq method-group-list (assoc method type-cache))
1714 (not (setq method-type (cdr (assoc method type-cache))))) 1719 (unless method-group-list
1715 (setq method-type 1720 (setq method-type
1716 (cond 1721 (cond
1717 ((gnus-secondary-method-p method) 1722 ((gnus-secondary-method-p method)
1718 'secondary) 1723 'secondary)
1719 ((inline (gnus-server-equal gnus-select-method method)) 1724 ((inline (gnus-server-equal gnus-select-method method))
1720 'primary) 1725 'primary)
1721 (t 1726 (t
1722 'foreign))) 1727 'foreign)))
1723 (push (cons method method-type) type-cache)) 1728 (push (setq method-group-list (list method method-type nil))
1724 1729 type-cache))
1725 (cond ((and method (eq method-type 'foreign)) 1730 (setcar (nthcdr 2 method-group-list)
1726 ;; These groups are foreign. Check the level. 1731 (cons info (nth 2 method-group-list))))
1727 (if (<= (gnus-info-level info) foreign-level) 1732
1728 (when (setq active (gnus-activate-group group 'scan)) 1733 ;; Sort the methods based so that the primary and secondary
1729 ;; Let the Gnus agent save the active file. 1734 ;; methods come first. This is done for legacy reasons to try to
1730 (when (and gnus-agent active (gnus-online method)) 1735 ;; ensure that side-effect behaviour doesn't change from previous
1731 (gnus-agent-save-group-info 1736 ;; Gnus versions.
1732 method (gnus-group-real-name group) active)) 1737 (setq type-cache
1733 (unless (inline (gnus-virtual-group-p group)) 1738 (sort (nreverse type-cache)
1734 (inline (gnus-close-group group))) 1739 (lambda (c1 c2)
1735 (when (fboundp (intern (concat (symbol-name (car method)) 1740 (< (gnus-method-rank (cadr c1) (car c1))
1736 "-request-update-info"))) 1741 (gnus-method-rank (cadr c2) (car c2))))))
1737 (inline (gnus-request-update-info info method)))) 1742
1738 (if (and level 1743 (while type-cache
1739 ;; If `active' is nil that means the group has 1744 (setq method (nth 0 (car type-cache))
1740 ;; never been read, the group should be marked 1745 method-type (nth 1 (car type-cache))
1741 ;; as having never been checked (see below). 1746 infos (nth 2 (car type-cache)))
1742 active 1747 (pop type-cache)
1743 (> (gnus-info-level info) level)) 1748
1744 ;; Don't check groups of which levels are higher 1749 ;; See if any of the groups from this method require updating.
1745 ;; than the one that a user specified. 1750 (when (block nil
1746 (setq active 'ignore)))) 1751 (dolist (info infos)
1747 ;; These groups are native or secondary. 1752 (when (<= (gnus-info-level info)
1748 ((> (gnus-info-level info) alevel) 1753 (if (eq method-type 'foreign)
1749 ;; We don't want these groups. 1754 foreign-level
1750 (setq active 'ignore)) 1755 alevel))
1751 ;; Activate groups. 1756 (return t))))
1752 ((not gnus-read-active-file) 1757 (gnus-read-active-for-groups method infos)
1753 (if (gnus-check-backend-function 'retrieve-groups group) 1758 (dolist (info infos)
1754 ;; if server support gnus-retrieve-groups we push 1759 (inline (gnus-get-unread-articles-in-group
1755 ;; the group onto retrievegroups for later checking 1760 info (gnus-active (gnus-info-group info)))))))
1756 (if (assoc method retrieve-groups)
1757 (setcdr (assoc method retrieve-groups)
1758 (cons group (cdr (assoc method retrieve-groups))))
1759 (push (list method group) retrieve-groups))
1760 ;; hack: `nnmail-get-new-mail' changes the mail-source depending
1761 ;; on the group, so we must perform a scan for every group
1762 ;; if the users has any directory mail sources.
1763 ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil,
1764 ;; for it scan all spool files even when the groups are
1765 ;; not required.
1766 (if (and
1767 (or nnmail-scan-directory-mail-source-once
1768 (null (assq 'directory mail-sources)))
1769 (member method scanned-methods))
1770 (setq active (gnus-activate-group group))
1771 (setq active (gnus-activate-group group 'scan))
1772 (push method scanned-methods))
1773 (when active
1774 (gnus-close-group group)))))
1775
1776 ;; Get the number of unread articles in the group.
1777 (cond
1778 ((eq active 'ignore)
1779 ;; Don't do anything.
1780 )
1781 (active
1782 (inline (gnus-get-unread-articles-in-group info active t)))
1783 (t
1784 ;; The group couldn't be reached, so we nix out the number of
1785 ;; unread articles and stuff.
1786 (gnus-set-active group nil)
1787 (let ((tmp (gnus-group-entry group)))
1788 (when tmp
1789 (setcar tmp t))))))
1790
1791 ;; iterate through groups on methods which support gnus-retrieve-groups
1792 ;; and fetch a partial active file and use it to find new news.
1793 (dolist (rg retrieve-groups)
1794 (let ((method (or (car rg) gnus-select-method))
1795 (groups (cdr rg)))
1796 (when (gnus-check-server method)
1797 ;; Request that the backend scan its incoming messages.
1798 (when (gnus-check-backend-function 'request-scan (car method))
1799 (gnus-request-scan nil method))
1800 (gnus-read-active-file-2
1801 (mapcar (lambda (group) (gnus-group-real-name group)) groups)
1802 method)
1803 (dolist (group groups)
1804 (cond
1805 ((setq active (gnus-active (gnus-info-group
1806 (setq info (gnus-get-info group)))))
1807 (inline (gnus-get-unread-articles-in-group info active t)))
1808 (t
1809 ;; The group couldn't be reached, so we nix out the number of
1810 ;; unread articles and stuff.
1811 (gnus-set-active group nil)
1812 (setcar (gnus-group-entry group) t)))))))
1813
1814 (gnus-message 6 "Checking new news...done"))) 1761 (gnus-message 6 "Checking new news...done")))
1762
1763 (defun gnus-method-rank (type method)
1764 (cond
1765 ((eq type 'primary)
1766 1)
1767 ;; Compute the rank of the secondary methods based on where they
1768 ;; are in the secondary select list.
1769 ((eq type 'secondary)
1770 (let ((i 2))
1771 (block nil
1772 (dolist (smethod gnus-secondary-select-methods)
1773 (when (equalp method smethod)
1774 (return i))
1775 (incf i))
1776 i)))
1777 ;; Just say that all foreign groups have the same rank.
1778 (t
1779 100)))
1780
1781 (defun gnus-read-active-for-groups (method infos)
1782 (with-current-buffer nntp-server-buffer
1783 (cond
1784 ((gnus-check-backend-function 'retrieve-groups (car method))
1785 (gnus-read-active-file-2
1786 (mapcar (lambda (info)
1787 (gnus-group-real-name (gnus-info-group info)))
1788 infos)
1789 method))
1790 ((gnus-check-backend-function 'request-list (car method))
1791 (gnus-read-active-file-1 method nil))
1792 (t
1793 (dolist (info infos)
1794 (gnus-activate-group (gnus-info-group info) nil nil method))))))
1815 1795
1816 ;; Create a hash table out of the newsrc alist. The `car's of the 1796 ;; Create a hash table out of the newsrc alist. The `car's of the
1817 ;; alist elements are used as keys. 1797 ;; alist elements are used as keys.
1818 (defun gnus-make-hashtable-from-newsrc-alist () 1798 (defun gnus-make-hashtable-from-newsrc-alist ()
1819 (let ((alist gnus-newsrc-alist) 1799 (let ((alist gnus-newsrc-alist)
2041 (concat " from " where) "") 2021 (concat " from " where) "")
2042 (car method))) 2022 (car method)))
2043 (gnus-message 5 mesg) 2023 (gnus-message 5 mesg)
2044 (when (gnus-check-server method) 2024 (when (gnus-check-server method)
2045 ;; Request that the backend scan its incoming messages. 2025 ;; Request that the backend scan its incoming messages.
2046 (when (gnus-check-backend-function 'request-scan (car method)) 2026 (when (and gnus-agent
2027 (gnus-online method)
2028 (gnus-check-backend-function 'request-scan (car method)))
2047 (gnus-request-scan nil method)) 2029 (gnus-request-scan nil method))
2048 (cond 2030 (cond
2049 ((and (eq gnus-read-active-file 'some) 2031 ((and (eq gnus-read-active-file 'some)
2050 (gnus-check-backend-function 'retrieve-groups (car method)) 2032 (gnus-check-backend-function 'retrieve-groups (car method))
2051 (not force)) 2033 (not force))