Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ghc-async for openSUSE:Factory 
checked in at 2021-03-10 08:54:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-async (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-async.new.2378 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-async"

Wed Mar 10 08:54:31 2021 rev:24 rq:877615 version:2.2.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-async/ghc-async.changes      2020-12-22 
11:34:53.713224277 +0100
+++ /work/SRC/openSUSE:Factory/.ghc-async.new.2378/ghc-async.changes    
2021-03-10 08:56:35.974848373 +0100
@@ -1,0 +2,8 @@
+Fri Feb 19 23:02:58 UTC 2021 - [email protected]
+
+- Update async to version 2.2.3.
+  ## Changes in 2.2.3:
+
+   - Documentation fixes
+
+-------------------------------------------------------------------

Old:
----
  async-2.2.2.tar.gz
  async.cabal

New:
----
  async-2.2.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-async.spec ++++++
--- /var/tmp/diff_new_pack.089E3F/_old  2021-03-10 08:56:36.534848951 +0100
+++ /var/tmp/diff_new_pack.089E3F/_new  2021-03-10 08:56:36.538848956 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-async
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,13 +19,12 @@
 %global pkg_name async
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        2.2.2
+Version:        2.2.3
 Release:        0
 Summary:        Run IO operations asynchronously and wait for their results
 License:        BSD-3-Clause
 URL:            https://hackage.haskell.org/package/%{pkg_name}
 Source0:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
-Source1:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal#/%{pkg_name}.cabal
 BuildRequires:  ghc-Cabal-devel
 BuildRequires:  ghc-hashable-devel
 BuildRequires:  ghc-rpm-macros
@@ -64,7 +63,6 @@
 
 %prep
 %autosetup -n %{pkg_name}-%{version}
-cp -p %{SOURCE1} %{pkg_name}.cabal
 
 %build
 %ghc_lib_build

++++++ async-2.2.2.tar.gz -> async-2.2.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/async-2.2.2/Control/Concurrent/Async.hs 
new/async-2.2.3/Control/Concurrent/Async.hs
--- old/async-2.2.2/Control/Concurrent/Async.hs 2019-06-06 09:11:39.000000000 
+0200
+++ new/async-2.2.3/Control/Concurrent/Async.hs 2021-02-15 09:41:48.000000000 
+0100
@@ -24,65 +24,123 @@
 -- "Control.Concurrent".  The main additional functionality it
 -- provides is the ability to wait for the return value of a thread,
 -- but the interface also provides some additional safety and
--- robustness over using threads and @MVar@ directly.
+-- robustness over using 'forkIO' threads and @MVar@ directly.
+--
+-- == High-level API
+--
+-- @async@'s high-level API spawns /lexically scoped/ threads,
+-- ensuring the following key poperties that make it safer to use
+-- than using plain 'forkIO':
+--
+-- 1. No exception is swallowed (waiting for results propagates exceptions).
+-- 2. No thread is leaked (left running unintentionally).
+--
+-- (This is done using the 'Control.Exception.bracket' pattern to work in 
presence
+-- of synchornous and asynchronous exceptions.)
+--
+-- __Most practical/production code should only use the high-level API__.
 --
 -- The basic type is @'Async' a@, which represents an asynchronous
 -- @IO@ action that will return a value of type @a@, or die with an
--- exception.  An @Async@ corresponds to a thread, and its 'ThreadId'
--- can be obtained with 'asyncThreadId', although that should rarely
--- be necessary.
+-- exception.  An 'Async' is a wrapper around a low-level 'forkIO' thread.
+--
+-- The fundamental function to spawn threads with the high-level API is
+-- 'withAsync'.
 --
 -- For example, to fetch two web pages at the same time, we could do
 -- this (assuming a suitable @getURL@ function):
 --
--- >    do a1 <- async (getURL url1)
--- >       a2 <- async (getURL url2)
--- >       page1 <- wait a1
--- >       page2 <- wait a2
--- >       ...
---
--- where 'async' starts the operation in a separate thread, and
--- 'wait' waits for and returns the result.  If the operation
--- throws an exception, then that exception is re-thrown by
--- 'wait'.  This is one of the ways in which this library
--- provides some additional safety: it is harder to accidentally
--- forget about exceptions thrown in child threads.
---
--- A slight improvement over the previous example is this:
---
--- >       withAsync (getURL url1) $ \a1 -> do
--- >       withAsync (getURL url2) $ \a2 -> do
--- >       page1 <- wait a1
--- >       page2 <- wait a2
--- >       ...
+-- > withAsync (getURL url1) $ \a1 -> do
+-- >   withAsync (getURL url2) $ \a2 -> do
+-- >     page1 <- wait a1
+-- >     page2 <- wait a2
+-- >     ...
+--
+-- where 'withAsync' starts the operation in a separate thread, and
+-- 'wait' waits for and returns the result.
+--
+-- * If the operation throws an exception, then that exception is re-thrown
+--   by 'wait'. This ensures property (1): No exception is swallowed.
+-- * If an exception bubbles up through a 'withAsync', then the 'Async'
+--   it spawned is 'cancel'ed. This ensures property (2): No thread is leaked.
+--
+-- Often we do not care to work manually with 'Async' handles like
+-- @a1@ and @a2@. Instead, we want to express high-level objectives like
+-- performing two or more tasks concurrently, and waiting for one or all
+-- of them to finish.
+--
+-- For example, the pattern of performing two IO actions concurrently and
+-- waiting for both their results is packaged up in a combinator 
'concurrently',
+-- so we can further shorten the above example to:
+--
+-- > (page1, page2) <- concurrently (getURL url1) (getURL url2)
+-- > ...
+--
+-- The section __/High-level utilities/__ covers the most
+-- common high-level objectives, including:
+--
+-- * Waiting for 2 results ('concurrently').
+-- * Waiting for many results ('mapConcurrently' / 'forConcurrently').
+-- * Waiting for the first of 2 results ('race').
+-- * Waiting for arbitrary nestings of "all of /N/" and "the first of /N/"
+--   results with the 'Concurrently' newtype and its 'Applicative' and
+--   'Alternative' instances.
+--
+-- Click here to scroll to that section:
+-- "Control.Concurrent.Async#high-level-utilities".
+--
+-- == Low-level API
+--
+-- Some use cases require parallelism that is not lexically scoped.
+--
+-- For those, the low-level function 'async' can be used as a direct
+-- equivalent of 'forkIO':
+--
+-- > -- Do NOT use this code in production, it has a flaw (explained below).
+-- > do
+-- >   a1 <- async (getURL url1)
+-- >   a2 <- async (getURL url2)
+-- >   page1 <- wait a1
+-- >   page2 <- wait a2
+-- >   ...
+--
+-- In contrast to 'withAsync', this code has a problem.
+--
+-- It still fulfills property (1) in that an exception arising from
+-- @getUrl@ will be re-thrown by 'wait', but it does not fulfill
+-- property (2).
+-- Consider the case when the first 'wait' throws an exception; then the
+-- second 'wait' will not happen, and the second 'async' may be left
+-- running in the background, possibly indefinitely.
 --
 -- 'withAsync' is like 'async', except that the 'Async' is
 -- automatically killed (using 'uninterruptibleCancel') if the
--- enclosing IO operation returns before it has completed.  Consider
--- the case when the first 'wait' throws an exception; then the second
--- 'Async' will be automatically killed rather than being left to run
--- in the background, possibly indefinitely.  This is the second way
--- that the library provides additional safety: using 'withAsync'
--- means we can avoid accidentally leaving threads running.
+-- enclosing IO operation returns before it has completed.
 -- Furthermore, 'withAsync' allows a tree of threads to be built, such
 -- that children are automatically killed if their parents die for any
 -- reason.
 --
--- The pattern of performing two IO actions concurrently and waiting
--- for their results is packaged up in a combinator 'concurrently', so
--- we can further shorten the above example to:
+-- If you need to use the low-level API, ensure that you gurantee
+-- property (2) by other means, such as 'link'ing asyncs that need
+-- to die together, and protecting against asynchronous exceptions
+-- using 'Control.Exception.bracket', 'Control.Exception.mask',
+-- or other functions from "Control.Exception".
 --
--- >       (page1, page2) <- concurrently (getURL url1) (getURL url2)
--- >       ...
+-- == Miscellaneous
 --
 -- The 'Functor' instance can be used to change the result of an
 -- 'Async'.  For example:
 --
--- > ghci> a <- async (return 3)
--- > ghci> wait a
--- > 3
--- > ghci> wait (fmap (+1) a)
+-- > ghci> withAsync (return 3) (\a -> wait (fmap (+1) a))
 -- > 4
+--
+-- === Resource exhaustion
+--
+-- As with all concurrent programming, keep in mind that while
+-- Haskell's cooperative ("green") multithreading carries low overhead,
+-- spawning too many of them at the same time may lead to resource exhaustion
+-- (of memory, file descriptors, or other limited resources), given that the
+-- actions running in the threads consume these resources.
 
 -----------------------------------------------------------------------------
 
@@ -90,8 +148,8 @@
 
     -- * Asynchronous actions
     Async,
-    -- ** Spawning
-    async, asyncBound, asyncOn, asyncWithUnmask, asyncOnWithUnmask,
+
+    -- * High-level API
 
     -- ** Spawning with automatic 'cancel'ation
     withAsync, withAsyncBound, withAsyncOn, withAsyncWithUnmask,
@@ -101,33 +159,40 @@
     wait, poll, waitCatch, asyncThreadId,
     cancel, uninterruptibleCancel, cancelWith, AsyncCancelled(..),
 
-    -- ** STM operations
+    -- ** #high-level-utilities# High-level utilities
+    race, race_,
+    concurrently, concurrently_,
+    mapConcurrently, forConcurrently,
+    mapConcurrently_, forConcurrently_,
+    replicateConcurrently, replicateConcurrently_,
+    Concurrently(..),
+    compareAsyncs,
+
+    -- ** Specialised operations
+
+    -- *** STM operations
     waitSTM, pollSTM, waitCatchSTM,
 
-    -- ** Waiting for multiple 'Async's
+    -- *** Waiting for multiple 'Async's
     waitAny, waitAnyCatch, waitAnyCancel, waitAnyCatchCancel,
     waitEither, waitEitherCatch, waitEitherCancel, waitEitherCatchCancel,
     waitEither_,
     waitBoth,
 
-    -- ** Waiting for multiple 'Async's in STM
+    -- *** Waiting for multiple 'Async's in STM
     waitAnySTM, waitAnyCatchSTM,
     waitEitherSTM, waitEitherCatchSTM,
     waitEitherSTM_,
     waitBothSTM,
 
+    -- * Low-level API
+
+    -- ** Spawning (low-level API)
+    async, asyncBound, asyncOn, asyncWithUnmask, asyncOnWithUnmask,
+
     -- ** Linking
     link, linkOnly, link2, link2Only, ExceptionInLinkedThread(..),
 
-    -- * Convenient utilities
-    race, race_,
-    concurrently, concurrently_,
-    mapConcurrently, forConcurrently,
-    mapConcurrently_, forConcurrently_,
-    replicateConcurrently, replicateConcurrently_,
-    Concurrently(..),
-    compareAsyncs,
-
   ) where
 
 import Control.Concurrent.STM
