1010from itertools import chain
1111from typing import Any
1212from typing import NamedTuple
13- from typing import TYPE_CHECKING
1413
1514from .._parser import EntryPair
1615from .._parser import EntryPairBase
2322from .._types import FeedForUpdate
2423from .._types import FeedToUpdate
2524from .._types import FeedUpdateIntent
26- from .._utils import MapFunction
25+ from .._utils import make_pool_map
2726from .._utils import PrefixLogger
2827from ..exceptions import ParseError
2928from ..types import ExceptionInfo
3029from ..types import UpdateConfig
3130from .base import PipelineBase
3231
33- if TYPE_CHECKING : # pragma: no cover
34- from ..core import Reader
35-
3632log = logging .getLogger ("reader" )
3733
3834HASH_CHANGED_LIMIT = 24
@@ -53,6 +49,19 @@ class Decider:
5349
5450 old_feed : FeedForUpdate
5551 now : datetime
52+
53+ # global now, is used as first_updated_epoch for all new entries,
54+ # so that the subset of new entries from an update appears before
55+ # all others and the entries in it are sorted by published/updated;
56+ # if we used last_updated (now) for this, they would be sorted
57+ # by feed order first (due to now increasing for each feed).
58+ #
59+ # A side effect of relying first_updated_epoch for ordering is that
60+ # for the second of two new feeds updated in the same update_feeds()
61+ # call, first_updated_epoch != last_updated.
62+ #
63+ # However, added == last_updated for the first update.
64+ #
5665 global_now : datetime
5766 config : UpdateConfig
5867 log : Any = log
@@ -325,7 +334,7 @@ def next_update_after(now: datetime, interval: int, jitter: float = 0) -> dateti
325334 return rv
326335
327336
328- @dataclass ( frozen = True )
337+ @dataclass
329338class Pipeline (PipelineBase [FeedData , EntryData , FeedUpdateIntent , EntryUpdateIntent ]):
330339 """Update multiple feeds.
331340
@@ -349,23 +358,6 @@ class Pipeline(PipelineBase[FeedData, EntryData, FeedUpdateIntent, EntryUpdateIn
349358
350359 """
351360
352- reader : Reader
353-
354- # global now, is used as first_updated_epoch for all new entries,
355- # so that the subset of new entries from an update appears before
356- # all others and the entries in it are sorted by published/updated;
357- # if we used last_updated (now) for this, they would be sorted
358- # by feed order first (due to now increasing for each feed).
359- #
360- # A side effect of relying first_updated_epoch for ordering is that
361- # for the second of two new feeds updated in the same update_feeds()
362- # call, first_updated_epoch != last_updated.
363- #
364- # However, added == last_updated for the first update.
365- #
366- global_now : datetime
367-
368- map : MapFunction [Any , Any ]
369361 decider = Decider
370362
371363 def parse_feeds (self , feeds : Iterable [FeedForUpdate ]) -> Iterable [ParseResult ]:
@@ -388,10 +380,11 @@ def parser_process_feeds_for_update(
388380 except ParseError as e :
389381 parse_errors .append (ParseResult (feed , e ))
390382
391- feeds = parser_process_feeds_for_update (feeds )
392- feeds = map (self .decider .process_feed_for_update , feeds )
393- parse_results = self .reader ._parser .parallel (feeds , self .map )
394- return chain (parse_results , parse_errors )
383+ with make_pool_map (self .workers ) as parallel_map :
384+ feeds = parser_process_feeds_for_update (feeds )
385+ feeds = map (self .decider .process_feed_for_update , feeds )
386+ parse_results = self .reader ._parser .parallel (feeds , parallel_map )
387+ yield from chain (parse_results , parse_errors )
395388
396389 def make_intents (
397390 self , result : ParseResult , entries : Iterable [EntryPair ]
@@ -411,7 +404,7 @@ def make_intents(
411404
412405 return self .decider .make_intents (
413406 self .reader ._now (),
414- self .global_now ,
407+ self .now ,
415408 config ,
416409 result ,
417410 entries ,
0 commit comments