Example #1
0
        public IObservableWithTask <IndexChangeNotification> ForIndex(string indexName)
        {
            var counter = counters.GetOrAdd("indexes/" + indexName, s =>
            {
                var indexSubscriptionTask = AfterConnection(() =>
                {
                    watchedIndexes.TryAdd(indexName);
                    return(Send("watch-index", indexName));
                });

                return(new LocalConnectionState(
                           () =>
                {
                    watchedIndexes.TryRemove(indexName);
                    Send("unwatch-index", indexName);
                    counters.Remove("indexes/" + indexName);
                },
                           indexSubscriptionTask));
            });

            counter.Inc();
            var taskedObservable = new TaskedObservable <IndexChangeNotification>(
                counter,
                notification => string.Equals(notification.Name, indexName, StringComparison.InvariantCultureIgnoreCase));

            counter.OnIndexChangeNotification += taskedObservable.Send;
            counter.OnError = taskedObservable.Error;


            return(taskedObservable);
        }
Example #2
0
        public IObservable <ConfigChange> ConfigurationChanges()
        {
            EnsureConnectionInitiated();

#pragma warning disable 4014
            var observable = subjects.GetOrAdd("config", s => new NotificationSubject <ConfigChange>(
                                                   () => ConfigureConnection("watch-config"),
                                                   () => ConfigureConnection("unwatch-config"),
                                                   item => true));
#pragma warning restore 4014

            return((IObservable <ConfigChange>)observable);
        }
Example #3
0
        public IObservableWithTask <IndexChangeNotification> ForIndex(string indexName)
        {
            var counter = counters.GetOrAdd("indexes/" + indexName, s =>
            {
                var indexSubscriptionTask = AfterConnection(() =>
                {
                    connectionsData.AddOrUpdate("watch-index", indexName, (s1, s2) => s2);
                    return(Send("watch-index", indexName));
                });

                return(new LocalConnectionState(
                           () =>
                {
                    string value;
                    connectionsData.TryRemove("watch-index", out value);
                    Send("unwatch-index", indexName);
                    counters.Remove("indexes/" + indexName);
                },
                           indexSubscriptionTask));
            });

            counter.Inc();
            var taskedObservable = new TaskedObservable <IndexChangeNotification>(
                counter,
                notification => string.Equals(notification.Name, indexName, StringComparison.InvariantCultureIgnoreCase));

            counter.OnIndexChangeNotification += taskedObservable.Send;
            counter.OnError = taskedObservable.Error;

            var disposableTask = counter.Task.ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    return(null);
                }
                return((IDisposable) new DisposableAction(() =>
                {
                    try
                    {
                        connection.Dispose();
                    }
                    catch (Exception)
                    {
                        // nothing to do here
                    }
                }));
            });

            counter.Add(disposableTask);
            return(taskedObservable);
        }
Example #4
0
        protected virtual IFilesChanges CreateFileSystemChanges(string filesystem)
        {
            if (string.IsNullOrEmpty(Url))
            {
                throw new InvalidOperationException("Changes API requires usage of server/client");
            }

            var tenantUrl = Url + "/fs/" + filesystem;

            var commands = fileSystemCommands.GetOrAdd(filesystem, x => (IAsyncFilesCommandsImpl)this.AsyncFilesCommands.ForFileSystem(x));

            using (NoSynchronizationContext.Scope())
            {
                var client = new FilesChangesClient(tenantUrl,
                                                    ApiKey,
                                                    Credentials,
                                                    jsonRequestFactory,
                                                    Conventions,
                                                    commands.ReplicationInformer,
                                                    ((AsyncFilesServerClient)this.AsyncFilesCommands).TryResolveConflictByUsingRegisteredListenersAsync,
                                                    () =>
                {
                    fileSystemChanges.Remove(filesystem);
                    fileSystemCommands.Remove(filesystem);
                });

                return(client);
            }
        }
Example #5
0
        /// <summary>
        /// Subscribe to change notifications from the server
        /// </summary>
        public override IDatabaseChanges Changes(string database = null)
        {
            AssertInitialized();

            return(databaseChanges.GetOrAdd(database ?? DefaultDatabase,
                                            CreateDatabaseChanges));
        }
Example #6
0
        public IFilesChanges Changes(string filesystem = null)
        {
            AssertInitialized();

            if (string.IsNullOrWhiteSpace(filesystem))
            {
                filesystem = this.DefaultFileSystem;
            }

            return(fileSystemChanges.GetOrAdd(filesystem, CreateFileSystemChanges));
        }
Example #7
0
        public ICountersChanges Changes(string counterStorage = null)
        {
            AssertInitialized();

            if (string.IsNullOrWhiteSpace(counterStorage))
            {
                counterStorage = Name;
            }

            return(counterStorageChanges.GetOrAdd(counterStorage, CreateCounterStorageChanges));
        }
Example #8
0
        public ITimeSeriesChanges Changes(string timeSeries = null)
        {
            AssertInitialized();

            if (string.IsNullOrWhiteSpace(timeSeries))
            {
                timeSeries = Name;
            }

            return(timeSeriesChanges.GetOrAdd(timeSeries, CreateTimeSeriesChanges));
        }
