示例#1
0
		public void OpenSubscription(long id, SubscriptionConnectionOptions options)
		{
			if (openSubscriptions.TryAdd(id, options))
			{
				UpdateClientActivityDate(id);
				return;
			}

			SubscriptionConnectionOptions existingOptions;

			if(openSubscriptions.TryGetValue(id, out existingOptions) == false)
				throw new SubscriptionDoesNotExistException("Didn't get existing open subscription while it's expected. Subscription id: " + id);

			if (existingOptions.ConnectionId.Equals(options.ConnectionId, StringComparison.OrdinalIgnoreCase))
			{
				// reopen subscription on already existing connection - might happen after network connection problems the client tries to reopen

				UpdateClientActivityDate(id);
				return; 
			}

			var config = GetSubscriptionConfig(id);

			if (SystemTime.UtcNow - config.TimeOfLastClientActivity > TimeSpan.FromTicks(existingOptions.ClientAliveNotificationInterval.Ticks * 3))
			{
				// last connected client didn't send at least two 'client-alive' notifications - let the requesting client to open it

				ReleaseSubscription(id);
				openSubscriptions.TryAdd(id, options);
				return;
			}

			throw new SubscriptionInUseException("Subscription is already in use. There can be only a single open subscription connection per subscription.");
		}
示例#2
0
        public void OpenSubscription(long id, SubscriptionConnectionOptions options)
        {
            SizeLimitedConcurrentSet<string> releasedConnections;
            if (forciblyReleasedSubscriptions.TryGetValue(id, out releasedConnections) && releasedConnections.Contains(options.ConnectionId))
                throw new SubscriptionClosedException("Subscription " + id + " was forcibly released. Cannot reopen it.");

            if (openSubscriptions.TryAdd(id, options))
            {
                UpdateClientActivityDate(id);
                return;
            }

            SubscriptionConnectionOptions existingOptions;

            if(openSubscriptions.TryGetValue(id, out existingOptions) == false)
                throw new SubscriptionDoesNotExistException("Didn't get existing open subscription while it's expected. Subscription id: " + id);

            if (existingOptions.ConnectionId.Equals(options.ConnectionId, StringComparison.OrdinalIgnoreCase))
            {
                // reopen subscription on already existing connection - might happen after network connection problems the client tries to reopen
                UpdateClientActivityDate(id);
                return; 
            }

            var config = GetSubscriptionConfig(id);

            var now = SystemTime.UtcNow;
            var timeSinceBatchSent = now - config.TimeOfSendingLastBatch;

            if (timeSinceBatchSent > existingOptions.BatchOptions.AcknowledgmentTimeout && 
                SystemTime.UtcNow - config.TimeOfLastClientActivity > TimeSpan.FromTicks(existingOptions.ClientAliveNotificationInterval.Ticks * 3))
            {
                // last connected client exceeded ACK timeout and didn't send at least two 'client-alive' notifications - let the requesting client to open it
                ForceReleaseAndOpenForNewClient(id, options);
                return;
            }

            switch (options.Strategy)
            {
                case SubscriptionOpeningStrategy.TakeOver:
                    if (existingOptions.Strategy != SubscriptionOpeningStrategy.ForceAndKeep)
                    {
                        ForceReleaseAndOpenForNewClient(id, options);
                        return;
                    }
                    break;
                case SubscriptionOpeningStrategy.ForceAndKeep:
                    ForceReleaseAndOpenForNewClient(id, options);
                    return;
            }

            throw new SubscriptionInUseException("Subscription is already in use. There can be only a single open subscription connection per subscription.");
        }
示例#3
0
 private void ForceReleaseAndOpenForNewClient(long id, SubscriptionConnectionOptions options)
 {
     ReleaseSubscription(id);
     openSubscriptions.TryAdd(id, options);
     UpdateClientActivityDate(id);
 }