/// <summary>
        ///		Create a new <see cref="ChangesApi"/>.
        /// </summary>
        /// <param name="serverUrl">
        ///		The RavenDB server URL.
        /// </param>
        /// <param name="databaseName">
        ///		The RavenDB database name.
        /// </param>
        /// <param name="api">
        ///		The change-notification API.
        /// </param>
        /// <param name="subscribe">
        ///		A delegate that performs the subscription to the change-notification API.
        /// </param>
        public ChangesApi(string serverUrl, string databaseName, IDatabaseChanges api, Func <IDatabaseChanges, IDisposable> subscribe)
        {
            if (String.IsNullOrWhiteSpace(serverUrl))
            {
                throw new ArgumentException("Argument cannot be null, empty, or composed entirely of whitespace: 'url'.", nameof(serverUrl));
            }

            if (String.IsNullOrWhiteSpace(databaseName))
            {
                throw new ArgumentException("Argument cannot be null, empty, or composed entirely of whitespace: 'databaseName'.", nameof(databaseName));
            }

            if (api == null)
            {
                throw new ArgumentNullException(nameof(api));
            }

            ServerUrl    = serverUrl;
            DatabaseName = databaseName;
            Api          = api;
            _subscribe   = subscribe;

            // Converts from what would be an IObservable<EventArgs> to an IObservable<ChangesApi>
            ConnectionObservable = Observable.FromEvent <EventHandler, ChangesApi>(
                conversion: publishEvent => (eventSender, eventArguments) => publishEvent(this),
                addHandler: handler => Api.ConnectionStatusChanged    += handler,
                removeHandler: handler => Api.ConnectionStatusChanged -= handler
                );
        }
示例#2
0
        public RemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes)
#endif
        {
            var synchronizationContext = SynchronizationContext.Current;

            try
            {
                SynchronizationContext.SetSynchronizationContext(null);

                OperationId      = Guid.NewGuid();
                operationClient  = client;
                operationChanges = changes;
                queue            = new BlockingCollection <RavenJObject>(options.BatchSize * 8);

                operationTask = StartBulkInsertAsync(options);
#if !MONO
                SubscribeToBulkInsertNotifications(changes);
#endif
            }

#if !MONO
            finally
            {
                SynchronizationContext.SetSynchronizationContext(synchronizationContext);
            }
        }
示例#3
0
        /// <summary>
        /// Creates embeddable instance of document changes
        /// </summary>
        /// <param name="database">Database name is ignored in embeddable document store</param>
        protected override IDatabaseChanges CreateDatabaseChanges(string database)
        {
            IDatabaseChanges result = null;

            result = new EmbeddableDatabaseChanges(this, () => result = null, ((EmbeddedDatabaseCommands)DatabaseCommands).TryResolveConflictByUsingRegisteredListeners);
            return(result);
        }
		public ChunkedRemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes, int chunkSize)
		{
			this.options = options;
			this.client = client;
			this.changes = changes;
			this.chunkSize = chunkSize;
		}
示例#5
0
        internal Subscription(long id, string database, SubscriptionConnectionOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes, DocumentConvention conventions, bool open, Func <Task> ensureOpenSubscription)
        {
            this.id                     = id;
            this.options                = options;
            this.commands               = commands;
            this.changes                = changes;
            this.conventions            = conventions;
            this.ensureOpenSubscription = ensureOpenSubscription;

            SubscriptionLifetimeTask = taskCompletionSource.Task;

            if (typeof(T) != typeof(RavenJObject))
            {
                isStronglyTyped             = true;
                generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(conventions, entity => AsyncHelpers.RunSync(() => conventions.GenerateDocumentKeyAsync(database, commands, entity)));
            }

            if (open)
            {
                Start();
            }
            else
            {
                if (options.Strategy != SubscriptionOpeningStrategy.WaitForFree)
                {
                    throw new InvalidOperationException("Subscription isn't open while its opening strategy is: " + options.Strategy);
                }
            }

            if (options.Strategy == SubscriptionOpeningStrategy.WaitForFree)
            {
                WaitForSubscriptionReleased();
            }
        }
示例#6
0
        public async Task AsyncWhatIsChangesApi()
        {
            using (var store = new DocumentStore())
            {
                #region changes_2
                IDatabaseChanges changes = store.Changes();
                await changes.EnsureConnectedNow();

                var subscription = changes
                                   .ForAllDocuments()
                                   .Subscribe(change => Console.WriteLine("{0} on document {1}", change.Type, change.Id));
                try
                {
                    // application code here
                }
                finally
                {
                    if (subscription != null)
                    {
                        subscription.Dispose();
                    }
                }
                #endregion
            }
        }
 public ChunkedRemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes)
 {
     this.options = options;
     this.client = client;
     this.changes = changes;			
     currentChunkSize = 0;
     current = GetBulkInsertOperation();
 }
