@@ -207,6 +207,7 @@ public static async Task<Client> Create(ClientParameters parameters, ILogger log
207207 client . connection = await Connection
208208 . Create ( parameters . Endpoint , client . HandleIncoming , client . HandleClosed , parameters . Ssl , logger )
209209 . ConfigureAwait ( false ) ;
210+ client . connection . ClientId = client . ClientId ;
210211 // exchange properties
211212 var peerPropertiesResponse = await client . Request < PeerPropertiesRequest , PeerPropertiesResponse > ( corr =>
212213 new PeerPropertiesRequest ( corr , parameters . Properties ) ) . ConfigureAwait ( false ) ;
@@ -306,7 +307,7 @@ public ValueTask<bool> Publish<T>(T msg) where T : struct, ICommand
306307 Action < ( ulong , ResponseCode ) [ ] > errorCallback , ConnectionsPool pool = null )
307308 {
308309 await _poolSemaphore . WaitAsync ( ) . ConfigureAwait ( false ) ;
309- var publisherId = ConnectionsPool . FindNextValidId ( publishers . Keys . ToList ( ) ) ;
310+ var publisherId = ConnectionsPool . FindNextValidId ( publishers . Keys . ToList ( ) , IncrementEntityId ( ) ) ;
310311 DeclarePublisherResponse response ;
311312
312313 try
@@ -320,7 +321,7 @@ public ValueTask<bool> Publish<T>(T msg) where T : struct, ICommand
320321 _poolSemaphore . Release ( ) ;
321322 }
322323
323- if ( response . ResponseCode == ResponseCode . Ok || pool == null )
324+ if ( response . ResponseCode == ResponseCode . Ok )
324325 return ( publisherId , response ) ;
325326
326327 // if the response code is not ok we need to remove the subscription
@@ -357,59 +358,65 @@ await Request<DeletePublisherRequest, DeletePublisherResponse>(corr =>
357358 public async Task < ( byte , SubscribeResponse ) > Subscribe ( string stream , IOffsetType offsetType ,
358359 ushort initialCredit ,
359360 Dictionary < string , string > properties , Func < Deliver , Task > deliverHandler ,
360- Func < bool , Task < IOffsetType > > consumerUpdateHandler = null )
361+ Func < bool , Task < IOffsetType > > consumerUpdateHandler = null , ConnectionsPool pool = null )
361362 {
362- return await Subscribe ( new RawConsumerConfig ( stream ) { OffsetSpec = offsetType } ,
363+ return await Subscribe ( new RawConsumerConfig ( stream ) { OffsetSpec = offsetType , Pool = pool } ,
363364 initialCredit ,
364365 properties ,
365366 deliverHandler ,
366367 consumerUpdateHandler ) . ConfigureAwait ( false ) ;
367368 }
368369
370+ private byte _nextEntityId = 0 ;
371+
372+ // the entity id is a byte so we need to increment it and reset it when it reaches the max value
373+ // to avoid to use always the same ids when producers and consumers are created
374+ // so even there is a connection with one producer or consumer we need to increment the id
375+ private byte IncrementEntityId ( )
376+ {
377+ lock ( Obj )
378+ {
379+ var current = _nextEntityId ;
380+ _nextEntityId ++ ;
381+ if ( _nextEntityId != byte . MaxValue )
382+ return current ;
383+ _nextEntityId = 0 ;
384+ return _nextEntityId ;
385+ }
386+ }
387+
369388 public async Task < ( byte , SubscribeResponse ) > Subscribe ( RawConsumerConfig config ,
370389 ushort initialCredit ,
371390 Dictionary < string , string > properties , Func < Deliver , Task > deliverHandler ,
372391 Func < bool , Task < IOffsetType > > consumerUpdateHandler )
373392 {
374393 await _poolSemaphore . WaitAsync ( ) . ConfigureAwait ( false ) ;
375- var subscriptionId = ConnectionsPool . FindNextValidId ( consumers . Keys . ToList ( ) ) ;
376-
394+ var subscriptionId = ConnectionsPool . FindNextValidId ( consumers . Keys . ToList ( ) , IncrementEntityId ( ) ) ;
395+ SubscribeResponse response ;
377396 try
378397 {
379- SubscribeResponse response ;
380- try
381- {
382- consumers . Add ( subscriptionId ,
383- new ConsumerEvents (
384- deliverHandler ,
385- consumerUpdateHandler ) ) ;
386-
387- response = await Request < SubscribeRequest , SubscribeResponse > ( corr =>
388- new SubscribeRequest ( corr , subscriptionId , config . Stream , config . OffsetSpec , initialCredit ,
389- properties ) ) . ConfigureAwait ( false ) ;
390- }
391- finally
392- {
393- _poolSemaphore . Release ( ) ;
394- }
395-
396- if ( response . ResponseCode == ResponseCode . Ok )
397- return ( subscriptionId , response ) ;
398+ consumers . Add ( subscriptionId ,
399+ new ConsumerEvents (
400+ deliverHandler ,
401+ consumerUpdateHandler ) ) ;
398402
399- ClientExceptions . MaybeThrowException ( response . ResponseCode ,
400- $ "Error while creating consumer for stream { config . Stream } ") ;
403+ response = await Request < SubscribeRequest , SubscribeResponse > ( corr =>
404+ new SubscribeRequest ( corr , subscriptionId , config . Stream , config . OffsetSpec , initialCredit ,
405+ properties ) ) . ConfigureAwait ( false ) ;
401406 }
402- catch ( Exception e )
407+ finally
403408 {
404- // if the response code is not ok we need to remove the subscription
405- // and close the connection if necessary.
406- consumers . Remove ( subscriptionId ) ;
407- await MaybeClose ( "Create Consumer Exception" , config . Stream , config . Pool ) . ConfigureAwait ( false ) ;
408- throw new CreateConsumerException (
409- $ "Error while creating consumer for stream { config . Stream } , error: { e . Message } ") ;
409+ _poolSemaphore . Release ( ) ;
410410 }
411411
412- return ( subscriptionId , new SubscribeResponse ( subscriptionId , ResponseCode . InternalError ) ) ;
412+ if ( response . ResponseCode == ResponseCode . Ok )
413+ return ( subscriptionId , response ) ;
414+
415+ // if the response code is not ok we need to remove the subscription
416+ // and close the connection if necessary.
417+ consumers . Remove ( subscriptionId ) ;
418+ await MaybeClose ( "Create Consumer Exception" , config . Stream , config . Pool ) . ConfigureAwait ( false ) ;
419+ return ( subscriptionId , response ) ;
413420 }
414421
415422 public async Task < UnsubscribeResponse > Unsubscribe ( byte subscriptionId , bool ignoreIfAlreadyRemoved = false )
@@ -799,7 +806,6 @@ internal async Task<CloseResponse> MaybeClose(string reason, string stream, Conn
799806 _logger . LogInformation ( "Close connection for the {ClientId}" , ClientId ) ;
800807 // the client can be closed in an unexpected way so we need to remove it from the pool
801808 // so you will find pool.remove(ClientId) also to the disconnect event
802- // pool.remove(ClientId) is a duplicate call here but it is ok. The pool is idempotent
803809 pool . Remove ( ClientId ) ;
804810 await Close ( reason ) . ConfigureAwait ( false ) ;
805811 }
0 commit comments