@@ -185,11 +250,16 @@
 instance Functor Async where
   fmap f (Async a w) = Async a (fmap (fmap f) w)
 
--- | Compare two Asyncs that may have different types by their ThreadId.
+-- | Compare two Asyncs that may have different types by their 'ThreadId'.
 compareAsyncs :: Async a -> Async b -> Ordering
 compareAsyncs (Async t1 _) (Async t2 _) = compare t1 t2
 
 -- | Spawn an asynchronous action in a separate thread.
+--
+-- Like for 'forkIO', the action may be left running unintentinally
+-- (see module-level documentation for details).
+--
+-- __Use 'withAsync' style functions wherever you can instead!__
 async :: IO a -> IO (Async a)
 async = inline asyncUsing rawForkIO
 
@@ -516,7 +586,10 @@
 --
 {-# INLINE waitBoth #-}
 waitBoth :: Async a -> Async b -> IO (a,b)
-waitBoth left right = atomically (waitBothSTM left right)
+waitBoth left right = tryAgain $ atomically (waitBothSTM left right)
+  where
+    -- See: https://github.com/simonmar/async/issues/14
+    tryAgain f = f `catch` \BlockedIndefinitelyOnSTM -> f
 
 -- | A version of 'waitBoth' that can be used inside an STM transaction.
 --
@@ -647,6 +720,11 @@
 -- >   waitBoth a b
 concurrently :: IO a -> IO b -> IO (a,b)
 
+-- | 'concurrently', but ignore the result values
+--
+-- @since 2.1.1
+concurrently_ :: IO a -> IO b -> IO ()
+
 #define USE_ASYNC_VERSIONS 0
 
 #if USE_ASYNC_VERSIONS
@@ -656,16 +734,15 @@
   withAsync right $ \b ->
   waitEither a b
 
-race_ left right =
-  withAsync left $ \a ->
-  withAsync right $ \b ->
-  waitEither_ a b
+race_ left right = void $ race left right
 
 concurrently left right =
   withAsync left $ \a ->
   withAsync right $ \b ->
   waitBoth a b
 
+concurrently_ left right = void $ concurrently left right
+
 #else
 
 -- MVar versions of race/concurrently
@@ -744,9 +821,19 @@
         stop
         return r
 
+concurrently_ left right = concurrently' left right (collect 0)
+  where
+    collect 2 _ = return ()
+    collect i m = do
+        e <- m
+        case e of
+            Left ex -> throwIO ex
+            Right _ -> collect (i + 1 :: Int) m
+
+
 #endif
 
--- | maps an @IO@-performing function over any @Traversable@ data
+-- | Maps an 'IO'-performing function over any 'Traversable' data
 -- type, performing all the @IO@ actions concurrently, and returning
 -- the original data structure with the arguments replaced by the
 -- results.
@@ -758,6 +845,10 @@
 --
 -- > pages <- mapConcurrently getURL ["url1", "url2", "url3"]
 --
+-- Take into account that @async@ will try to immediately spawn a thread
+-- for each element of the @Traversable@, so running this on large
+-- inputs without care may lead to resource exhaustion (of memory,
+-- file descriptors, or other limited resources).
 mapConcurrently :: Traversable t => (a -> IO b) -> t a -> IO (t b)
 mapConcurrently f = runConcurrently . traverse (Concurrently . f)
 
@@ -769,29 +860,16 @@
 forConcurrently :: Traversable t => t a -> (a -> IO b) -> IO (t b)
 forConcurrently = flip mapConcurrently
 
--- | `mapConcurrently_` is `mapConcurrently` with the return value discarded,
--- just like @mapM_@.
+-- | `mapConcurrently_` is `mapConcurrently` with the return value discarded;
+-- a concurrent equivalent of 'mapM_'.
 mapConcurrently_ :: F.Foldable f => (a -> IO b) -> f a -> IO ()
 mapConcurrently_ f = runConcurrently . F.foldMap (Concurrently . void . f)
 
--- | `forConcurrently_` is `forConcurrently` with the return value discarded,
--- just like @forM_@.
+-- | `forConcurrently_` is `forConcurrently` with the return value discarded;
+-- a concurrent equivalent of 'forM_'.
 forConcurrently_ :: F.Foldable f => f a -> (a -> IO b) -> IO ()
 forConcurrently_ = flip mapConcurrently_
 
--- | 'concurrently', but ignore the result values
---
--- @since 2.1.1
-concurrently_ :: IO a -> IO b -> IO ()
-concurrently_ left right = concurrently' left right (collect 0)
-  where
-    collect 2 _ = return ()
-    collect i m = do
-        e <- m
-        case e of
-            Left ex -> throwIO ex
-            Right _ -> collect (i + 1 :: Int) m
-
 -- | Perform the action in the given number of threads.
 --
 -- @since 2.1.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/async-2.2.2/async.cabal new/async-2.2.3/async.cabal
--- old/async-2.2.2/async.cabal 2019-06-06 09:11:39.000000000 +0200
+++ new/async-2.2.3/async.cabal 2021-02-15 09:41:48.000000000 +0100
@@ -1,5 +1,5 @@
 name:                async
-version:             2.2.2
+version:             2.2.3
 -- don't forget to update ./changelog.md!
 synopsis:            Run IO operations asynchronously and wait for their 
results
 
@@ -34,7 +34,7 @@
 cabal-version:       >=1.10
 homepage:            https://github.com/simonmar/async
 bug-reports:         https://github.com/simonmar/async/issues
-tested-with:         GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, 
GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, GHC==7.2.2, GHC==7.0.4
+tested-with:         GHC==8.10.1, GHC==8.8.3, GHC==8.6.5, GHC==8.4.4, 
GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, 
GHC==7.2.2, GHC==7.0.4
 
 extra-source-files:
     changelog.md
@@ -50,14 +50,14 @@
     if impl(ghc>=7.1)
         other-extensions: Trustworthy
     exposed-modules:     Control.Concurrent.Async
-    build-depends:       base >= 4.3 && < 4.14, hashable >= 1.1.2.0 && < 1.4, 
stm >= 2.2 && < 2.6
+    build-depends:       base >= 4.3 && < 4.16, hashable >= 1.1.2.0 && < 1.4, 
stm >= 2.2 && < 2.6
 
 test-suite test-async
     default-language: Haskell2010
     type:       exitcode-stdio-1.0
     hs-source-dirs: test
     main-is:    test-async.hs
-    build-depends: base >= 4.3 && < 4.14,
+    build-depends: base >= 4.3 && < 4.15,
                    async,
                    stm,
                    test-framework,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/async-2.2.2/changelog.md new/async-2.2.3/changelog.md
--- old/async-2.2.2/changelog.md        2019-06-06 09:11:39.000000000 +0200
+++ new/async-2.2.3/changelog.md        2021-02-15 09:41:48.000000000 +0100
@@ -1,3 +1,7 @@
+## Changes in 2.2.3:
+
+ - Documentation fixes
+
 ## Changes in 2.2.2:
 
  - Builds with GHC 8.6.x

Reply via email to