示例#8
0
 public ChunkedRemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes)
 {
     this.options     = options;
     this.client      = client;
     this.changes     = changes;
     currentChunkSize = 0;
     current          = GetBulkInsertOperation();
 }
示例#9
0
 public IDatabaseChanges Changes()
 {
     return(databaseChanges ??
            (databaseChanges =
                 name == Constants.SystemDatabase
                 ? documentStore.Changes()
                 : documentStore.Changes(name)));
 }
		public ChunkedRemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes, int chunkSize,long? documentSizeInChunkLimit = null)
		{
			this.options = options;
			this.client = client;
			this.changes = changes;
			this.chunkSize = chunkSize;
			this.documentSizeInChunkLimit = documentSizeInChunkLimit;
			documentSizeInChunk = 0;
		}
 public ChunkedRemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes, int chunkSize, long?documentSizeInChunkLimit = null)
 {
     this.options   = options;
     this.client    = client;
     this.changes   = changes;
     this.chunkSize = chunkSize;
     this.documentSizeInChunkLimit = documentSizeInChunkLimit;
     documentSizeInChunk           = 0;
 }
示例#12
0
        protected ConnectionStateBase(IDatabaseChanges changes, Func <Task <bool> > onConnect, Func <Task> onDisconnect)
        {
            _changes      = changes;
            _onConnect    = onConnect;
            _onDisconnect = onDisconnect;
            _value        = 0;
            _tcs          = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            _changes.ConnectionStatusChanged += OnConnectionStatusChanged;
        }
		public ChunkedRemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes, int chunkSize,long? documentSizeInChunkLimit = null)
		{
			this.options = options;
			this.client = client;
			this.changes = changes;
			this.chunkSize = chunkSize;
			this.documentSizeInChunkLimit = documentSizeInChunkLimit;
			documentSizeInChunk = 0;
			if(documentSizeInChunkLimit.HasValue)
				Console.WriteLine("Limit of document size in chunk = " + documentSizeInChunkLimit.Value);
		}
示例#14
0
		public ShardedDatabaseChanges(IDatabaseChanges[] shardedDatabaseChanges)
		{
			this.shardedDatabaseChanges = shardedDatabaseChanges;
			Task = Task.Factory.ContinueWhenAll(shardedDatabaseChanges.Select(x => x.Task).ToArray(), tasks =>
			{
				foreach (var task in tasks)
				{
					task.AssertNotFailed();
				}
			});
		}
示例#15
0
        public EvictItemsFromCacheBasedOnChanges(DocumentStore store, string databaseName)
        {
            _databaseName    = databaseName;
            _changes         = store.Changes(databaseName);
            _requestExecutor = store.GetRequestExecutor(databaseName);
            var docSub = _changes.ForAllDocuments();

            _documentsSubscription = docSub.Subscribe(this);
            var indexSub = _changes.ForAllIndexes();

            _indexesSubscription = indexSub.Subscribe(this);
        }
示例#16
0
        private async Task AssertChangesApiTaskFailure(IDatabaseChanges changes)
        {
            Task <IDatabaseChanges> changesTask = null;

            Assert.Equal(TaskStatus.Faulted, await WaitForValueAsync(() =>
            {
                changesTask = changes.EnsureConnectedNow();
                return(changesTask.Status);
            }, TaskStatus.Faulted));
            Assert.NotNull(changesTask.Exception.InnerException);
            Assert.Equal(typeof(DatabaseDoesNotExistException), changesTask.Exception.InnerException.GetType());
        }
 public ChunkedRemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes, int chunkSize, long?documentSizeInChunkLimit = null)
 {
     this.options   = options;
     this.client    = client;
     this.changes   = changes;
     this.chunkSize = chunkSize;
     this.documentSizeInChunkLimit = documentSizeInChunkLimit;
     documentSizeInChunk           = 0;
     if (documentSizeInChunkLimit.HasValue)
     {
         Console.WriteLine("Limit of document size in chunk = " + documentSizeInChunkLimit.Value);
     }
 }
        public EvictItemsFromCacheBasedOnChanges(string databaseName, IDatabaseChanges changes, Action <string> evictCacheOldItems)
        {
            this.databaseName       = databaseName;
            this.changes            = changes;
            this.evictCacheOldItems = evictCacheOldItems;
            var docSub = changes.ForAllDocuments();

            documentsSubscription = docSub.Subscribe(this);
            var indexSub = changes.ForAllIndexes();

            indexesSubscription = indexSub.Subscribe(this);

            connectionTask = Task.Factory.ContinueWhenAll(new Task[] { docSub.Task, indexSub.Task }, tasks => { });
        }