Example #9
0
        protected TConnectionState GetOrAddConnectionState(string name, string watchCommand, string unwatchCommand, Action afterConnection, Action beforeDisconnect, string value)
        {
            var counter = Counters.GetOrAdd(name, s =>
            {
                Func <Task> onZero = () =>
                {
                    beforeDisconnect();

                    Counters.Remove(name);
                    return(Send(unwatchCommand, value));
                };

                Func <TConnectionState, Task> ensureConnection = existingConnectionState =>
                {
                    TConnectionState _;
                    if (Counters.TryGetValue(name, out _))
                    {
                        return(_.Task);
                    }

                    Counters.GetOrAdd(name, x => existingConnectionState);

                    return(AfterConnection(() =>
                    {
                        afterConnection();
                        return Send(watchCommand, value);
                    }));
                };

                var counterSubscriptionTask = AfterConnection(() =>
                {
                    afterConnection();
                    return(Send(watchCommand, value));
                });

                return(CreateTConnectionState(onZero, ensureConnection, counterSubscriptionTask));
            });

            return(counter);
        }
Example #10
0
        protected bool TryGetOrCreateResourceStore(string tenantId, out Task <DocumentDatabase> database)
        {
            if (ResourcesStoresCache.TryGetValue(tenantId, out database))
            {
                if (database.IsFaulted || database.IsCanceled)
                {
                    ResourcesStoresCache.TryRemove(tenantId, out database);
                    DateTime time;
                    databaseLastRecentlyUsed.TryRemove(tenantId, out time);
                    // and now we will try creating it again
                }
                else
                {
                    return(true);
                }
            }

            if (LockedDatabases.Contains(tenantId))
            {
                throw new InvalidOperationException("Database '" + tenantId + "' is currently locked and cannot be accessed");
            }

            var config = CreateTenantConfiguration(tenantId);

            if (config == null)
            {
                return(false);
            }

            database = ResourcesStoresCache.GetOrAdd(tenantId, __ => Task.Factory.StartNew(() =>
            {
                var documentDatabase = new DocumentDatabase(config);
                AssertLicenseParameters(config);
                documentDatabase.SpinBackgroundWorkers();
                InitializeRequestResponders(documentDatabase);

                // if we have a very long init process, make sure that we reset the last idle time for this db.
                databaseLastRecentlyUsed.AddOrUpdate(tenantId, SystemTime.UtcNow, (_, time) => SystemTime.UtcNow);
                return(documentDatabase);
            }).ContinueWith(task =>
            {
                if (task.Status == TaskStatus.Faulted)                 // this observes the task exception
                {
                    logger.WarnException("Failed to create database " + tenantId, task.Exception);
                }
                return(task);
            }).Unwrap());
            return(true);
        }
Example #11
0
        private DatabaseConnectionState GetOrAddConnectionState(string name, string watchCommand, string unwatchCommand, string value)
        {
            var counter = _counters.GetOrAdd(name, s =>
            {
                async Task OnDisconnect()
                {
                    try
                    {
                        if (Connected)
                        {
                            await Send(unwatchCommand, value).ConfigureAwait(false);
                        }
                    }
                    catch (WebSocketException)
                    {
                        // if we are not connected then we unsubscribed already
                        // because connections drops with all subscriptions
                    }

                    DatabaseConnectionState state;
                    if (_counters.TryRemove(s, out state))
                    {
                        state.Dispose();
                    }
                }

                async Task <bool> OnConnect()
                {
                    try
                    {
                        if (Connected)
                        {
                            await Send(watchCommand, value).ConfigureAwait(false);
                            return(true);
                        }
                    }
                    catch (WebSocketException)
                    {
                        // if we are not connected then we will subscribe again after connection be established
                    }

                    return(false);
                }

                return(new DatabaseConnectionState(this, OnConnect, OnDisconnect));
            });

            return(counter);
        }
Example #12
0
        public void Repeat(IRepeatedAction action)
        {
            var tuple = timers.GetOrAdd(action.RepeatDuration.ToString(),
                                        span =>
            {
                var repeatedActions = new ConcurrentSet <IRepeatedAction>
                {
                    action
                };
                var timer = new Timer(ExecuteTimer, action.RepeatDuration,
                                      action.RepeatDuration,
                                      action.RepeatDuration);
                return(Tuple.Create(timer, repeatedActions));
            });

            tuple.Item2.TryAdd(action);
        }
Example #13
0
        private DatabaseConnectionState GetOrAddConnectionState(string name, string watchCommand, string unwatchCommand, string value)
        {
            bool newValue = false;
            var  counter  = _counters.GetOrAdd(name, s =>
            {
                async Task OnDisconnect()
                {
                    try
                    {
                        if (Connected)
                        {
                            await Send(unwatchCommand, value).ConfigureAwait(false);
                        }
                    }
                    catch (WebSocketException)
                    {
                        // if we are not connected then we unsubscribed already
                        // because connections drops with all subscriptions
                    }

                    if (_counters.TryRemove(s, out var state))
                    {
                        state.Dispose();
                    }
                }

                async Task OnConnect()
                {
                    await Send(watchCommand, value).ConfigureAwait(false);
                }

                newValue = true;
                return(new DatabaseConnectionState(OnConnect, OnDisconnect));
            });

            // try to reconnect
            if (newValue && Volatile.Read(ref _immediateConnection) != 0)
            {
                counter.Set(counter.OnConnect());
            }

            return(counter);
        }
 public override IDatabaseChanges Changes(string database = null)
 {
     return(changes.GetOrAdd(database,
                             _ => new ShardedDatabaseChanges(ShardStrategy.Shards.Values.Select(x => x.Changes(database)).ToArray())));
 }