@@ -19,9 +19,9 @@ module Kafka.Consumer
19
19
where
20
20
21
21
import Control.Arrow (left , (&&&) )
22
- import Control.Concurrent (forkIO , rtsSupportsBoundThreads )
22
+ import Control.Concurrent (forkIO , rtsSupportsBoundThreads , withMVar )
23
23
import Control.Exception (bracket )
24
- import Control.Monad (forM_ , void , when )
24
+ import Control.Monad (forM_ , mapM_ , void , when )
25
25
import Control.Monad.IO.Class (MonadIO (liftIO ))
26
26
import Control.Monad.Trans.Except (ExceptT (ExceptT ), runExceptT )
27
27
import Data.Bifunctor (bimap , first )
@@ -38,7 +38,7 @@ import Kafka.Consumer.Convert (fromMessagePtr, fromNativeTop
38
38
import Kafka.Consumer.Types (KafkaConsumer (.. ))
39
39
import Kafka.Internal.CancellationToken as CToken
40
40
import Kafka.Internal.RdKafka (RdKafkaRespErrT (.. ), RdKafkaTopicPartitionListTPtr , RdKafkaTypeT (.. ), newRdKafkaT , newRdKafkaTopicPartitionListT , newRdKafkaTopicT , rdKafkaAssignment , rdKafkaCommit , rdKafkaCommitted , rdKafkaConfSetDefaultTopicConf , rdKafkaConsumeBatchQueue , rdKafkaConsumeQueue , rdKafkaConsumerClose , rdKafkaConsumerPoll , rdKafkaOffsetsStore , rdKafkaPausePartitions , rdKafkaPollSetConsumer , rdKafkaPosition , rdKafkaQueueDestroy , rdKafkaQueueNew , rdKafkaResumePartitions , rdKafkaSeek , rdKafkaSetLogLevel , rdKafkaSubscribe , rdKafkaSubscription , rdKafkaTopicConfDup , rdKafkaTopicPartitionListAdd )
41
- import Kafka.Internal.Setup (Kafka (.. ), KafkaConf (.. ), KafkaProps (.. ), TopicConf (.. ), TopicProps (.. ), getRdKafka , kafkaConf , topicConf )
41
+ import Kafka.Internal.Setup (Kafka (.. ), KafkaConf (.. ), KafkaProps (.. ), TopicConf (.. ), TopicProps (.. ), getKafkaConf , getRdKafka , kafkaConf , topicConf )
42
42
import Kafka.Internal.Shared (kafkaErrorToMaybe , maybeToLeft , rdKafkaErrorToEither )
43
43
44
44
import Kafka.Consumer.ConsumerProperties as X
@@ -69,17 +69,17 @@ newConsumer :: MonadIO m
69
69
-> Subscription
70
70
-> m (Either KafkaError KafkaConsumer )
71
71
newConsumer props (Subscription ts tp) = liftIO $ do
72
- let cp = case cpUserPolls props of
73
- CallbackModeAsync -> setCallback (rebalanceCallback (\ _ _ -> return () )) <> props
74
- CallbackModeSync -> props
75
- kc@ (KafkaConf kc' qref ct) <- newConsumerConf cp
72
+ let cp = case cpCallbackPollMode props of
73
+ CallbackPollModeAsync -> setCallback (rebalanceCallback (\ _ _ -> return () )) <> props
74
+ CallbackPollModeSync -> props
75
+ kc@ (KafkaConf kc' qref _ ct) <- newConsumerConf cp
76
76
tp' <- topicConf (TopicProps tp)
77
77
_ <- setDefaultTopicConf kc tp'
78
78
rdk <- newRdKafkaT RdKafkaConsumer kc'
79
79
case rdk of
80
80
Left err -> return . Left $ KafkaError err
81
81
Right rdk' -> do
82
- when (cpUserPolls props == CallbackModeAsync ) $ do
82
+ when (cpCallbackPollMode props == CallbackPollModeAsync ) $ do
83
83
msgq <- rdKafkaQueueNew rdk'
84
84
writeIORef qref (Just msgq)
85
85
let kafka = KafkaConsumer (Kafka rdk') kc
@@ -90,21 +90,19 @@ newConsumer props (Subscription ts tp) = liftIO $ do
90
90
forM_ (cpLogLevel cp) (setConsumerLogLevel kafka)
91
91
sub <- subscribe kafka ts
92
92
case sub of
93
- Nothing -> (when (cpUserPolls props == CallbackModeAsync ) $
93
+ Nothing -> (when (cpCallbackPollMode props == CallbackPollModeAsync ) $
94
94
runConsumerLoop kafka ct (Just $ Timeout 100 )) >> return (Right kafka)
95
95
Just err -> closeConsumer kafka >> return (Left err)
96
96
97
97
pollMessage :: MonadIO m
98
98
=> KafkaConsumer
99
99
-> Timeout -- ^ the timeout, in milliseconds
100
100
-> m (Either KafkaError (ConsumerRecord (Maybe BS. ByteString ) (Maybe BS. ByteString ))) -- ^ Left on error or timeout, right for success
101
- pollMessage c@ (KafkaConsumer _ (KafkaConf _ qr _)) (Timeout ms) = liftIO $ do
101
+ pollMessage c@ (KafkaConsumer _ (KafkaConf _ qr _ _ )) (Timeout ms) = liftIO $ do
102
102
mbq <- readIORef qr
103
103
case mbq of
104
104
Nothing -> rdKafkaConsumerPoll (getRdKafka c) ms >>= fromMessagePtr
105
- Just q -> do
106
- pollConsumerEvents c Nothing
107
- rdKafkaConsumeQueue q (fromIntegral ms) >>= fromMessagePtr
105
+ Just q -> rdKafkaConsumeQueue q (fromIntegral ms) >>= fromMessagePtr
108
106
109
107
-- | Polls up to BatchSize messages.
110
108
-- Unlike 'pollMessage' this function does not return usual "timeout" errors.
@@ -116,7 +114,7 @@ pollMessageBatch :: MonadIO m
116
114
-> Timeout
117
115
-> BatchSize
118
116
-> m [Either KafkaError (ConsumerRecord (Maybe BS. ByteString ) (Maybe BS. ByteString ))]
119
- pollMessageBatch c@ (KafkaConsumer _ (KafkaConf _ qr _)) (Timeout ms) (BatchSize b) = liftIO $ do
117
+ pollMessageBatch c@ (KafkaConsumer _ (KafkaConf _ qr _ _ )) (Timeout ms) (BatchSize b) = liftIO $ do
120
118
pollConsumerEvents c Nothing
121
119
mbq <- readIORef qr
122
120
case mbq of
@@ -206,8 +204,7 @@ seek (KafkaConsumer (Kafka k) _) (Timeout timeout) tps = liftIO $
206
204
where
207
205
seekAll = runExceptT $ do
208
206
tr <- traverse (ExceptT . topicPair) tps
209
- void $ traverse (\ (kt, p, o) -> ExceptT (rdSeek kt p o)) tr
210
- return ()
207
+ mapM_ (\ (kt, p, o) -> ExceptT (rdSeek kt p o)) tr
211
208
212
209
rdSeek kt (PartitionId p) o =
213
210
rdKafkaErrorToEither <$> rdKafkaSeek kt (fromIntegral p) (offsetToInt64 o) timeout
@@ -252,13 +249,14 @@ position (KafkaConsumer (Kafka k) _) tps = liftIO $ do
252
249
-- when polling for events on each 'pollMessage' is not
253
250
-- frequent enough.
254
251
pollConsumerEvents :: KafkaConsumer -> Maybe Timeout -> IO ()
255
- pollConsumerEvents k timeout =
252
+ pollConsumerEvents k timeout = do
256
253
let (Timeout tm) = fromMaybe (Timeout 0 ) timeout
257
- in void $ rdKafkaConsumerPoll (getRdKafka k) tm
254
+ let (KafkaConf _ _ rv _) = getKafkaConf k
255
+ withMVar rv . const $ void $ rdKafkaConsumerPoll (getRdKafka k) tm
258
256
259
257
-- | Closes the consumer.
260
258
closeConsumer :: MonadIO m => KafkaConsumer -> m (Maybe KafkaError )
261
- closeConsumer (KafkaConsumer (Kafka k) (KafkaConf _ qr ct)) = liftIO $ do
259
+ closeConsumer (KafkaConsumer (Kafka k) (KafkaConf _ qr _ ct)) = liftIO $ do
262
260
CToken. cancel ct
263
261
mbq <- readIORef qr
264
262
void $ traverse rdKafkaQueueDestroy mbq
@@ -285,7 +283,7 @@ subscribe (KafkaConsumer (Kafka k) _) ts = do
285
283
return $ kafkaErrorToMaybe res
286
284
287
285
setDefaultTopicConf :: KafkaConf -> TopicConf -> IO ()
288
- setDefaultTopicConf (KafkaConf kc _ _) (TopicConf tc) =
286
+ setDefaultTopicConf (KafkaConf kc _ _ _ ) (TopicConf tc) =
289
287
rdKafkaTopicConfDup tc >>= rdKafkaConfSetDefaultTopicConf kc
290
288
291
289
commitOffsets :: OffsetCommit -> KafkaConsumer -> RdKafkaTopicPartitionListTPtr -> IO (Maybe KafkaError )
0 commit comments