示例#19
0
		public BulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners, BulkInsertOptions options, IDatabaseChanges changes)
		{
			this.documentStore = documentStore;

			database = database ?? MultiDatabase.GetDatabaseName(documentStore.Url);

			// Fitzchak: Should not be ever null because of the above code, please refactor this.
			DatabaseCommands = database == null
				? documentStore.AsyncDatabaseCommands.ForSystemDatabase()
				: documentStore.AsyncDatabaseCommands.ForDatabase(database);

			generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(documentStore.Conventions, entity => documentStore.Conventions.GenerateDocumentKeyAsync(database, DatabaseCommands, entity).ResultUnwrap());
			Operation = GetBulkInsertOperation(options, DatabaseCommands, changes);
			entityToJson = new EntityToJson(documentStore, listeners);
		}
示例#20
0
        public RemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes)
        {
            using (NoSynchronizationContext.Scope())
            {
                OperationId      = Guid.NewGuid();
                operationClient  = client;
                operationChanges = changes;
                queue            = new BlockingCollection <RavenJObject>(Math.Max(128, (options.BatchSize * 3) / 2));

                operationTask = StartBulkInsertAsync(options);
#if !MONO
                SubscribeToBulkInsertNotifications(changes);
#endif
            }
        }
示例#21
0
        internal Subscription(long id, SubscriptionConnectionOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes, DocumentConvention conventions, Func <Task> ensureOpenSubscription)
        {
            this.id                     = id;
            this.options                = options;
            this.commands               = commands;
            this.changes                = changes;
            this.conventions            = conventions;
            this.ensureOpenSubscription = ensureOpenSubscription;

            if (typeof(T) != typeof(RavenJObject))
            {
                isStronglyTyped = true;
            }

            StartWatchingDocs();
            StartPullingTask = StartPullingDocs();
        }
示例#22
0
        internal Subscription(long id, string database, SubscriptionConnectionOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes, DocumentConvention conventions, Func <Task> ensureOpenSubscription)
        {
            this.id                     = id;
            this.options                = options;
            this.commands               = commands;
            this.changes                = changes;
            this.conventions            = conventions;
            this.ensureOpenSubscription = ensureOpenSubscription;

            if (typeof(T) != typeof(RavenJObject))
            {
                isStronglyTyped             = true;
                generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(conventions, entity => conventions.GenerateDocumentKeyAsync(database, commands, entity).ResultUnwrap());
            }

            StartWatchingDocs();
            StartPullingTask = StartPullingDocs();
        }
示例#23
0
        /// <summary>
        ///		An example subscription to the change-notification API.
        /// </summary>
        /// <param name="changes">
        ///		The change-notification API.
        /// </param>
        /// <param name="serverUrl">
        ///		The URL of the server targeted by the API.
        /// </param>
        /// <returns>
        ///		An <see cref="IDisposable"/> representing the subscription.
        /// </returns>
        static IDisposable SubscribeToChangesApi(IDatabaseChanges changes, string serverUrl)
        {
            if (changes == null)
            {
                throw new ArgumentNullException(nameof(changes));
            }

            if (String.IsNullOrWhiteSpace(serverUrl))
            {
                throw new ArgumentException("Argument cannot be null, empty, or composed entirely of whitespace: 'serverUrl'.", nameof(serverUrl));
            }

            return(changes.ForAllDocuments()
                   .Where(
                       change => !change.Id.StartsWith("Raven/Replication")
                       )
                   .Subscribe(
                       change => Log.Information("{ServerUrl} {ChangeType}: {DocumentId} ({DocumentETag})", serverUrl, change.Type, change.Id, change.Etag),
                       error => Log.Error(error, "{ServerUrl} subscription error: {ErrorMessage}", serverUrl, error.Message),
                       () => Log.Information("[{ServerUrl}] subscription complete", serverUrl)
                       ));
        }
示例#24
0
 public ILowLevelBulkInsertOperation GetBulkInsertOperation(BulkInsertOptions options, IDatabaseChanges changes)
 {
     return(asyncServerClient.GetBulkInsertOperation(options, changes));
 }
