@@ -1042,10 +1042,10 @@ newRcvConnSrv c nm userId connId enableNtfs cMode userLinkData_ clientData pqIni
10421042 createRcvQueue nonce_ qd e2eKeys = do
10431043 AgentConfig {smpClientVRange = vr} <- asks config
10441044 ntfServer_ <- if enableNtfs then newQueueNtfServer else pure Nothing
1045- (rq, qUri, tSess, sessId) <- newRcvQueue_ c nm userId connId srvWithAuth vr qd (isJust ntfServer_) subMode nonce_ e2eKeys `catchAllErrors` \ e -> liftIO (print e) >> throwE e
1045+ (rq, qUri, tSess, sessId, serviceId_ ) <- newRcvQueue_ c nm userId connId srvWithAuth vr qd (isJust ntfServer_) subMode nonce_ e2eKeys `catchAllErrors` \ e -> liftIO (print e) >> throwE e
10461046 atomically $ incSMPServerStat c userId srv connCreated
10471047 rq' <- withStore c $ \ db -> updateNewConnRcv db connId rq subMode
1048- lift . when (subMode == SMSubscribe ) $ addNewQueueSubscription c rq' tSess sessId
1048+ lift . when (subMode == SMSubscribe ) $ addNewQueueSubscription c rq' tSess sessId serviceId_
10491049 mapM_ (newQueueNtfSubscription c rq') ntfServer_
10501050 pure (rq', qUri)
10511051 createConnReq :: SMPQueueUri -> AM (ConnectionRequestUri c )
@@ -1293,11 +1293,11 @@ joinConnSrvAsync _c _userId _connId _enableNtfs (CRContactUri _) _cInfo _subMode
12931293createReplyQueue :: AgentClient -> NetworkRequestMode -> ConnData -> SndQueue -> SubscriptionMode -> SMPServerWithAuth -> AM SMPQueueInfo
12941294createReplyQueue c nm ConnData {userId, connId, enableNtfs} SndQueue {smpClientVersion} subMode srv = do
12951295 ntfServer_ <- if enableNtfs then newQueueNtfServer else pure Nothing
1296- (rq, qUri, tSess, sessId) <- newRcvQueue c nm userId connId srv (versionToRange smpClientVersion) SCMInvitation (isJust ntfServer_) subMode
1296+ (rq, qUri, tSess, sessId, serviceId_ ) <- newRcvQueue c nm userId connId srv (versionToRange smpClientVersion) SCMInvitation (isJust ntfServer_) subMode
12971297 atomically $ incSMPServerStat c userId (qServer rq) connCreated
12981298 let qInfo = toVersionT qUri smpClientVersion
12991299 rq' <- withStore c $ \ db -> upgradeSndConnToDuplex db connId rq subMode
1300- lift . when (subMode == SMSubscribe ) $ addNewQueueSubscription c rq' tSess sessId
1300+ lift . when (subMode == SMSubscribe ) $ addNewQueueSubscription c rq' tSess sessId serviceId_
13011301 mapM_ (newQueueNtfSubscription c rq') ntfServer_
13021302 pure qInfo
13031303
@@ -1453,22 +1453,14 @@ subscribeAllConnections' c onlyNeeded activeUserId_ = handleErr $ do
14531453 Just activeUserId -> sortOn (\ (uId, _) -> if uId == activeUserId then 0 else 1 :: Int ) userSrvs
14541454 Nothing -> userSrvs
14551455 useServices <- readTVarIO $ useClientServices c
1456- -- These options are possible below:
1457- -- 1) services fully disabled:
1458- -- No service subscriptions will be attempted, and existing services and association will remain in in the database,
1459- -- but they will be ignored because of hasService parameter set to False.
1460- -- This approach preserves performance for all clients that do not use services.
1461- -- 2) at least one user ID has services enabled:
1462- -- Service will be loaded for all user/server combinations:
1463- -- a) service is enabled for user ID and service record exists: subscription will be attempted,
1464- -- b) service is disabled and record exists: service record and all associations will be removed,
1465- -- c) service is disabled or no record: no subscription attempt.
1456+ -- Service will be loaded for all user/server combinations:
1457+ -- a) service is enabled for user ID and service record exists: subscription will be attempted,
1458+ -- b) service is disabled and record exists: service record and all associations will be removed,
1459+ -- c) service is disabled or no record: no subscription attempt.
14661460 -- On successful service subscription, only unassociated queues will be subscribed.
1467- userSrvs'' <-
1468- if any id useServices
1469- then lift $ mapConcurrently (subscribeService useServices) userSrvs'
1470- else pure $ map (,False ) userSrvs'
1471- rs <- lift $ mapConcurrently (subscribeUserServer maxPending currPending) userSrvs''
1461+ userSrvs2 <- withStore' c $ \ db -> mapM (getService db useServices) userSrvs'
1462+ userSrvs3 <- lift $ mapConcurrently subscribeService userSrvs2
1463+ rs <- lift $ mapConcurrently (subscribeUserServer maxPending currPending) userSrvs3
14721464 let (errs, oks) = partitionEithers rs
14731465 logInfo $ " subscribed " <> tshow (sum oks) <> " queues"
14741466 forM_ (L. nonEmpty errs) $ notifySub c . ERRS . L. map (" " ,)
@@ -1477,23 +1469,27 @@ subscribeAllConnections' c onlyNeeded activeUserId_ = handleErr $ do
14771469 resumeAllCommands c
14781470 where
14791471 handleErr = (`catchAllErrors` \ e -> notifySub' c " " (ERR e) >> throwE e)
1480- subscribeService :: Map UserId Bool -> (UserId , SMPServer ) -> AM' ((UserId , SMPServer ), ServiceAssoc )
1481- subscribeService useServices us@ (userId, srv) = fmap ((us,) . fromRight False ) $ tryAllErrors' $ do
1482- withStore' c ( \ db -> getSubscriptionService db userId srv) >>= \ case
1472+ getService :: DB. Connection -> Map UserId Bool -> (UserId , SMPServer ) -> IO ((UserId , SMPServer ), Maybe ServiceSub )
1473+ getService db useServices us@ (userId, srv) =
1474+ fmap (us,) $ getSubscriptionService db userId srv >>= \ case
14831475 Just serviceSub -> case M. lookup userId useServices of
1484- Just True -> tryAllErrors (subscribeClientService c True userId srv serviceSub) >>= \ case
1485- Right (ServiceSubResult e _) -> case e of
1486- Just SSErrorServiceId {} -> unassocQueues
1487- -- Below would resubscribe all queues after service was disabled and re-enabled
1488- -- Possibly, we should always resubscribe all with expected is greated than subscribed
1489- Just SSErrorQueueCount {expectedQueueCount = n, subscribedQueueCount = n'} | n > 0 && n' == 0 -> unassocQueues
1490- _ -> pure True
1491- Left e -> do
1492- atomically $ writeTBQueue (subQ c) (" " , " " , AEvt SAEConn $ ERR e)
1493- if clientServiceError e
1494- then unassocQueues
1495- else pure True
1496- _ -> unassocQueues
1476+ Just True -> pure $ Just serviceSub
1477+ _ -> Nothing <$ unassocUserServerRcvQueueSubs' db userId srv
1478+ _ -> pure Nothing
1479+ subscribeService :: ((UserId , SMPServer ), Maybe ServiceSub ) -> AM' ((UserId , SMPServer ), ServiceAssoc )
1480+ subscribeService (us@ (userId, srv), serviceSub_) = fmap ((us,) . fromRight False ) $ tryAllErrors' $
1481+ case serviceSub_ of
1482+ Just serviceSub -> tryAllErrors (subscribeClientService c True userId srv serviceSub) >>= \ case
1483+ Right (ServiceSubResult e _) -> case e of
1484+ Just SSErrorServiceId {} -> unassocQueues
1485+ -- Possibly, we should always resubscribe all when expected is greater than subscribed
1486+ Just SSErrorQueueCount {expectedQueueCount = n, subscribedQueueCount = n'} | n > 0 && n' == 0 -> unassocQueues
1487+ _ -> pure True
1488+ Left e -> do
1489+ atomically $ writeTBQueue (subQ c) (" " , " " , AEvt SAEConn $ ERR e)
1490+ if clientServiceError e
1491+ then unassocQueues
1492+ else pure True
14971493 where
14981494 unassocQueues :: AM Bool
14991495 unassocQueues = False <$ withStore' c (\ db -> unassocUserServerRcvQueueSubs' db userId srv)
@@ -2231,10 +2227,10 @@ switchDuplexConnection c nm (DuplexConnection cData@ConnData {connId, userId} rq
22312227 srv' <- if srv == server then getNextSMPServer c userId [server] else pure srvAuth
22322228 -- TODO [notications] possible improvement would be to create ntf credentials here, to avoid creating them after rotation completes.
22332229 -- The problem is that currently subscription already exists, and we do not support queues with credentials but without subscriptions.
2234- (q, qUri, tSess, sessId) <- newRcvQueue c nm userId connId srv' clientVRange SCMInvitation False SMSubscribe
2230+ (q, qUri, tSess, sessId, serviceId_ ) <- newRcvQueue c nm userId connId srv' clientVRange SCMInvitation False SMSubscribe
22352231 let rq' = (q :: NewRcvQueue ) {primary = True , dbReplaceQueueId = Just dbQueueId}
22362232 rq'' <- withStore c $ \ db -> addConnRcvQueue db connId rq' SMSubscribe
2237- lift $ addNewQueueSubscription c rq'' tSess sessId
2233+ lift $ addNewQueueSubscription c rq'' tSess sessId serviceId_
22382234 void . enqueueMessages c cData sqs SMP. noMsgFlags $ QADD [(qUri, Just (server, sndId))]
22392235 rq1 <- withStore' c $ \ db -> setRcvSwitchStatus db rq $ Just RSSendingQADD
22402236 let rqs' = updatedQs rq1 rqs <> [rq'']
@@ -2920,7 +2916,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), THandlePar
29202916 processSubOk :: RcvQueue -> TVar [ConnId ] -> TVar [RcvQueue ] -> Maybe SMP. ServiceId -> IO ()
29212917 processSubOk rq@ RcvQueue {connId} upConnIds serviceRQs serviceId_ =
29222918 atomically . whenM (isPendingSub rq) $ do
2923- SS. addActiveSub tSess sessId rq $ currentSubs c
2919+ SS. addActiveSub tSess sessId serviceId_ rq $ currentSubs c
29242920 modifyTVar' upConnIds (connId : )
29252921 when (isJust serviceId_ && serviceId_ == clientServiceId_) $ modifyTVar' serviceRQs (rq : )
29262922 clientServiceId_ = (\ THClientService {serviceId} -> serviceId) <$> (clientService =<< thAuth)
0 commit comments