async Task InitializeAsync()
        {
            this.documentClient = new DocumentClient(this.collectionLocation.Uri, this.collectionLocation.MasterKey, this.collectionLocation.ConnectionPolicy);

            Uri      databaseUri = UriFactory.CreateDatabaseUri(this.collectionLocation.DatabaseName);
            Database database    = await this.documentClient.ReadDatabaseAsync(databaseUri);

            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(this.collectionLocation.DatabaseName, this.collectionLocation.CollectionName);
            ResourceResponse <DocumentCollection> collectionResponse = await this.documentClient.ReadDocumentCollectionAsync(
                collectionUri,
                new RequestOptions { PopulateQuotaInfo = true });

            DocumentCollection collection = collectionResponse.Resource;

            this.collectionSelfLink = collection.SelfLink;

            // Grab the options-supplied prefix if present otherwise leave it empty.
            string optionsPrefix = this.options.LeasePrefix ?? string.Empty;

            // Beyond this point all access to collection is done via this self link: if collection is removed, we won't access new one using same name by accident.
            this.leasePrefix = string.Format(CultureInfo.InvariantCulture, "{0}{1}_{2}_{3}", optionsPrefix, this.collectionLocation.Uri.Host, database.ResourceId, collection.ResourceId);

            var leaseManager = new DocumentServiceLeaseManager(
                this.auxCollectionLocation,
                this.leasePrefix,
                this.options.LeaseExpirationInterval,
                this.options.LeaseRenewInterval);
            await leaseManager.InitializeAsync();

            this.leaseManager      = leaseManager;
            this.checkpointManager = (ICheckpointManager)leaseManager;

            if (this.options.DiscardExistingLeases)
            {
                TraceLog.Warning(string.Format("Host '{0}': removing all leases, as requested by ChangeFeedHostOptions", this.HostName));
                await this.leaseManager.DeleteAllAsync();
            }

            // Note: lease store is never stale as we use monitored colleciton Rid as id prefix for aux collection.
            // Collection was removed and re-created, the rid would change.
            // If it's not deleted, it's not stale. If it's deleted, it's not stale as it doesn't exist.
            await this.leaseManager.CreateLeaseStoreIfNotExistsAsync();

            var ranges = new Dictionary <string, PartitionKeyRange>();

            foreach (var range in await this.EnumPartitionKeyRangesAsync(this.collectionSelfLink))
            {
                ranges.Add(range.Id, range);
            }

            TraceLog.Informational(string.Format("Source collection: '{0}', {1} partition(s), {2} document(s)", this.collectionLocation.CollectionName, ranges.Count, GetDocumentCount(collectionResponse)));

            await this.CreateLeases(ranges);

            this.partitionManager = new PartitionManager <DocumentServiceLease>(this.HostName, this.leaseManager, this.options);
            await this.partitionManager.SubscribeAsync(this);

            await this.partitionManager.InitializeAsync();
        }
Esempio n. 2
0
        async Task InitializeAsync()
        {
            this.documentClient = new DocumentClient(this.collectionLocation.Uri, this.collectionLocation.MasterKey, this.collectionLocation.ConnectionPolicy);

            Uri      databaseUri = UriFactory.CreateDatabaseUri(this.collectionLocation.DatabaseName);
            Database database    = await this.documentClient.ReadDatabaseAsync(databaseUri);

            Uri collectionUri             = UriFactory.CreateDocumentCollectionUri(this.collectionLocation.DatabaseName, this.collectionLocation.CollectionName);
            DocumentCollection collection = await this.documentClient.ReadDocumentCollectionAsync(collectionUri);

            this.collectionSelfLink = collection.SelfLink;

            // Beyond this point all access to colleciton is done via this self link: if collection is removed, we won't access new one using same name by accident.
            this.leasePrefix = string.Format(CultureInfo.InvariantCulture, "{0}_{1}_{2}", this.collectionLocation.Uri.Host, database.ResourceId, collection.ResourceId);

            var leaseManager = new DocumentServiceLeaseManager(
                this.auxCollectionLocation,
                this.leasePrefix,
                this.options.LeaseExpirationInterval,
                this.options.LeaseRenewInterval);
            await leaseManager.InitializeAsync();

            this.leaseManager      = leaseManager;
            this.checkpointManager = (ICheckpointManager)leaseManager;

            if (this.options.DiscardExistingLeases)
            {
                TraceLog.Warning(string.Format("Host '{0}': removing all leases, as requested by ChangeFeedHostOptions", this.HostName));
                await this.leaseManager.DeleteAllAsync();
            }

            // Note: lease store is never stale as we use monitored colleciton Rid as id prefix for aux collection.
            // Collection was removed and re-created, the rid would change.
            // If it's not deleted, it's not stale. If it's deleted, it's not stale as it doesn't exist.
            await this.leaseManager.CreateLeaseStoreIfNotExistsAsync();

            string[] rangeIds = await this.EnumPartitionKeyRangeIds(this.collectionSelfLink);

            Parallel.ForEach(rangeIds, async rangeId => {
                this.statsSinceLastCheckpoint.AddOrUpdate(
                    rangeId,
                    new CheckpointStats(),
                    (partitionId, existingStats) => existingStats);

                await this.leaseManager.CreateLeaseIfNotExistAsync(rangeId);
            });

            this.partitionManager = new PartitionManager <DocumentServiceLease>(this.HostName, this.leaseManager, this.options);
            await this.partitionManager.SubscribeAsync(this);

            await this.partitionManager.InitializeAsync();
        }