示例#25
0
 protected virtual ILowLevelBulkInsertOperation GetBulkInsertOperation(BulkInsertOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes)
 {
     return(commands.GetBulkInsertOperation(options, changes));
 }
示例#26
0
        public BulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners, BulkInsertOptions options, IDatabaseChanges changes)
        {
            this.documentStore = documentStore;

            database = database ?? MultiDatabase.GetDatabaseName(documentStore.Url);

            // Fitzchak: Should not be ever null because of the above code, please refactor this.
            DatabaseCommands = database == null
                ? documentStore.AsyncDatabaseCommands.ForSystemDatabase()
                : documentStore.AsyncDatabaseCommands.ForDatabase(database);

            generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(documentStore.Conventions, entity =>
                                                                          AsyncHelpers.RunSync(() => documentStore.Conventions.GenerateDocumentKeyAsync(database, DatabaseCommands, entity)));

            Operation    = GetBulkInsertOperation(options, DatabaseCommands, changes);
            entityToJson = new EntityToJson(documentStore, listeners);
        }
示例#27
0
 protected override ILowLevelBulkInsertOperation GetBulkInsertOperation(BulkInsertOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes)
 {
     return(null);            // ugly code
 }
        /// <summary>
        /// Create new instance of this class
        /// </summary>
        public EmbeddedBulkInsertOperation(DocumentDatabase database, BulkInsertOptions options, IDatabaseChanges changes)
        {
            OperationId = Guid.NewGuid();

            this.options = options;
            queue        = new BlockingCollection <JsonDocument>(options.BatchSize * 8);

            var cancellationToken = CreateCancellationToken();

            doBulkInsert = Task.Factory.StartNew(() =>
            {
                database.BulkInsert(options, YieldDocuments(cancellationToken), OperationId);
            });

            SubscribeToBulkInsertNotifications(changes);
        }
		protected override ILowLevelBulkInsertOperation GetBulkInsertOperation(BulkInsertOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes)
		{
			return null; // ugly code
		}
		public ChunkedBulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners, BulkInsertOptions options, IDatabaseChanges changes, int chunkSize)
			: base(database, documentStore, listeners, options, changes)
		{
			Operation = new ChunkedRemoteBulkInsertOperation(options, (AsyncServerClient)DatabaseCommands, changes, chunkSize);
		}
示例#31
0
        public ChangesApi()
        {
            using (var store = NewDocumentStore())
            {
                #region getting_database_changes_instance

                IDatabaseChanges changes = store.Changes("DatabaseName");

                #endregion

                #region subscribe_documents_replication_conflict
                store.Changes()
                .ForAllDocuments()
                .Subscribe(change =>
                {
                    if (change.Type == DocumentChangeTypes.ReplicationConflict)
                    {
                        Console.WriteLine("Replication conflict has occurred. Document id: " + change.Id);
                    }
                });
                #endregion

                #region subscribe_documents_starting_with
                store.Changes()
                .ForDocumentsStartingWith("users")
                .Subscribe(change =>
                {
                    if (change.Type == DocumentChangeTypes.Put)
                    {
                        Console.WriteLine("New user has been added. Its ID is " + change.Id + ", document ETag " + change.Etag);
                    }
                });
                #endregion

                #region subscribe_document_delete
                store.Changes()
                .ForDocument("users/1")
                .Subscribe(change =>
                {
                    if (change.Type == DocumentChangeTypes.Delete)
                    {
                        Console.WriteLine("User " + change.Id + " has been deleted.");
                    }
                });
                #endregion

                #region subscribe_indexes
                store.Changes()
                .ForAllIndexes()
                .Subscribe(change =>
                {
                    if (change.Type == IndexChangeTypes.IndexAdded)
                    {
                        Console.WriteLine("Index " + change.Name + " has been added.");
                    }
                });
                #endregion

                #region subscribe_index_reduce_completed
                store.Changes()
                .ForIndex("Users/ByName")
                .Subscribe(change =>
                {
                    if (change.Type == IndexChangeTypes.IndexRemoved)
                    {
                        Console.WriteLine("Index" + change.Name + " has been removed.");
                    }
                });
                #endregion
            }
        }
示例#32
0
        public ChangesApi()
        {
            using (var store = NewDocumentStore())
            {
                #region getting_database_changes_instance
                IDatabaseChanges changes = store.Changes("DatabaseName");
                #endregion

                #region subscribe_for_all_documents
                store.Changes()
                .ForAllDocuments()
                .Subscribe(change => Console.WriteLine("{0} on document {1}", change.Type, change.Id));
                #endregion

                #region subscribe_documents_starting_with
                store.Changes()
                .ForDocumentsStartingWith("users")
                .Subscribe(change =>
                {
                    if (change.Type == DocumentChangeTypes.Put)
                    {
                        Console.WriteLine("New user has been added. Its ID is " + change.Id + ", document ETag " + change.Etag);
                    }
                });
                #endregion

                #region subscribe_document_delete
                store.Changes()
                .ForDocument("users/1")
                .Subscribe(change =>
                {
                    if (change.Type == DocumentChangeTypes.Delete)
                    {
                        Console.WriteLine("User " + change.Id + " has been deleted.");
                    }
                });
                #endregion

                #region subscribe_indexes
                store.Changes()
                .ForAllIndexes()
                .Subscribe(change =>
                {
                    if (change.Type == IndexChangeTypes.IndexAdded)
                    {
                        Console.WriteLine("Index " + change.Name + " has been added.");
                    }
                });
                #endregion

                #region subscribe_index_reduce_completed
                store.Changes()
                .ForIndex("Orders/Total")
                .Subscribe(change =>
                {
                    if (change.Type == IndexChangeTypes.ReduceCompleted)
                    {
                        Console.WriteLine("Index 'Orders/Total' has finished the reduce work.");
                    }
                });
                #endregion

                #region subscribe_documents_replication_conflict
                store.Changes()
                .ForAllReplicationConflicts()
                .Subscribe(conflict =>
                {
                    if (conflict.ItemType == ReplicationConflictTypes.DocumentReplicationConflict)
                    {
                        Console.WriteLine("Conflict detected for {0}. Ids of conflicted docs: {1}. " +
                                          "Type of replication operation: {2}",
                                          conflict.Id,
                                          string.Join(", ", conflict.Conflicts),
                                          conflict.OperationType);
                    }
                });
                #endregion

                #region subscribe_bulk_insert
                using (var bulkInsert = store.BulkInsert())
                {
                    store.Changes()
                    .ForBulkInsert(bulkInsert.OperationId)
                    .Subscribe(change =>
                    {
                        switch (change.Type)
                        {
                        case DocumentChangeTypes.BulkInsertStarted:
                            // do something
                            break;

                        case DocumentChangeTypes.BulkInsertEnded:
                            // do something
                            break;

                        case DocumentChangeTypes.BulkInsertError:
                            // do something
                            break;
                        }
                    });

                    // process bulk insert here
                }

                #endregion
            }
        }
示例#33
0
        public RemoteBulkInsertOperation(BulkInsertOptions options, AsyncServerClient client, IDatabaseChanges changes,
                                         Task <int> previousTask = null, Guid?existingOperationId = null)
        {
            this.options      = options;
            this.previousTask = previousTask;
            using (NoSynchronizationContext.Scope())
            {
                OperationId     = existingOperationId.HasValue?existingOperationId.Value:Guid.NewGuid();
                operationClient = client;
                queue           = new BlockingCollection <RavenJObject>(Math.Max(128, (options.BatchSize * 3) / 2));

                operationTask = StartBulkInsertAsync(options);

#if !MONO
                SubscribeToBulkInsertNotifications(changes);
#endif
            }
        }
示例#34
0
 public IDatabaseChanges Changes()
 {
     return databaseChanges ??
            (databaseChanges =
             name == Constants.SystemDatabase
                 ? documentStore.Changes()
                 : documentStore.Changes(name));
 }
示例#35
0
 protected virtual ILowLevelBulkInsertOperation GetBulkInsertOperation(BulkInsertOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes)
 {
     return commands.GetBulkInsertOperation(options, changes);
 }
 public DatabaseConnectionState(IDatabaseChanges changes, Func <Task <bool> > onConnect, Func <Task> onDisconnect)
     : base(changes, onConnect, onDisconnect)
 {
 }
示例#37
0
 public ChunkedBulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners, BulkInsertOptions options, IDatabaseChanges changes, int chunkSize, long?documentSizeInChunkLimit = null)
     : base(database, documentStore, listeners, options, changes)
 {
     Operation = new ChunkedRemoteBulkInsertOperation(options, (AsyncServerClient)DatabaseCommands, changes, chunkSize, documentSizeInChunkLimit);
 }
 private void SubscribeToBulkInsertNotifications(IDatabaseChanges changes)
 {
     subscription = changes
                    .ForBulkInsert(OperationId)
                    .Subscribe(this);
 }
示例#39
0
 public RemoteBulkInsertOperation(BulkInsertOptions options, ServerClient client, IDatabaseChanges changes)